From 8bcc930ae9de2452dfecec96c81f7558bfc76d85 Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Mon, 4 May 2026 14:28:03 +0200 Subject: [PATCH 1/4] fix --- include/samurai/algorithm/update.hpp | 14 +++- include/samurai/bc/apply_field_bc.hpp | 108 ++++++++++++++++++++++++-- include/samurai/mesh.hpp | 59 ++++++++------ 3 files changed, 150 insertions(+), 31 deletions(-) diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index 43b4c8268..afda5484a 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -409,8 +409,18 @@ namespace samurai for_each_diagonal_direction( [&](auto& direction) { - auto d = find_direction_index(direction); - if (!mesh.is_periodic(d)) + // Skip if any non-zero component of the direction is periodic: + // a periodic direction has no real boundary, so no corner ghost to fill. + bool any_periodic = false; + for (std::size_t d = 0; d < dim; ++d) + { + if (direction[d] != 0 && mesh.is_periodic(d)) + { + any_periodic = true; + break; + } + } + if (!any_periodic) { update_outer_corners_by_polynomial_extrapolation(level, direction, field); project_corner_below(level, direction, field); // project to level-1 and level-2 diff --git a/include/samurai/bc/apply_field_bc.hpp b/include/samurai/bc/apply_field_bc.hpp index 9b28137c6..e7cc450dd 100644 --- a/include/samurai/bc/apply_field_bc.hpp +++ b/include/samurai/bc/apply_field_bc.hpp @@ -322,14 +322,112 @@ namespace samurai return; // No outer corners in 1D } - static constexpr std::size_t extrap_stencil_size = 2; + static constexpr std::size_t max_stencil_size_PE = PolynomialExtrapolation::max_stencil_size_implemented_PE; - auto& domain = detail::get_mesh(field.mesh()); - PolynomialExtrapolation bc(domain, ConstantBc(), true); + int ghost_width = field.mesh().ghost_width(); + const auto& domain = detail::get_mesh(field.mesh()); + const auto& corner_lca = field.mesh().corner(direction); - auto corner = self(field.mesh().corner(direction)).on(level); + // Step 1: Fill the diagonal ghost cells layer by layer using stencil sizes 2, 4, ..., 2*ghost_width + for (int ghost_layer = 1; ghost_layer <= ghost_width; ++ghost_layer) + { + int stencil_s = 2 * ghost_layer; + static_for<2, max_stencil_size_PE + 1>::apply( + [&](auto stencil_size_) + { + static constexpr int stencil_size = static_cast(stencil_size_()); + if constexpr (stencil_size % 2 == 0) + { + if (stencil_s == stencil_size) + { + PolynomialExtrapolation bc(domain, ConstantBc(), true); + auto corner = self(corner_lca).on(level); + __apply_extrapolation_bc__cells(bc, level, field, direction, corner); + } + } + }); + } + + // Step 2: Fill off-diagonal ghost cells using Cartesian constant extrapolation + // For each non-zero component of the direction, apply extrapolation from the diagonal ghost cells + using mesh_id_t = typename Field::mesh_t::mesh_id_t; + + // Count non-zero direction components + std::size_t num_nonzero = 0; + std::array nonzero_dirs; + for (std::size_t d = 0; d < Field::dim; ++d) + { + if (direction[d] != 0) + { + nonzero_dirs[num_nonzero] = d; + ++num_nonzero; + } + } + + // Check if the corner cells exist at this level + // If they don't, skip the off-diagonal fill entirely + auto corner_at_level = self(corner_lca).on(level); - __apply_extrapolation_bc__cells(bc, level, field, direction, corner); + PolynomialExtrapolation bc_e(domain, ConstantBc(), true); + auto stencil_0_e = bc_e.get_stencil(std::integral_constant()); + + for (std::size_t d = 0; d < Field::dim; ++d) + { + if (direction[d] == 0) continue; + + DirectionVector e_dir; + e_dir.fill(0); + e_dir[d] = direction[d]; + + auto stencil_e = convert_for_direction(stencil_0_e, e_dir); + auto analyzer_e = make_stencil_analyzer(stencil_e); + + auto& mesh = field.mesh(); + auto has_outer_neighbour = translate(self(mesh[mesh_id_t::reference][level]).on(level), -e_dir); + + // For each layer, extrapolate from diagonal/off-diagonal ghost cells in the e_dir direction + for (int g = 1; g <= ghost_width; ++g) + { + // Source: translate(corner, direction + (g-1)*e_dir) + auto source_set = translate(corner_at_level, direction + (g - 1) * e_dir); + auto valid_source = intersection(source_set, has_outer_neighbour).on(level); + __apply_bc_on_subset(bc_e, field, valid_source, analyzer_e, e_dir); + } + + // For true 3D corners (3 non-zero components), apply secondary sweeps + // to fill cells at edge-pair positions like (N+1,N+1,N) + if (num_nonzero == 3) + { + // For each pair of the OTHER non-zero directions, apply sweep in e_dir + // from the cells filled by those directions + for (std::size_t i = 0; i < num_nonzero; ++i) + { + if (nonzero_dirs[i] == d) continue; // skip the current direction + for (std::size_t j = i + 1; j < num_nonzero; ++j) + { + if (nonzero_dirs[j] == d) continue; // skip the current direction + + // Create unit direction vectors for the other two directions + DirectionVector e_dir_i; + e_dir_i.fill(0); + e_dir_i[nonzero_dirs[i]] = direction[nonzero_dirs[i]]; + + DirectionVector e_dir_j; + e_dir_j.fill(0); + e_dir_j[nonzero_dirs[j]] = direction[nonzero_dirs[j]]; + + // Source: cells filled by sweeps in directions i and j + // = translate(corner, direction + e_dir_i) and translate(corner, direction + e_dir_j) + auto source_i = translate(self(corner_lca).on(level), direction + e_dir_i); + auto source_j = translate(self(corner_lca).on(level), direction + e_dir_j); + auto combined_source = union_(source_i, source_j); + + auto valid_source = intersection(combined_source, has_outer_neighbour).on(level); + __apply_bc_on_subset(bc_e, field, valid_source, analyzer_e, e_dir); + } + } + } + } } template diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index 77f1f91ca..e3b5bd8a5 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -948,38 +948,49 @@ namespace samurai { using direction_t = DirectionVector; - // Generic implementation for any dim >= 2. - // For a diagonal direction d (each component ±1), the "corner" subset is: - // domain \ union_{i=0}^{dim-1}( translate(domain, e_i * -d[i]) ) - // where e_i is the canonical unit vector along axis i. - // We build the union_ call generically using an index sequence. + // For a diagonal direction d, the "corner" (inner cells at the boundary corner/edge) is: + // domain \ union_{i: d[i] != 0}( translate(domain, e_i * -d[i]) ) + // Only non-zero components are included: a zero component would give + // translate(domain, 0) = domain, making the union contain the domain itself + // and the difference empty. This is the correct formula for both true corner + // directions (all components ±1) and edge directions in 3D (one zero component). m_corners.clear(); for_each_diagonal_direction( [&](const auto& direction) { - // Build a tuple of dim translates, one per axis - auto translates = [&](std::index_sequence) + // Collect shifts only for non-zero components + std::array nonzero_shifts; + std::size_t n = 0; + for (std::size_t I = 0; I < dim; ++I) { - // For axis I: shift is -direction[I] along axis I, 0 elsewhere - auto make_translate = [&](std::integral_constant) + if (direction[I] != 0) { - direction_t shift{}; - shift.fill(0); - shift[I] = -direction[I]; - return translate(m_domain, shift); - }; - return std::make_tuple(make_translate(std::integral_constant{})...); - }(std::make_index_sequence{}); - - // Apply union_ to the tuple of translates - auto u = std::apply( - [](const auto&... ts) + nonzero_shifts[n].fill(0); + nonzero_shifts[n][I] = -direction[I]; + ++n; + } + } + + // Apply union_ to non-zero-component translates only. + // for_each_diagonal_direction guarantees n >= 2. + // In 3D: n == 2 for edge directions, n == 3 for true corner directions. + if (n > 1) + { + // n == dim: all components are non-zero (true corner), use index sequence + auto translates = [&](std::index_sequence) { - return union_(ts...); - }, - translates); + return std::make_tuple(translate(m_domain, nonzero_shifts[Is])...); + }(std::make_index_sequence{}); - m_corners.push_back(difference(m_domain, u).to_lca()); + auto u = std::apply( + [](const auto&... ts) + { + return union_(ts...); + }, + translates); + + m_corners.push_back(difference(m_domain, u).to_lca()); + } }); } From 09039ed585b0356c82d30531f0083787675a849a Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Mon, 4 May 2026 18:38:15 +0200 Subject: [PATCH 2/4] ... --- include/samurai/algorithm/update.hpp | 31 +++++-- include/samurai/bc/apply_field_bc.hpp | 29 ++++--- include/samurai/mesh.hpp | 116 +++++++++++++++++--------- 3 files changed, 119 insertions(+), 57 deletions(-) diff --git a/include/samurai/algorithm/update.hpp b/include/samurai/algorithm/update.hpp index afda5484a..4c0b6888f 100644 --- a/include/samurai/algorithm/update.hpp +++ b/include/samurai/algorithm/update.hpp @@ -361,11 +361,20 @@ namespace samurai auto& mesh = field.mesh(); + std::size_t nnz = 0; + for (std::size_t d = 0; d < dim; ++d) + { + if (direction[d] != 0) + { + nnz++; + } + } + for (std::size_t delta_l = 1; delta_l <= 2; ++delta_l) // lower level (1 or 2) { auto proj_level = level - delta_l; - auto fine_inner_corner = self(mesh.corner(direction)).on(level); + auto fine_inner_corner = intersection(self(mesh.corner(direction)).on(level), mesh[mesh_id_t::cells][level]); auto fine_outer_corner = intersection(translate(fine_inner_corner, direction), mesh[mesh_id_t::reference][level]); auto projection_ghost = intersection(fine_outer_corner.on(proj_level), mesh[mesh_id_t::reference][proj_level]); @@ -374,15 +383,25 @@ namespace samurai { using index_t = std::decay_t; - auto i_child = (1 << delta_l) * i; - i_child.start += direction[0] == -1 ? ((1 << delta_l) - 1) : 0; - i_child.end = i_child.start + 1; - i_child.step = 1; - index_t index_child = (1 << delta_l) * index; + auto i_child = (i << delta_l) + (direction[0] == -1 ? ((1 << delta_l) - 1) : 0); // this is the interval of the child + // cell in the fine level + if (nnz == dim) // || direction[0] != 0) + { + i_child.end = i_child.start + 1; // if we are projecting a corner ghost, we want only 1 child, so end = start + 1 + i_child.step = 1; + } + else + { + i_child.step = 1 << delta_l; + } + + index_t index_child = index << delta_l; + for (std::size_t d = 0; d < dim - 1; ++d) { index_child[d] += direction[d + 1] == -1 ? ((1 << delta_l) - 1) : 0; } + field(proj_level, i, index) = field(level, i_child, index_child); }); if (proj_level == 0) diff --git a/include/samurai/bc/apply_field_bc.hpp b/include/samurai/bc/apply_field_bc.hpp index e7cc450dd..439ec62b3 100644 --- a/include/samurai/bc/apply_field_bc.hpp +++ b/include/samurai/bc/apply_field_bc.hpp @@ -324,8 +324,8 @@ namespace samurai static constexpr std::size_t max_stencil_size_PE = PolynomialExtrapolation::max_stencil_size_implemented_PE; - int ghost_width = field.mesh().ghost_width(); - const auto& domain = detail::get_mesh(field.mesh()); + int ghost_width = field.mesh().ghost_width(); + const auto& domain = detail::get_mesh(field.mesh()); const auto& corner_lca = field.mesh().corner(direction); // Step 1: Fill the diagonal ghost cells layer by layer using stencil sizes 2, 4, ..., 2*ghost_width @@ -373,23 +373,26 @@ namespace samurai for (std::size_t d = 0; d < Field::dim; ++d) { - if (direction[d] == 0) continue; + if (direction[d] == 0) + { + continue; + } DirectionVector e_dir; e_dir.fill(0); e_dir[d] = direction[d]; - auto stencil_e = convert_for_direction(stencil_0_e, e_dir); + auto stencil_e = convert_for_direction(stencil_0_e, e_dir); auto analyzer_e = make_stencil_analyzer(stencil_e); - auto& mesh = field.mesh(); + auto& mesh = field.mesh(); auto has_outer_neighbour = translate(self(mesh[mesh_id_t::reference][level]).on(level), -e_dir); // For each layer, extrapolate from diagonal/off-diagonal ghost cells in the e_dir direction for (int g = 1; g <= ghost_width; ++g) { // Source: translate(corner, direction + (g-1)*e_dir) - auto source_set = translate(corner_at_level, direction + (g - 1) * e_dir); + auto source_set = translate(corner_at_level, direction + (g - 1) * e_dir); auto valid_source = intersection(source_set, has_outer_neighbour).on(level); __apply_bc_on_subset(bc_e, field, valid_source, analyzer_e, e_dir); } @@ -402,10 +405,16 @@ namespace samurai // from the cells filled by those directions for (std::size_t i = 0; i < num_nonzero; ++i) { - if (nonzero_dirs[i] == d) continue; // skip the current direction + if (nonzero_dirs[i] == d) + { + continue; // skip the current direction + } for (std::size_t j = i + 1; j < num_nonzero; ++j) { - if (nonzero_dirs[j] == d) continue; // skip the current direction + if (nonzero_dirs[j] == d) + { + continue; // skip the current direction + } // Create unit direction vectors for the other two directions DirectionVector e_dir_i; @@ -418,8 +427,8 @@ namespace samurai // Source: cells filled by sweeps in directions i and j // = translate(corner, direction + e_dir_i) and translate(corner, direction + e_dir_j) - auto source_i = translate(self(corner_lca).on(level), direction + e_dir_i); - auto source_j = translate(self(corner_lca).on(level), direction + e_dir_j); + auto source_i = translate(self(corner_lca).on(level), direction + e_dir_i); + auto source_j = translate(self(corner_lca).on(level), direction + e_dir_j); auto combined_source = union_(source_i, source_j); auto valid_source = intersection(combined_source, has_outer_neighbour).on(level); diff --git a/include/samurai/mesh.hpp b/include/samurai/mesh.hpp index e3b5bd8a5..213c68d97 100644 --- a/include/samurai/mesh.hpp +++ b/include/samurai/mesh.hpp @@ -946,52 +946,86 @@ namespace samurai template SAMURAI_INLINE void Mesh_base::construct_corners() { - using direction_t = DirectionVector; - - // For a diagonal direction d, the "corner" (inner cells at the boundary corner/edge) is: - // domain \ union_{i: d[i] != 0}( translate(domain, e_i * -d[i]) ) - // Only non-zero components are included: a zero component would give - // translate(domain, 0) = domain, making the union contain the domain itself - // and the difference empty. This is the correct formula for both true corner - // directions (all components ±1) and edge directions in 3D (one zero component). - m_corners.clear(); - for_each_diagonal_direction( - [&](const auto& direction) - { - // Collect shifts only for non-zero components - std::array nonzero_shifts; - std::size_t n = 0; - for (std::size_t I = 0; I < dim; ++I) + static_assert( + dim <= 6, + "Corner construction is currently only implemented up to 6D due to the combinatorial number of cases. Please implement the general ND version if you need higher dimensions."); + if constexpr (dim > 1) + { + using direction_t = DirectionVector; + + // For a diagonal direction d, the "corner" (inner cells at the boundary corner/edge) is: + // domain \ union_{i: d[i] != 0}( translate(domain, e_i * -d[i]) ) + // Only non-zero components are included: a zero component would give + // translate(domain, 0) = domain, making the union contain the domain itself + // and the difference empty. This is the correct formula for both true corner + // directions (all components ±1) and edge directions in 3D (one zero component). + m_corners.clear(); + for_each_diagonal_direction( + [&](const auto& direction) { - if (direction[I] != 0) + // Collect shifts only for non-zero components + std::array nonzero_shifts; + std::size_t n = 0; + for (std::size_t I = 0; I < dim; ++I) { - nonzero_shifts[n].fill(0); - nonzero_shifts[n][I] = -direction[I]; - ++n; + if (direction[I] != 0) + { + nonzero_shifts[n].fill(0); + nonzero_shifts[n][I] = -direction[I]; + ++n; + } } - } - // Apply union_ to non-zero-component translates only. - // for_each_diagonal_direction guarantees n >= 2. - // In 3D: n == 2 for edge directions, n == 3 for true corner directions. - if (n > 1) - { - // n == dim: all components are non-zero (true corner), use index sequence - auto translates = [&](std::index_sequence) + // Apply union_ to non-zero-component translates only. + // for_each_diagonal_direction guarantees n >= 2. + // In 3D: n == 2 for edge directions, n == 3 for true corner directions. + // TODO: make a ND version + if (n == 2) { - return std::make_tuple(translate(m_domain, nonzero_shifts[Is])...); - }(std::make_index_sequence{}); - - auto u = std::apply( - [](const auto&... ts) - { - return union_(ts...); - }, - translates); - - m_corners.push_back(difference(m_domain, u).to_lca()); - } - }); + m_corners.push_back( + difference(m_domain, union_(translate(m_domain, nonzero_shifts[0]), translate(m_domain, nonzero_shifts[1]))) + .to_lca()); + } + else if (n == 3) + { + m_corners.push_back(difference(m_domain, + union_(translate(m_domain, nonzero_shifts[0]), + translate(m_domain, nonzero_shifts[1]), + translate(m_domain, nonzero_shifts[2]))) + .to_lca()); + } + else if (n == 4) + { + m_corners.push_back(difference(m_domain, + union_(translate(m_domain, nonzero_shifts[0]), + translate(m_domain, nonzero_shifts[1]), + translate(m_domain, nonzero_shifts[2]), + translate(m_domain, nonzero_shifts[3]))) + .to_lca()); + } + else if (n == 5) + { + m_corners.push_back(difference(m_domain, + union_(translate(m_domain, nonzero_shifts[0]), + translate(m_domain, nonzero_shifts[1]), + translate(m_domain, nonzero_shifts[2]), + translate(m_domain, nonzero_shifts[3]), + translate(m_domain, nonzero_shifts[4]))) + .to_lca()); + } + else if (n == 6) + { + m_corners.push_back(difference(m_domain, + union_(translate(m_domain, nonzero_shifts[0]), + translate(m_domain, nonzero_shifts[1]), + translate(m_domain, nonzero_shifts[2]), + translate(m_domain, nonzero_shifts[3]), + translate(m_domain, nonzero_shifts[4]), + translate(m_domain, nonzero_shifts[5]))) + .to_lca()); + } + }); + } } template From 44ed1137353a5db5f3b3c5f3771ef1fda724ad0d Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Mon, 4 May 2026 21:00:14 +0200 Subject: [PATCH 3/4] update lid driven cavity results --- ...st_finite_volume_demo_lid_driven_cavity.h5 | Bin 168760 -> 168760 bytes ..._finite_volume_demo_lid_driven_cavity.xdmf | 26 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.h5 b/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.h5 index 73e4676133ec9432cbc56413dd1a1cd1222811a5..9164103ccfed93dfd1c269ea09fc56d3db558556 100644 GIT binary patch delta 18767 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%0AFhS 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 diff --git a/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf b/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf index b4da2dce3..6d71c2457 100644 --- a/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf +++ b/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf @@ -1,16 +1,16 @@ - - - - test_finite_volume_demo_lid_driven_cavity.h5:/mesh/connectivity - - - test_finite_volume_demo_lid_driven_cavity.h5:/mesh/points - - - test_finite_volume_demo_lid_driven_cavity.h5:/mesh/fields/ink - - - + + + + test_finite_volume_demo_lid_driven_cavity.h5:/mesh/connectivity + + + test_finite_volume_demo_lid_driven_cavity.h5:/mesh/points + + + test_finite_volume_demo_lid_driven_cavity.h5:/mesh/fields/ink + + + From e91024b8860129bdbfeb8e1d3dc1311b3b663bfd Mon Sep 17 00:00:00 2001 From: Loic Gouarin Date: Mon, 4 May 2026 21:35:31 +0200 Subject: [PATCH 4/4] fix pre-commit --- ..._finite_volume_demo_lid_driven_cavity.xdmf | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf b/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf index 6d71c2457..b4da2dce3 100644 --- a/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf +++ b/tests/reference/finite_volume/test_finite_volume_demo_lid_driven_cavity.xdmf @@ -1,16 +1,16 @@ - - - - test_finite_volume_demo_lid_driven_cavity.h5:/mesh/connectivity - - - test_finite_volume_demo_lid_driven_cavity.h5:/mesh/points - - - test_finite_volume_demo_lid_driven_cavity.h5:/mesh/fields/ink - - - + + + + test_finite_volume_demo_lid_driven_cavity.h5:/mesh/connectivity + + + test_finite_volume_demo_lid_driven_cavity.h5:/mesh/points + + + test_finite_volume_demo_lid_driven_cavity.h5:/mesh/fields/ink + + +