Skip to content

Commit 1dc49f5

Browse files
authored
Move tolerances out of hardcoded part of code (#140)
* Move tolerances out of hardcoded part of code * Remove debug print * Remove default argument in evaluate_basis_functions * real type of tolerance * Fix typing
1 parent 9ea0364 commit 1dc49f5

6 files changed

+77
-47
lines changed

cpp/ContactConstraint.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -469,7 +469,7 @@ mpc_data<T> create_contact_slip_condition(
469469
slave_coordinates, eps2);
470470

471471
auto [basis, basis_shape] = dolfinx_mpc::evaluate_basis_functions<U>(
472-
V, slave_coordinates, local_cell_collisions);
472+
V, slave_coordinates, local_cell_collisions, eps2);
473473
assert(basis_shape.back() == 1);
474474
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
475475
U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>
@@ -590,7 +590,7 @@ mpc_data<T> create_contact_slip_condition(
590590
= dolfinx_mpc::find_local_collisions<U>(*mesh, bb_tree, recv_coords,
591591
eps2);
592592
auto [recv_basis_values, shape] = dolfinx_mpc::evaluate_basis_functions<U>(
593-
V, recv_coords, remote_cell_collisions);
593+
V, recv_coords, remote_cell_collisions, eps2);
594594
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
595595
U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>
596596
basis_span(recv_basis_values.data(), shape[0], shape[1]);
@@ -1000,7 +1000,7 @@ mpc_data<T> create_contact_inelastic_condition(
10001000
= dolfinx_mpc::find_local_collisions<U>(*V.mesh(), bb_tree,
10011001
slave_coordinates, eps2);
10021002
auto [basis_values, basis_shape] = dolfinx_mpc::evaluate_basis_functions<U>(
1003-
V, slave_coordinates, colliding_cells);
1003+
V, slave_coordinates, colliding_cells, eps2);
10041004
assert(basis_shape.back() == 1);
10051005
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
10061006
U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>
@@ -1185,7 +1185,7 @@ mpc_data<T> create_contact_inelastic_condition(
11851185
= dolfinx_mpc::find_local_collisions<U>(*V.mesh(), bb_tree, recv_coords,
11861186
eps2);
11871187
auto [basis, basis_shape] = dolfinx_mpc::evaluate_basis_functions<U>(
1188-
V, recv_coords, remote_cell_collisions);
1188+
V, recv_coords, remote_cell_collisions, eps2);
11891189
assert(basis_shape.back() == 1);
11901190
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
11911191
const U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 2>>

cpp/MultiPointConstraint.h

+2
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,10 @@ class MultiPointConstraint
134134
auto coeffs = _coeff_map->links(slave);
135135
assert(masters.size() == coeffs.size());
136136
for (std::size_t k = 0; k < masters.size(); ++k)
137+
{
137138
vector[slave]
138139
+= coeffs[k] * vector[masters[k]]; //+ _mpc_constants[slave];
140+
}
139141
}
140142
};
141143

cpp/PeriodicConstraint.h

+46-29
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,20 @@ namespace impl
2020
/// not collapsed)
2121
/// @param[in] parent_space The parent space (The same space as V if not
2222
/// collapsed)
23+
/// @param[in] tol Tolerance for adding scaled basis values to MPC. Any
24+
/// contribution that is less than this value is ignored. The tolerance is also
25+
/// added as padding for the bounding box trees and corresponding collision
26+
/// searches to determine periodic degrees of freedom.
2327
/// @returns The multi point constraint
2428
template <typename T, std::floating_point U>
2529
dolfinx_mpc::mpc_data<T> _create_periodic_condition(
2630
const dolfinx::fem::FunctionSpace<U>& V,
2731
std::span<std::int32_t> slave_blocks,
2832
const std::function<std::vector<U>(std::span<const U>)>& relation, T scale,
2933
const std::function<const std::int32_t(const std::int32_t&)>& parent_map,
30-
const dolfinx::fem::FunctionSpace<U>& parent_space)
34+
const dolfinx::fem::FunctionSpace<U>& parent_space, const U tol)
3135
{
36+
3237
// Map a list of indices in collapsed space back to the parent space
3338
auto sub_to_parent = [&parent_map](const std::vector<std::int32_t>& sub_dofs)
3439
{
@@ -71,10 +76,6 @@ dolfinx_mpc::mpc_data<T> _create_periodic_condition(
7176
"Periodic conditions for vector valued spaces are not "
7277
"implemented");
7378

74-
// Tolerance for adding scaled basis values to MPC. Any scaled basis
75-
// value with lower absolute value than the tolerance is ignored
76-
const U tol = 500 * std::numeric_limits<U>::epsilon();
77-
7879
auto mesh = V.mesh();
7980
auto dofmap = V.dofmap();
8081
auto imap = dofmap->index_map;
@@ -138,7 +139,7 @@ dolfinx_mpc::mpc_data<T> _create_periodic_condition(
138139
= dolfinx_mpc::find_local_collisions<U>(*mesh, tree, mapped_T_b, tol);
139140
dolfinx::common::Timer t0("~~Periodic: Local cell and eval basis");
140141
auto [basis_values, basis_shape] = dolfinx_mpc::evaluate_basis_functions<U>(
141-
V, mapped_T_b, local_cell_collisions);
142+
V, mapped_T_b, local_cell_collisions, tol);
142143
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
143144
const U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 3>>
144145
tabulated_basis_values(basis_values.data(), basis_shape);
@@ -358,7 +359,7 @@ dolfinx_mpc::mpc_data<T> _create_periodic_condition(
358359
= dolfinx_mpc::find_local_collisions<U>(*mesh, tree, coords_recvb, tol);
359360
auto [remote_basis_valuesb, r_basis_shape]
360361
= dolfinx_mpc::evaluate_basis_functions<U>(V, coords_recvb,
361-
remote_cell_collisions);
362+
remote_cell_collisions, tol);
362363
MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
363364
const U, MDSPAN_IMPL_STANDARD_NAMESPACE::dextents<std::size_t, 3>>
364365
remote_basis_values(remote_basis_valuesb.data(), r_basis_shape);
@@ -490,6 +491,10 @@ dolfinx_mpc::mpc_data<T> _create_periodic_condition(
490491
/// @param[in] scale Scaling of the periodic condition
491492
/// @param[in] collapse If true, the list of marked dofs is in the collapsed
492493
/// input space
494+
/// @param[in] tol Tolerance for adding scaled basis values to MPC. Any
495+
/// contribution that is less than this value is ignored. The tolerance is also
496+
/// added as padding for the bounding box trees and corresponding collision
497+
/// searches to determine periodic degrees of freedom.
493498
/// @returns The multi point constraint
494499
template <typename T, std::floating_point U>
495500
dolfinx_mpc::mpc_data<T> geometrical_condition(
@@ -502,7 +507,7 @@ dolfinx_mpc::mpc_data<T> geometrical_condition(
502507
indicator,
503508
const std::function<std::vector<U>(std::span<const U>)>& relation,
504509
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<T>>>& bcs,
505-
T scale, bool collapse)
510+
T scale, bool collapse, const U tol)
506511
{
507512
std::vector<std::int32_t> reduced_blocks;
508513
if (collapse)
@@ -526,7 +531,7 @@ dolfinx_mpc::mpc_data<T> geometrical_condition(
526531
auto sub_map
527532
= [&parent_map](const std::int32_t& i) { return parent_map[i]; };
528533
return _create_periodic_condition<T>(V_sub, std::span(reduced_blocks),
529-
relation, scale, sub_map, *V);
534+
relation, scale, sub_map, *V, tol);
530535
}
531536
else
532537
{
@@ -542,7 +547,7 @@ dolfinx_mpc::mpc_data<T> geometrical_condition(
542547
reduced_blocks.push_back(slave_blocks[i]);
543548
auto sub_map = [](const std::int32_t& dof) { return dof; };
544549
return _create_periodic_condition<T>(*V, std::span(reduced_blocks),
545-
relation, scale, sub_map, *V);
550+
relation, scale, sub_map, *V, tol);
546551
}
547552
}
548553

@@ -558,6 +563,10 @@ dolfinx_mpc::mpc_data<T> geometrical_condition(
558563
/// @param[in] scale Scaling of the periodic condition
559564
/// @param[in] collapse If true, the list of marked dofs is in the collapsed
560565
/// input space
566+
/// @param[in] tol Tolerance for adding scaled basis values to MPC. Any
567+
/// contribution that is less than this value is ignored. The tolerance is also
568+
/// added as padding for the bounding box trees and corresponding collision
569+
/// searches to determine periodic degrees of freedom.
561570
/// @returns The multi point constraint
562571
template <typename T, std::floating_point U>
563572
dolfinx_mpc::mpc_data<T> topological_condition(
@@ -566,7 +575,7 @@ dolfinx_mpc::mpc_data<T> topological_condition(
566575
const std::int32_t tag,
567576
const std::function<std::vector<U>(std::span<const U>)>& relation,
568577
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<T>>>& bcs,
569-
T scale, bool collapse)
578+
T scale, bool collapse, const U tol)
570579
{
571580
std::vector<std::int32_t> entities = meshtag->find(tag);
572581
V->mesh()->topology_mutable()->create_connectivity(
@@ -594,7 +603,7 @@ dolfinx_mpc::mpc_data<T> topological_condition(
594603
= [&parent_map](const std::int32_t& i) { return parent_map[i]; };
595604
// Create mpc on sub space
596605
dolfinx_mpc::mpc_data<T> sub_data = _create_periodic_condition<T>(
597-
V_sub, std::span(reduced_blocks), relation, scale, sub_map, *V);
606+
V_sub, std::span(reduced_blocks), relation, scale, sub_map, *V, tol);
598607
return sub_data;
599608
}
600609
else
@@ -613,7 +622,7 @@ dolfinx_mpc::mpc_data<T> topological_condition(
613622
const auto sub_map = [](const std::int32_t& dof) { return dof; };
614623

615624
return _create_periodic_condition<T, U>(*V, std::span(reduced_blocks),
616-
relation, scale, sub_map, *V);
625+
relation, scale, sub_map, *V, tol);
617626
}
618627
};
619628

@@ -633,10 +642,11 @@ mpc_data<double> create_periodic_condition_geometrical(
633642
const std::function<std::vector<double>(std::span<const double>)>& relation,
634643
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<double>>>&
635644
bcs,
636-
double scale, bool collapse)
645+
double scale, bool collapse,
646+
const double tol = 500 * std::numeric_limits<double>::epsilon())
637647
{
638648
return impl::geometrical_condition<double, double>(V, indicator, relation,
639-
bcs, scale, collapse);
649+
bcs, scale, collapse, tol);
640650
}
641651

642652
mpc_data<std::complex<double>> create_periodic_condition_geometrical(
@@ -651,10 +661,11 @@ mpc_data<std::complex<double>> create_periodic_condition_geometrical(
651661
const std::vector<
652662
std::shared_ptr<const dolfinx::fem::DirichletBC<std::complex<double>>>>&
653663
bcs,
654-
std::complex<double> scale, bool collapse)
664+
std::complex<double> scale, bool collapse,
665+
const double tol = 500 * std::numeric_limits<double>::epsilon())
655666
{
656667
return impl::geometrical_condition<std::complex<double>, double>(
657-
V, indicator, relation, bcs, scale, collapse);
668+
V, indicator, relation, bcs, scale, collapse, tol);
658669
}
659670

660671
mpc_data<double> create_periodic_condition_topological(
@@ -664,10 +675,11 @@ mpc_data<double> create_periodic_condition_topological(
664675
const std::function<std::vector<double>(std::span<const double>)>& relation,
665676
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<double>>>&
666677
bcs,
667-
double scale, bool collapse)
678+
double scale, bool collapse,
679+
const double tol = 500 * std::numeric_limits<double>::epsilon())
668680
{
669681
return impl::topological_condition<double, double>(V, meshtag, tag, relation,
670-
bcs, scale, collapse);
682+
bcs, scale, collapse, tol);
671683
}
672684

673685
mpc_data<std::complex<double>> create_periodic_condition_topological(
@@ -678,10 +690,11 @@ mpc_data<std::complex<double>> create_periodic_condition_topological(
678690
const std::vector<
679691
std::shared_ptr<const dolfinx::fem::DirichletBC<std::complex<double>>>>&
680692
bcs,
681-
std::complex<double> scale, bool collapse)
693+
std::complex<double> scale, bool collapse,
694+
const double tol = 500 * std::numeric_limits<double>::epsilon())
682695
{
683696
return impl::topological_condition<std::complex<double>, double>(
684-
V, meshtag, tag, relation, bcs, scale, collapse);
697+
V, meshtag, tag, relation, bcs, scale, collapse, tol);
685698
}
686699

687700
mpc_data<float> create_periodic_condition_geometrical(
@@ -695,10 +708,11 @@ mpc_data<float> create_periodic_condition_geometrical(
695708
const std::function<std::vector<float>(std::span<const float>)>& relation,
696709
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<float>>>&
697710
bcs,
698-
float scale, bool collapse)
711+
float scale, bool collapse,
712+
const float tol = 500 * std::numeric_limits<float>::epsilon())
699713
{
700714
return impl::geometrical_condition<float, float>(V, indicator, relation, bcs,
701-
scale, collapse);
715+
scale, collapse, tol);
702716
}
703717

704718
mpc_data<std::complex<float>> create_periodic_condition_geometrical(
@@ -713,10 +727,11 @@ mpc_data<std::complex<float>> create_periodic_condition_geometrical(
713727
const std::vector<
714728
std::shared_ptr<const dolfinx::fem::DirichletBC<std::complex<float>>>>&
715729
bcs,
716-
std::complex<float> scale, bool collapse)
730+
std::complex<float> scale, bool collapse,
731+
const float tol = 500 * std::numeric_limits<float>::epsilon())
717732
{
718733
return impl::geometrical_condition<std::complex<float>, float>(
719-
V, indicator, relation, bcs, scale, collapse);
734+
V, indicator, relation, bcs, scale, collapse, tol);
720735
}
721736

722737
mpc_data<float> create_periodic_condition_topological(
@@ -726,10 +741,11 @@ mpc_data<float> create_periodic_condition_topological(
726741
const std::function<std::vector<float>(std::span<const float>)>& relation,
727742
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<float>>>&
728743
bcs,
729-
float scale, bool collapse)
744+
float scale, bool collapse,
745+
const float tol = 500 * std::numeric_limits<float>::epsilon())
730746
{
731747
return impl::topological_condition<float, float>(V, meshtag, tag, relation,
732-
bcs, scale, collapse);
748+
bcs, scale, collapse, tol);
733749
}
734750

735751
mpc_data<std::complex<float>> create_periodic_condition_topological(
@@ -740,10 +756,11 @@ mpc_data<std::complex<float>> create_periodic_condition_topological(
740756
const std::vector<
741757
std::shared_ptr<const dolfinx::fem::DirichletBC<std::complex<float>>>>&
742758
bcs,
743-
std::complex<float> scale, bool collapse)
759+
std::complex<float> scale, bool collapse,
760+
const float tol = 500 * std::numeric_limits<float>::epsilon())
744761
{
745762
return impl::topological_condition<std::complex<float>, float>(
746-
V, meshtag, tag, relation, bcs, scale, collapse);
763+
V, meshtag, tag, relation, bcs, scale, collapse, tol);
747764
}
748765

749766
} // namespace dolfinx_mpc

cpp/utils.h

+5-3
Original file line numberDiff line numberDiff line change
@@ -962,13 +962,16 @@ dolfinx_mpc::mpc_data<T> distribute_ghost_data(
962962
/// @param[in,out] u The values at the points. Values are not computed
963963
/// for points with a negative cell index. This argument must be
964964
/// passed with the correct size.
965+
/// @param[in] tol The stopping tolerance for the l2 norm of the Newton update
966+
/// when pulling back a point on a non-affine cell. For affine cells this value
967+
/// is not used.
965968
/// @returns basis values (not unrolled for block size) for each point. shape
966969
/// (num_points, number_of_dofs, value_size). Flattened row major
967970
template <std::floating_point U>
968971
std::pair<std::vector<U>, std::array<std::size_t, 3>>
969972
evaluate_basis_functions(const dolfinx::fem::FunctionSpace<U>& V,
970973
std::span<const U> x,
971-
std::span<const std::int32_t> cells)
974+
std::span<const std::int32_t> cells, const U tol)
972975
{
973976
assert(x.size() % 3 == 0);
974977
const std::size_t num_points = x.size() / 3;
@@ -1132,8 +1135,7 @@ evaluate_basis_functions(const dolfinx::fem::FunctionSpace<U>& V,
11321135
else
11331136
{
11341137
// Pull-back physical point xp to reference coordinate Xp
1135-
cmap.pull_back_nonaffine(Xp, xp, coord_dofs,
1136-
5000 * std::numeric_limits<U>::epsilon(), 15);
1138+
cmap.pull_back_nonaffine(Xp, xp, coord_dofs, tol, 15);
11371139

11381140
cmap.tabulate(1, std::span(Xpb.data(), tdim), {1, tdim}, phi_b);
11391141
dolfinx::fem::CoordinateElement<U>::compute_jacobian(dphi, coord_dofs,

python/dolfinx_mpc/mpc.cpp

+7-6
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ void declare_functions(nb::module_& m)
152152
nb::ndarray<const U, nb::ndim<2>, nb::numpy>&)>& relation,
153153
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<T>>>&
154154
bcs,
155-
T scale, bool collapse)
155+
T scale, bool collapse, const U tol)
156156
{
157157
auto _indicator
158158
= [&indicator](MDSPAN_IMPL_STANDARD_NAMESPACE::mdspan<
@@ -180,10 +180,10 @@ void declare_functions(nb::module_& m)
180180
return output;
181181
};
182182
return dolfinx_mpc::create_periodic_condition_geometrical(
183-
V, _indicator, _relation, bcs, scale, collapse);
183+
V, _indicator, _relation, bcs, scale, collapse, tol);
184184
},
185185
"V"_a, "indicator"_a, "relation"_a, "bcs"_a, nb::arg("scale").noconvert(),
186-
nb::arg("collapse").noconvert());
186+
nb::arg("collapse").noconvert(), nb::arg("tol").noconvert());
187187
m.def(
188188
"create_periodic_constraint_topological",
189189
[](std::shared_ptr<const dolfinx::fem::FunctionSpace<U>>& V,
@@ -193,7 +193,7 @@ void declare_functions(nb::module_& m)
193193
nb::ndarray<const U, nb::ndim<2>, nb::numpy>&)>& relation,
194194
const std::vector<std::shared_ptr<const dolfinx::fem::DirichletBC<T>>>&
195195
bcs,
196-
T scale, bool collapse)
196+
T scale, bool collapse, const U tol)
197197
{
198198
auto _relation = [&relation](std::span<const U> x) -> std::vector<U>
199199
{
@@ -204,10 +204,11 @@ void declare_functions(nb::module_& m)
204204
return output;
205205
};
206206
return dolfinx_mpc::create_periodic_condition_topological(
207-
V, meshtags, dim, _relation, bcs, scale, collapse);
207+
V, meshtags, dim, _relation, bcs, scale, collapse, tol);
208208
},
209209
"V"_a, "meshtags"_a, "dim"_a, "relation"_a, "bcs"_a,
210-
nb::arg("scale").noconvert(), nb::arg("collapse").noconvert());
210+
nb::arg("scale").noconvert(), nb::arg("collapse").noconvert(),
211+
nb::arg("tol").noconvert());
211212
}
212213

213214
template <typename T, std::floating_point U>

0 commit comments

Comments
 (0)