Skip to content

Commit c3e4f81

Browse files
committed
Replace IntegralType with structure storing the necessary information
1 parent 1dfaef4 commit c3e4f81

14 files changed

Lines changed: 226 additions & 238 deletions

File tree

cpp/demo/codim_0_assembly/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ int main(int argc, char* argv[])
100100
// domain `mesh`
101101
std::vector<std::int32_t> integration_entities
102102
= fem::compute_integration_domains(
103-
fem::IntegralType::cell, *mesh->topology(), cell_marker.find(2));
103+
fem::IntegralType(0, 1), *mesh->topology(), cell_marker.find(2));
104104
std::map<
105105
fem::IntegralType,
106106
std::vector<std::pair<std::int32_t, std::span<const std::int32_t>>>>
107107
subdomain_data
108-
= {{fem::IntegralType::cell, {{3, integration_entities}}}};
108+
= {{fem::IntegralType(0, 1), {{3, integration_entities}}}};
109109

110110
// A mixed-domain form involves functions defined over multiple
111111
// meshes. The mesh passed to `create_form` is called the

cpp/demo/custom_kernel/main.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ double assemble_matrix0(std::shared_ptr<const fem::FunctionSpace<T>> V,
7575
{
7676
// Kernel data (ID, kernel function, cell indices to execute over)
7777
std::map integrals{
78-
std::pair{std::tuple{fem::IntegralType::cell, 0, 0},
78+
std::pair{std::tuple{fem::IntegralType(0, 1), 0, 0},
7979
fem::integral_data<T>(kernel, cells, std::vector<int>{})}};
8080

8181
fem::Form<T, T> a({V, V}, integrals, V->mesh(), {}, {}, false, {});
@@ -105,7 +105,7 @@ double assemble_vector0(std::shared_ptr<const fem::FunctionSpace<T>> V,
105105
{
106106
auto mesh = V->mesh();
107107
std::map integrals{
108-
std::pair{std::tuple{fem::IntegralType::cell, 0, 0},
108+
std::pair{std::tuple{fem::IntegralType(0, 1), 0, 0},
109109
fem::integral_data<T>(kernel, cells, std::vector<int>{})}};
110110
fem::Form<T> L({V}, integrals, mesh, {}, {}, false, {});
111111
auto dofmap = V->dofmap();

cpp/demo/mixed_poisson/main.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -271,17 +271,17 @@ int main(int argc, char* argv[])
271271
// (applied on the `ds(1)` in the UFL file). First we get facet data
272272
// integration data for facets in dfacets.
273273
std::vector<std::int32_t> domains = fem::compute_integration_domains(
274-
fem::IntegralType::facet, *mesh->topology(), dfacets);
274+
IntegralType(1, 1), *mesh->topology(), dfacets);
275275

276276
// Create data structure for the `ds(1)` integration domain in form
277277
// (see the UFL file). It is for en exterior facet integral (the key
278278
// in the map), and exterior facet domain marked as '1' in the UFL
279279
// file, and `domains` holds the necessary data to perform
280280
// integration of selected facets.
281281
std::map<
282-
fem::IntegralType,
282+
std::int32_t,
283283
std::vector<std::pair<std::int32_t, std::span<const std::int32_t>>>>
284-
subdomain_data{{fem::IntegralType::facet, {{1, domains}}}};
284+
subdomain_data{{IntegralType(1, 1), {{1, domains}}}};
285285

286286
// Since we are doing a `ds(1)` integral on mesh and `u0` is defined
287287
// on the `submesh`, our form involves more than one mesh. The mesh

cpp/dolfinx/fem/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ target_sources(
3434
${CMAKE_CURRENT_SOURCE_DIR}/DofMap.cpp
3535
${CMAKE_CURRENT_SOURCE_DIR}/ElementDofLayout.cpp
3636
${CMAKE_CURRENT_SOURCE_DIR}/FiniteElement.cpp
37+
${CMAKE_CURRENT_SOURCE_DIR}/Form.cpp
3738
${CMAKE_CURRENT_SOURCE_DIR}/dofmapbuilder.cpp
3839
${CMAKE_CURRENT_SOURCE_DIR}/petsc.cpp
3940
${CMAKE_CURRENT_SOURCE_DIR}/sparsitybuild.cpp

cpp/dolfinx/fem/Form.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (C) 2025 Jørgen S. Dokken
2+
//
3+
// This file is part of DOLFINx (https://www.fenicsproject.org)
4+
//
5+
// SPDX-License-Identifier: LGPL-3.0-or-later
6+
7+
#include "Form.h"
8+
9+
bool dolfinx::fem::operator<(const dolfinx::fem::IntegralType& self,
10+
const dolfinx::fem::IntegralType& other)
11+
{
12+
// First, compare codim
13+
if (self.codim < other.codim)
14+
{
15+
return true;
16+
}
17+
// If codims are equal, compare num_cells
18+
if (self.codim == other.codim)
19+
{
20+
return self.num_cells < other.num_cells;
21+
}
22+
// Otherwise, this object is not less than 'other'
23+
return false;
24+
}

cpp/dolfinx/fem/Form.h

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,24 @@ template <dolfinx::scalar T, std::floating_point U>
3535
class Function;
3636

3737
/// @brief Type of integral
38-
enum class IntegralType : std::int8_t
38+
39+
struct IntegralType
3940
{
40-
cell = 0, ///< Cell
41-
facet = 1, ///< Facet
42-
interior_facet = 2, ///< Interior facet
43-
vertex = 3 ///< Vertex
41+
std::int32_t codim; ///< Codimension of the integral
42+
std::int32_t num_cells; ///< Number of cells in the integral
43+
44+
/// @brief Equality operator for integral type
45+
/// @param other The other IntegralType to compare with
46+
/// @return True if the integral types are equal, false otherwise
47+
bool operator==(const IntegralType& other) const
48+
{
49+
return codim == other.codim && num_cells == other.num_cells;
50+
}
4451
};
4552

53+
// Overload the less-than operator
54+
bool operator<(const IntegralType& self, const IntegralType& other);
55+
4656
/// @brief Represents integral data, containing the kernel, and a list
4757
/// of entities to integrate over and the indicies of the coefficient
4858
/// functions (relative to the Form) active for this integral.
@@ -274,10 +284,9 @@ class Form
274284
{
275285
auto [type, idx, kernel_idx] = key;
276286
std::vector<std::int32_t> e;
277-
if (type == IntegralType::cell)
287+
if (type.codim == 0)
278288
e = emap.sub_topology_to_topology(itg.entities, inverse);
279-
else if (type == IntegralType::facet
280-
or type == IntegralType::interior_facet)
289+
else if (type.codim = 1)
281290
{
282291
const mesh::Topology topology = *_mesh->topology();
283292
int tdim = topology.dim();
@@ -317,10 +326,9 @@ class Form
317326
bool inverse = emap.sub_topology() == mesh0->topology();
318327

319328
std::vector<std::int32_t> e;
320-
if (type == IntegralType::cell)
329+
if (type.codim == 0)
321330
e = emap.sub_topology_to_topology(integral.entities, inverse);
322-
else if (type == IntegralType::facet
323-
or type == IntegralType::interior_facet)
331+
else if (type.codim == 1)
324332
{
325333
const mesh::Topology topology = *_mesh->topology();
326334
int tdim = topology.dim();
@@ -454,16 +462,12 @@ class Form
454462
/// These are the entities in the mesh returned by ::mesh that are
455463
/// integrated over by a given integral (kernel).
456464
///
457-
/// - For IntegralType::cell, returns a list of cell indices.
458-
/// - For IntegralType::facet, returns a list with shape
459-
/// `(num_facets, 2)`, where `[cell_index, 0]` is the cell index and
460-
/// `[cell_index, 1]` is the local facet index relative to the cell.
461-
/// - For IntegralType::interior_facet the shape is `(num_facets, 4)`,
462-
/// where `[cell_index, 0]` is one attached cell and `[cell_index, 1]`
463-
/// is the is the local facet index relative to the cell, and
464-
/// `[cell_index, 2]` is the other one attached cell and `[cell_index, 1]`
465-
/// is the is the local facet index relative to this cell. Storage
466-
/// is row-major.
465+
/// - For IntegralType of codim 0 returns a list of cell indices.
466+
/// - For any other codim return a set of tuples `[cell_index,
467+
/// local_entity_index]`.
468+
/// - If the number of cells in the integral type, return as many tuples per
469+
/// entity as there are number of cells in the integral type. Storage is
470+
/// row-major.
467471
///
468472
/// @param[in] type Integral type.
469473
/// @param[in] idx Integral index in flattened list of integral kernels.

cpp/dolfinx/fem/assemble_matrix_impl.h

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -588,15 +588,15 @@ void assemble_matrix(
588588
cell_info0 = std::span(mesh0->topology()->get_cell_permutation_info());
589589
cell_info1 = std::span(mesh1->topology()->get_cell_permutation_info());
590590
}
591-
592-
for (int i = 0; i < a.num_integrals(IntegralType::cell, cell_type_idx); ++i)
591+
IntegralType cell_integral = IntegralType(0, 1);
592+
for (int i = 0; i < a.num_integrals(cell_integral, cell_type_idx); ++i)
593593
{
594-
auto fn = a.kernel(IntegralType::cell, i, cell_type_idx);
594+
auto fn = a.kernel(cell_integral, i, cell_type_idx);
595595
assert(fn);
596-
std::span cells = a.domain(IntegralType::cell, i, cell_type_idx);
597-
std::span cells0 = a.domain_arg(IntegralType::cell, 0, i, cell_type_idx);
598-
std::span cells1 = a.domain_arg(IntegralType::cell, 1, i, cell_type_idx);
599-
auto& [coeffs, cstride] = coefficients.at({IntegralType::cell, i});
596+
std::span cells = a.domain(cell_integral, i, cell_type_idx);
597+
std::span cells0 = a.domain_arg(cell_integral, 0, i, cell_type_idx);
598+
std::span cells1 = a.domain_arg(cell_integral, 1, i, cell_type_idx);
599+
auto& [coeffs, cstride] = coefficients.at({cell_integral, i});
600600
assert(cells.size() * cstride == coeffs.size());
601601
impl::assemble_cells_matrix(
602602
mat_set, x_dofmap, x, cells, {dofs0, bs0, cells0}, P0,
@@ -618,8 +618,8 @@ void assemble_matrix(
618618
num_facets_per_cell);
619619
}
620620

621-
for (int i = 0; i < a.num_integrals(IntegralType::facet, cell_type_idx);
622-
++i)
621+
IntegralType facet = IntegralType(1, 1);
622+
for (int i = 0; i < a.num_integrals(facet, cell_type_idx); ++i)
623623
{
624624
if (num_cell_types > 1)
625625
{
@@ -631,15 +631,15 @@ void assemble_matrix(
631631
= md::mdspan<const std::int32_t,
632632
md::extents<std::size_t, md::dynamic_extent, 2>>;
633633

634-
auto fn = a.kernel(IntegralType::facet, i, 0);
634+
auto fn = a.kernel(facet, i, 0);
635635
assert(fn);
636-
auto& [coeffs, cstride] = coefficients.at({IntegralType::facet, i});
636+
auto& [coeffs, cstride] = coefficients.at({facet, i});
637637

638-
std::span f = a.domain(IntegralType::facet, i, 0);
638+
std::span f = a.domain(facet, i, 0);
639639
mdspanx2_t facets(f.data(), f.size() / 2, 2);
640-
std::span f0 = a.domain_arg(IntegralType::facet, 0, i, 0);
640+
std::span f0 = a.domain_arg(facet, 0, i, 0);
641641
mdspanx2_t facets0(f0.data(), f0.size() / 2, 2);
642-
std::span f1 = a.domain_arg(IntegralType::facet, 1, i, 0);
642+
std::span f1 = a.domain_arg(facet, 1, i, 0);
643643
mdspanx2_t facets1(f1.data(), f1.size() / 2, 2);
644644
assert((facets.size() / 2) * cstride == coeffs.size());
645645
impl::assemble_exterior_facets(
@@ -649,8 +649,8 @@ void assemble_matrix(
649649
cell_info0, cell_info1, perms);
650650
}
651651

652-
for (int i = 0;
653-
i < a.num_integrals(IntegralType::interior_facet, cell_type_idx); ++i)
652+
IntegralType interior_facet = IntegralType(1, 2);
653+
for (int i = 0; i < a.num_integrals(interior_facet, cell_type_idx); ++i)
654654
{
655655
if (num_cell_types > 1)
656656
{
@@ -665,14 +665,13 @@ void assemble_matrix(
665665
= md::mdspan<const T, md::extents<std::size_t, md::dynamic_extent, 2,
666666
md::dynamic_extent>>;
667667

668-
auto fn = a.kernel(IntegralType::interior_facet, i, 0);
668+
auto fn = a.kernel(interior_facet, i, 0);
669669
assert(fn);
670-
auto& [coeffs, cstride]
671-
= coefficients.at({IntegralType::interior_facet, i});
670+
auto& [coeffs, cstride] = coefficients.at({interior_facet, i});
672671

673-
std::span facets = a.domain(IntegralType::interior_facet, i, 0);
674-
std::span facets0 = a.domain_arg(IntegralType::interior_facet, 0, i, 0);
675-
std::span facets1 = a.domain_arg(IntegralType::interior_facet, 1, i, 0);
672+
std::span facets = a.domain(interior_facet, i, 0);
673+
std::span facets0 = a.domain_arg(interior_facet, 0, i, 0);
674+
std::span facets1 = a.domain_arg(interior_facet, 1, i, 0);
676675
assert((facets.size() / 4) * 2 * cstride == coeffs.size());
677676
impl::assemble_interior_facets(
678677
mat_set, x_dofmap, x,

cpp/dolfinx/fem/assemble_scalar_impl.h

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,13 @@ T assemble_scalar(
201201
std::vector<scalar_value_t<T>> cdofs_b(2 * 3 * x_dofmap.extent(1));
202202

203203
T value = 0;
204-
for (int i = 0; i < M.num_integrals(IntegralType::cell, 0); ++i)
204+
IntegralType cell_integral = IntegralType(0, 1);
205+
for (int i = 0; i < M.num_integrals(cell_integral, 0); ++i)
205206
{
206-
auto fn = M.kernel(IntegralType::cell, i, 0);
207+
auto fn = M.kernel(cell_integral, i, 0);
207208
assert(fn);
208-
auto& [coeffs, cstride] = coefficients.at({IntegralType::cell, i});
209-
std::span<const std::int32_t> cells = M.domain(IntegralType::cell, i, 0);
209+
auto& [coeffs, cstride] = coefficients.at({cell_integral, i});
210+
std::span<const std::int32_t> cells = M.domain(cell_integral, i, 0);
210211
assert(cells.size() * cstride == coeffs.size());
211212
value += impl::assemble_cells(
212213
x_dofmap, x, cells, fn, constants,
@@ -226,13 +227,14 @@ T assemble_scalar(
226227
num_facets_per_cell);
227228
}
228229

229-
for (int i = 0; i < M.num_integrals(IntegralType::facet, 0); ++i)
230+
IntegralType facet_type = IntegralType(1, 1);
231+
for (int i = 0; i < M.num_integrals(facet_type, 0); ++i)
230232
{
231-
auto fn = M.kernel(IntegralType::facet, i, 0);
233+
auto fn = M.kernel(facet_type, i, 0);
232234
assert(fn);
233-
auto& [coeffs, cstride] = coefficients.at({IntegralType::facet, i});
235+
auto& [coeffs, cstride] = coefficients.at({facet_type, i});
234236

235-
std::span facets = M.domain(IntegralType::facet, i, 0);
237+
std::span facets = M.domain(facet_type, i, 0);
236238

237239
// Two values per each adjacent cell (cell index and local facet
238240
// index)
@@ -250,13 +252,13 @@ T assemble_scalar(
250252
cdofs_b);
251253
}
252254

253-
for (int i = 0; i < M.num_integrals(IntegralType::interior_facet, 0); ++i)
255+
IntegralType interior_facet_type = IntegralType(1, 2);
256+
for (int i = 0; i < M.num_integrals(interior_facet_type, 0); ++i)
254257
{
255-
auto fn = M.kernel(IntegralType::interior_facet, i, 0);
258+
auto fn = M.kernel(interior_facet_type, i, 0);
256259
assert(fn);
257-
auto& [coeffs, cstride]
258-
= coefficients.at({IntegralType::interior_facet, i});
259-
std::span facets = M.domain(IntegralType::interior_facet, i, 0);
260+
auto& [coeffs, cstride] = coefficients.at({interior_facet_type, i});
261+
std::span facets = M.domain(interior_facet_type, i, 0);
260262

261263
constexpr std::size_t num_adjacent_cells = 2;
262264
// Two values per each adj. cell (cell index and local facet index).
@@ -275,15 +277,15 @@ T assemble_scalar(
275277
perms, cdofs_b);
276278
}
277279

278-
for (int i = 0; i < M.num_integrals(IntegralType::vertex, 0); ++i)
280+
IntegralType vertex_type = IntegralType(1, 2);
281+
for (int i = 0; i < M.num_integrals(vertex_type, 0); ++i)
279282
{
280-
auto fn = M.kernel(IntegralType::vertex, i, 0);
283+
auto fn = M.kernel(vertex_type, i, 0);
281284
assert(fn);
282285

283-
auto& [coeffs, cstride] = coefficients.at({IntegralType::vertex, i});
286+
auto& [coeffs, cstride] = coefficients.at({vertex_type, i});
284287

285-
std::span<const std::int32_t> vertices
286-
= M.domain(IntegralType::vertex, i, 0);
288+
std::span<const std::int32_t> vertices = M.domain(vertex_type, i, 0);
287289
assert(vertices.size() * cstride == coeffs.size());
288290

289291
constexpr std::size_t num_adjacent_cells = 1;

0 commit comments

Comments
 (0)