Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
160 commits
Select commit Hold shift + click to select a range
f62eecd
Start work
jpdean Jul 12, 2022
29cd3b1
Pass integration entities
jpdean Jul 12, 2022
d3f0369
Change Form constructor
jpdean Jul 12, 2022
06377dc
Restructure integral data
jpdean Jul 12, 2022
ac41b90
Set domains
jpdean Jul 12, 2022
e6d308d
Same for ext and int facets
jpdean Jul 12, 2022
7973ebc
Rename new integral data
jpdean Jul 12, 2022
88024a9
Set default domains
jpdean Jul 13, 2022
5f2b1ef
Start work on converting meshtags
jpdean Jul 13, 2022
be209e8
Fix for parallel
jpdean Jul 13, 2022
d55f0fb
Start work on ext facets
jpdean Jul 13, 2022
f4f0035
Move function
jpdean Jul 13, 2022
63bb4e0
Get ext facets working
jpdean Jul 13, 2022
bcbf256
Same for int facets
jpdean Jul 13, 2022
1a7ec76
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Jul 13, 2022
42e4054
Add comment
jpdean Jul 13, 2022
11ffe8a
Add docs
jpdean Jul 13, 2022
9189bbe
Fix docs
jpdean Jul 13, 2022
2684c93
Remove old code
jpdean Jul 13, 2022
b9b2d6c
Add test
jpdean Jul 13, 2022
a04da11
Fix for parallel
jpdean Jul 13, 2022
b34e33d
Remove cout
jpdean Jul 13, 2022
0b803e9
Add fix for measures without subdomain data
jpdean Jul 13, 2022
c08a044
Flake8
jpdean Jul 13, 2022
30893b0
Bind Form constructor
jpdean Jul 14, 2022
e4ee75b
Bind Form constructor
jpdean Jul 14, 2022
a4f124d
Make const
jpdean Jul 14, 2022
69aa67a
Fix and simplify
jpdean Jul 14, 2022
b406878
Make const reference
jpdean Jul 14, 2022
9ee7f81
Flake8
jpdean Jul 14, 2022
3f25107
Fix consts
jpdean Jul 14, 2022
bbda851
Update test
jpdean Jul 14, 2022
14ea680
Add FIXMEs
jpdean Jul 14, 2022
36806dc
Format
jpdean Jul 14, 2022
09c84e4
Remove commented code
jpdean Jul 14, 2022
93579d0
Remove old code
jpdean Jul 14, 2022
85a048d
Add to test
jpdean Jul 14, 2022
6305ec2
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Jul 14, 2022
090e8b6
Remove duplicate code
jpdean Jul 15, 2022
ab5ffe9
Simplify
jpdean Jul 15, 2022
2dd89a9
Improve test
jpdean Jul 15, 2022
ed23634
Update error message
jpdean Jul 15, 2022
264132d
Remove TODO
jpdean Jul 15, 2022
9d4646d
FIXMEs
jpdean Jul 15, 2022
b53423c
Add NOTE
jpdean Jul 15, 2022
f0bbd89
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Jul 15, 2022
7b6e5b3
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Jul 20, 2022
99e3047
Update docs
jpdean Jul 20, 2022
df6074b
Simplify
jpdean Jul 20, 2022
573bd71
Docs
jpdean Jul 20, 2022
2181476
Docs
jpdean Jul 20, 2022
52d87c8
Specify type explicitly
jpdean Jul 20, 2022
075643e
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Jul 22, 2022
7c9e6e5
Use exterior_facet_indices
jpdean Jul 22, 2022
545628a
Reduce number of map lookups
jpdean Jul 22, 2022
186bcc7
Improve docs
jpdean Jul 22, 2022
52007e1
fix typo
jpdean Jul 22, 2022
67a5ec5
Don't use isinstance
jpdean Jul 22, 2022
bf63ea0
Don't use isinstance
jpdean Jul 22, 2022
bd40d01
Move subdomain data check to dolfinx
jpdean Jul 22, 2022
e817549
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Jul 25, 2022
75662aa
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Aug 7, 2022
5ecf02a
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Aug 8, 2022
5119278
Flake8
jpdean Aug 8, 2022
3769ff8
Flake8
jpdean Aug 8, 2022
014a701
Flake8
jpdean Aug 8, 2022
1212dbb
Mypy
jpdean Aug 8, 2022
0679c47
Use UFL branch
jpdean Aug 8, 2022
8885904
Merge branch 'main' into jpdean/manual_integration_domains_2
jorgensd Sep 6, 2022
0452ee3
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Sep 6, 2022
015a79b
Put on single line
jpdean Sep 6, 2022
c72284f
Merge branch 'jpdean/manual_integration_domains_2' of github.com:FEni…
jpdean Sep 6, 2022
e645f72
Workaround for strange issue
jpdean Sep 6, 2022
a451dad
Flake8
jpdean Sep 6, 2022
fc90a58
Add TODOs
jpdean Sep 7, 2022
48edeae
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Sep 8, 2022
b6c0d71
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Sep 12, 2022
fb27110
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Sep 14, 2022
d46b8a0
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Sep 14, 2022
43bfaf9
Check all subdomain data is the same
jpdean Sep 16, 2022
9fce163
Use UFL branch
jpdean Sep 16, 2022
5c4500e
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Sep 26, 2022
6cb0294
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Sep 29, 2022
908ce88
Pass partitioner
jpdean Oct 6, 2022
cb834c7
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Oct 7, 2022
9626c0b
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Oct 17, 2022
3b214e2
Fix typo
jpdean Oct 17, 2022
e4c60d2
Merge branch 'main' into jpdean/multiple_subdomain_data
jpdean Oct 17, 2022
550ecc2
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Oct 21, 2022
1bee2ab
Merge branch 'main' into jpdean/multiple_subdomain_data
chrisrichardson Oct 21, 2022
d92bff4
Try to use sd.get(domain)
chrisrichardson Oct 21, 2022
aa95e56
Merge branch 'main' into jpdean/multiple_subdomain_data
jpdean Oct 31, 2022
b92737e
Change UFL branch
jpdean Oct 31, 2022
f880cf8
Merge branch 'main' into jpdean/multiple_subdomain_data
chrisrichardson Oct 31, 2022
9e2588a
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Oct 31, 2022
ec221d9
Change UFL branch
jpdean Oct 31, 2022
bc1b8ff
Merge branch 'jpdean/multiple_subdomain_data' into jpdean/manual_inte…
jpdean Oct 31, 2022
c519174
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Oct 31, 2022
d79c677
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Nov 4, 2022
aff551f
Use std::size_t
jpdean Nov 4, 2022
2c347c3
Fix bug
jpdean Nov 4, 2022
2664d63
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Nov 17, 2022
9b36c4a
Some fixes
jpdean Nov 17, 2022
c7508ec
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Nov 23, 2022
e6c1f17
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Nov 24, 2022
a5061de
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Nov 28, 2022
1ebc04d
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Dec 6, 2022
17568c9
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Dec 20, 2022
32ad526
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Dec 23, 2022
c3e51a5
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Dec 29, 2022
f05f947
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Jan 10, 2023
6e1c3cf
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Feb 2, 2023
79b4c6f
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Feb 11, 2023
a576179
Move meshtag to entity code
jpdean Feb 12, 2023
6882ad2
Fix bug
jpdean Feb 12, 2023
20f8e8a
Fix for parallel
jpdean Feb 12, 2023
8574db4
Fix bug where ghost entites were being added to integration domains b…
jpdean Feb 12, 2023
1a058b7
Simplify
jpdean Feb 12, 2023
841acf5
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Feb 12, 2023
43fc676
Merge branch 'main' into jpdean/manual_integration_domains_2
jpdean Feb 27, 2023
7a25d1b
Remove TODO
jpdean Mar 3, 2023
1954109
Remove unused function
jpdean Mar 3, 2023
cabb3e1
Avoid map lookup in tight loop
jpdean Mar 3, 2023
8ce9e00
Rename
jpdean Mar 5, 2023
49417cc
Same for facet integrals
jpdean Mar 5, 2023
6dfbc8e
Merge branch 'main' into jpdean/manual_integration_domains_2_refactoring
jpdean Mar 6, 2023
d8cad21
Remove unnecessary sort
jpdean Mar 6, 2023
33b1822
Remove function
jpdean Mar 6, 2023
b67dc16
Remove function
jpdean Mar 6, 2023
e5e2467
Tidy
jpdean Mar 6, 2023
b0fca68
Remove second map
jpdean Mar 6, 2023
57e8b05
Change type
jpdean Mar 6, 2023
690971c
Update test
jpdean Mar 6, 2023
e00d53f
Tidy
jpdean Mar 6, 2023
0c51fce
Update type
jpdean Mar 6, 2023
f4ef663
Tidy
jpdean Mar 6, 2023
caccd2c
Fix seg fault
jpdean Mar 6, 2023
1baae06
Tidy
jpdean Mar 6, 2023
269c93a
Simplify
jpdean Mar 6, 2023
3a3dfa9
Simplify
jpdean Mar 6, 2023
eb14d81
Small style fixes
garth-wells Mar 7, 2023
788f71f
Readability improvement.
garth-wells Mar 7, 2023
728f125
Merge branch 'main' into jpdean/manual_integration_domains_2
garth-wells Mar 12, 2023
1f1daeb
Improve pybind11 wrapping
garth-wells Mar 12, 2023
8582233
Merge branch 'jpdean/manual_integration_domains_2' of github.com:FEni…
garth-wells Mar 12, 2023
b341781
Avoid copies
garth-wells Mar 12, 2023
7a316fa
Simplifications
garth-wells Mar 12, 2023
dcd66d5
Small fix
garth-wells Mar 12, 2023
d21bd3e
Revert some changes
garth-wells Mar 12, 2023
6fa9f29
Interface fix
garth-wells Mar 12, 2023
5075832
Work on doc
garth-wells Mar 12, 2023
54600f3
Avoid costly allocations
garth-wells Mar 12, 2023
0c8e7b3
Cleanup
garth-wells Mar 12, 2023
c13724f
Use stable sort
garth-wells Mar 12, 2023
7637f5f
Merge branch 'main' into jpdean/manual_integration_domains_2
garth-wells Mar 12, 2023
98bc806
Simplificstions
garth-wells Mar 12, 2023
377876b
Small naming improvements
garth-wells Mar 13, 2023
c6a6e32
Bug fix
garth-wells Mar 13, 2023
f8b6c71
Another fix
garth-wells Mar 13, 2023
088f2d3
Tidy up
garth-wells Mar 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions cpp/dolfinx/fem/Form.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,8 @@ class Form
throw std::runtime_error("No mesh could be associated with the Form.");

// Store kernels, looping over integrals by domain type (dimension)
for (auto& integral_type : integrals)
for (auto& [type, kernels] : integrals)
{
const IntegralType type = integral_type.first;
auto& kernels = integral_type.second;

// Loop over integrals kernels and set domains
switch (type)
{
Expand Down
8 changes: 4 additions & 4 deletions cpp/dolfinx/fem/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ class Function
std::int32_t num_cells = cell_map->size_local() + cell_map->num_ghosts();
std::vector<std::int32_t> cells(num_cells, 0);
std::iota(cells.begin(), cells.end(), 0);

interpolate(v, cells, nmm_interpolation_data);
}

Expand Down Expand Up @@ -217,6 +216,7 @@ class Function
throw std::runtime_error(
"Data returned by callable has wrong shape(0) size");
}

if (fshape[1] != x.size() / 3)
{
throw std::runtime_error(
Expand Down Expand Up @@ -285,6 +285,7 @@ class Function
"Function element interpolation points has different shape to "
"Expression interpolation points");
}

for (std::size_t i = 0; i < X0.size(); ++i)
{
if (std::abs(X0[i] - X1[i]) > 1.0e-10)
Expand All @@ -295,9 +296,8 @@ class Function
}
}

namespace stdex = std::experimental;

// Array to hold evaluated Expression
namespace stdex = std::experimental;
std::size_t num_cells = cells.size();
std::size_t num_points = e.X().second[0];
std::vector<T> fdata(num_cells * num_points * value_size);
Expand All @@ -312,7 +312,6 @@ class Function
// value_size), i.e. xyzxyz ordering of dof values per cell per point.
// The interpolation uses xxyyzz input, ordered for all points of each
// cell, i.e. (value_size, num_cells*num_points)

std::vector<T> fdata1(num_cells * num_points * value_size);
stdex::mdspan<T, stdex::dextents<std::size_t, 3>> f1(
fdata1.data(), value_size, num_cells, num_points);
Expand Down Expand Up @@ -371,6 +370,7 @@ class Function
throw std::runtime_error(
"Number of points and number of cells must be equal.");
}

if (xshape[0] != ushape[0])
{
throw std::runtime_error(
Expand Down
4 changes: 2 additions & 2 deletions cpp/dolfinx/fem/assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class FunctionSpace;

/// @brief Create a map of `std::span`s from a map of `std::vector`s
template <typename T>
std::map<std::pair<fem::IntegralType, int>, std::pair<std::span<const T>, int>>
std::map<std::pair<IntegralType, int>, std::pair<std::span<const T>, int>>
make_coefficients_span(const std::map<std::pair<IntegralType, int>,
std::pair<std::vector<T>, int>>& coeffs)
{
Expand Down Expand Up @@ -394,7 +394,7 @@ void set_diagonal(auto set_fn, std::span<const std::int32_t> rows,
/// @param[in] diagonal The value to add to the diagonal for rows with a
/// boundary condition applied
template <typename T>
void set_diagonal(auto set_fn, const fem::FunctionSpace& V,
void set_diagonal(auto set_fn, const FunctionSpace& V,
const std::vector<std::shared_ptr<const DirichletBC<T>>>& bcs,
T diagonal = 1.0)
{
Expand Down
28 changes: 15 additions & 13 deletions cpp/dolfinx/fem/interpolate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,40 +69,43 @@ fem::interpolation_coords(const FiniteElement& element, const mesh::Mesh& mesh,

return x;
}

//-----------------------------------------------------------------------------
fem::nmm_interpolation_data_t fem::create_nonmatching_meshes_interpolation_data(
const fem::FunctionSpace& Vu, const fem::FunctionSpace& Vv,
std::span<const std::int32_t> cells)
{
std::vector<double> x;
auto mesh = Vu.mesh();
auto mesh_v = Vv.mesh();
auto element_u = Vu.element();

// Collect all the points at which values are needed to define the
// interpolating function
auto element_u = Vu.element();
assert(element_u);
auto mesh = Vu.mesh();
assert(mesh);
const std::vector<double> coords_b
= fem::interpolation_coords(*element_u, *mesh, cells);
= interpolation_coords(*element_u, *mesh, cells);

namespace stdex = std::experimental;
using cmdspan2_t
= stdex::mdspan<const double, stdex::dextents<std::size_t, 2>>;
using mdspan2_t = stdex::mdspan<double, stdex::dextents<std::size_t, 2>>;
cmdspan2_t coords(coords_b.data(), 3, coords_b.size() / 3);

// Transpose interpolation coords
x.resize(coords.size());
std::vector<double> x(coords.size());
mdspan2_t _x(x.data(), coords_b.size() / 3, 3);
for (std::size_t j = 0; j < coords.extent(1); ++j)
for (std::size_t i = 0; i < 3; ++i)
_x(j, i) = coords(i, j);

// Determine ownership of each point
return dolfinx::geometry::determine_point_ownership(*mesh_v, x);
auto mesh_v = Vv.mesh();
assert(mesh_v);
return geometry::determine_point_ownership(*mesh_v, x);
}

fem::nmm_interpolation_data_t fem::create_nonmatching_meshes_interpolation_data(
const dolfinx::fem::FunctionSpace& Vu,
const dolfinx::fem::FunctionSpace& Vv)
//-----------------------------------------------------------------------------
fem::nmm_interpolation_data_t
fem::create_nonmatching_meshes_interpolation_data(const FunctionSpace& Vu,
const FunctionSpace& Vv)
{
assert(Vu.mesh());
int tdim = Vu.mesh()->topology().dim();
Expand All @@ -111,7 +114,6 @@ fem::nmm_interpolation_data_t fem::create_nonmatching_meshes_interpolation_data(
std::int32_t num_cells = cell_map->size_local() + cell_map->num_ghosts();
std::vector<std::int32_t> cells(num_cells, 0);
std::iota(cells.begin(), cells.end(), 0);

return create_nonmatching_meshes_interpolation_data(Vu, Vv, cells);
}
//-----------------------------------------------------------------------------
18 changes: 9 additions & 9 deletions cpp/dolfinx/fem/interpolate.h
Original file line number Diff line number Diff line change
Expand Up @@ -916,28 +916,28 @@ void interpolate(Function<T>& u, std::span<const T> f,
}
}

/// Generate data needed to interpolate discrete functions across different
/// meshes
/// Generate data needed to interpolate discrete functions across
/// different meshes.
///
/// @param[out] Vu The function space of the function to interpolate into
/// @param[out] Vu The function space of the function to interpolate
/// into
/// @param[in] Vv The function space of the function to interpolate from
/// @param[in] cells Indices of the cells in the destination mesh on which to
/// interpolate. Should be the same as the list used when calling
/// fem::interpolation_coords.
/// @param[in] cells Indices of the cells in the destination mesh on
/// which to interpolate. Should be the same as the list used when
/// calling fem::interpolation_coords.
nmm_interpolation_data_t create_nonmatching_meshes_interpolation_data(
const FunctionSpace& Vu, const FunctionSpace& Vv,
std::span<const std::int32_t> cells);

/// Generate data needed to interpolate discrete functions defined on different
/// meshes. Interpolate on all cells in the mesh.
/// Generate data needed to interpolate discrete functions defined on
/// different meshes. Interpolate on all cells in the mesh.
///
/// @param[out] Vu The function space of the function to interpolate into
/// @param[in] Vv The function space of the function to interpolate from
nmm_interpolation_data_t
create_nonmatching_meshes_interpolation_data(const FunctionSpace& Vu,
const FunctionSpace& Vv);

//----------------------------------------------------------------------------
/// Interpolate from one finite element Function to another one
/// @param[out] u The function to interpolate into
/// @param[in] v The function to be interpolated
Expand Down
129 changes: 127 additions & 2 deletions cpp/dolfinx/fem/utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "Function.h"
#include "FunctionSpace.h"
#include "dofmapbuilder.h"
#include <algorithm>
#include <array>
#include <dolfinx/common/IndexMap.h>
#include <dolfinx/common/Timer.h>
Expand Down Expand Up @@ -197,8 +198,6 @@ fem::FunctionSpace fem::create_functionspace(
const std::function<std::vector<int>(
const graph::AdjacencyList<std::int32_t>&)>& reorder_fn)
{
assert(mesh);

// Create a DOLFINx element
auto _e = std::make_shared<FiniteElement>(e, bs);

Expand All @@ -220,6 +219,7 @@ fem::FunctionSpace fem::create_functionspace(
// Create a dofmap
ElementDofLayout layout(bs, e.entity_dofs(), e.entity_closure_dofs(), {},
sub_doflayout);
assert(mesh);
auto dofmap = std::make_shared<const DofMap>(
create_dofmap(mesh->comm(), layout, mesh->topology(), reorder_fn, *_e));

Expand Down Expand Up @@ -266,3 +266,128 @@ fem::FunctionSpace fem::create_functionspace(
mesh->comm(), layout, mesh->topology(), reorder_fn, *element)));
}
//-----------------------------------------------------------------------------
std::vector<std::pair<int, std::vector<std::int32_t>>>
fem::compute_integration_domains(fem::IntegralType integral_type,
const mesh::MeshTags<int>& meshtags)
{
std::shared_ptr<const mesh::Mesh> mesh = meshtags.mesh();
assert(mesh);
const mesh::Topology& topology = mesh->topology();
const int tdim = topology.dim();
const int dim = integral_type == IntegralType::cell ? tdim : tdim - 1;
if (dim != meshtags.dim())
{
throw std::runtime_error("Invalid MeshTags dimension: "
+ std::to_string(meshtags.dim()));
}

std::span<const std::int32_t> entities = meshtags.indices();
std::span<const int> values = meshtags.values();
{
assert(topology.index_map(dim));
auto it0 = entities.begin();
auto it1 = std::lower_bound(it0, entities.end(),
topology.index_map(dim)->size_local());
entities = entities.first(std::distance(it0, it1));
values = values.first(std::distance(it0, it1));
}

std::vector<std::int32_t> entity_data;
std::vector<int> values1;
switch (integral_type)
{
case IntegralType::cell:
entity_data.insert(entity_data.begin(), entities.begin(), entities.end());
values1.insert(values1.begin(), values.begin(), values.end());
break;
default:
mesh->topology_mutable().create_connectivity(dim, tdim);
mesh->topology_mutable().create_connectivity(tdim, dim);
auto f_to_c = topology.connectivity(tdim - 1, tdim);
assert(f_to_c);
auto c_to_f = topology.connectivity(tdim, tdim - 1);
assert(c_to_f);
switch (integral_type)
{
case IntegralType::exterior_facet:
{
// Create list of tagged boundary facets
const std::vector bfacets = mesh::exterior_facet_indices(topology);
std::vector<std::int32_t> facets;
std::set_intersection(entities.begin(), entities.end(), bfacets.begin(),
bfacets.end(), std::back_inserter(facets));
for (auto f : facets)
{
auto index_it = std::lower_bound(entities.begin(), entities.end(), f);
assert(index_it != entities.end() and *index_it == f);
std::size_t pos = std::distance(entities.begin(), index_it);
auto facet
= impl::get_cell_facet_pairs<1>(f, f_to_c->links(f), *c_to_f);
entity_data.insert(entity_data.end(), facet.begin(), facet.end());
values1.push_back(values[pos]);
}
}
break;
case IntegralType::interior_facet:
{
for (std::size_t j = 0; j < entities.size(); ++j)
{
const std::int32_t f = entities[j];
if (f_to_c->num_links(f) == 2)
{
// Get the facet as a pair of (cell, local facet) pairs, one
// for each cell
auto facets
= impl::get_cell_facet_pairs<2>(f, f_to_c->links(f), *c_to_f);
entity_data.insert(entity_data.end(), facets.begin(), facets.end());
values1.push_back(values[j]);
}
}
}
break;
default:
throw std::runtime_error(
"Cannot compute integration domains. Integral type not supported.");
}
}

// Build permutation that sorts by meshtag value
std::vector<std::int32_t> perm(values1.size());
std::iota(perm.begin(), perm.end(), 0);
std::stable_sort(perm.begin(), perm.end(),
[&values1](auto p0, auto p1)
{ return values1[p0] < values1[p1]; });

std::size_t shape = 1;
if (integral_type == IntegralType::exterior_facet)
shape = 2;
else if (integral_type == IntegralType::interior_facet)
shape = 4;
std::vector<std::pair<int, std::vector<std::int32_t>>> integrals;
{
// Iterator to mark the start of the group
auto p0 = perm.begin();
while (p0 != perm.end())
{
auto id0 = values1[*p0];
auto p1 = std::find_if_not(p0, perm.end(),
[id0, &values1](auto idx)
{ return id0 == values1[idx]; });

std::vector<std::int32_t> data;
data.reserve(shape * std::distance(p0, p1));
for (auto it = p0; it != p1; ++it)
{
auto e_it0 = std::next(entity_data.begin(), (*it) * shape);
auto e_it1 = std::next(e_it0, shape);
data.insert(data.end(), e_it0, e_it1);
}

integrals.push_back({id0, std::move(data)});
p0 = p1;
}
}

return integrals;
}
//-----------------------------------------------------------------------------
Loading