Skip to content

Mixed topology #2597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 93 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
93 commits
Select commit Hold shift + click to select a range
389b2f5
compile
chrisrichardson Nov 28, 2022
efc5613
Merge branch 'main' into chris/mixed-geom
chrisrichardson Jan 10, 2023
c84d253
Catch a few cases
chrisrichardson Jan 11, 2023
ffb6f03
Fix typo
chrisrichardson Jan 11, 2023
28ce267
Change create_topology input [skip ci]
chrisrichardson Jan 11, 2023
7bac6a4
update create topology
IgorBaratta Jan 11, 2023
51349bc
add some checks
IgorBaratta Jan 11, 2023
3157382
afix documentation
IgorBaratta Jan 11, 2023
5dd1b1e
remove checl
IgorBaratta Jan 11, 2023
2fb15c4
fix type conversion
IgorBaratta Jan 11, 2023
ddb7e51
fix "const"
IgorBaratta Jan 11, 2023
3c7fb71
Store multiple cell types
chrisrichardson Jan 11, 2023
7aa8061
Merge branch 'mixed-topology-hackathon-23' of ssh://github.com/fenics…
chrisrichardson Jan 11, 2023
2ce930b
Start demo
jpdean Jan 11, 2023
50240e8
Merge branch 'mixed-topology-hackathon-23' of github.com:FEniCS/dolfi…
jpdean Jan 11, 2023
e0c4d71
remove petsc from demo
IgorBaratta Jan 11, 2023
d5235ee
fix test
IgorBaratta Jan 11, 2023
7b237c2
Fix test
chrisrichardson Jan 11, 2023
f3581e9
fix
chrisrichardson Jan 11, 2023
6f88835
Fix demo
chrisrichardson Jan 11, 2023
dc673db
Sort and unique boundary vertices
chrisrichardson Jan 11, 2023
86f58ef
Print out something
chrisrichardson Jan 11, 2023
e197dd6
Generalise test
jpdean Jan 11, 2023
38add11
throw an error if multiple cell types are used where. ...
IgorBaratta Jan 11, 2023
ed5c949
Merge branch 'mixed-topology-hackathon-23' of github.com:FEniCS/dolfi…
IgorBaratta Jan 11, 2023
df024a7
Merge branch 'mixed-topology-hackathon-23' of github.com:FEniCS/dolfi…
jpdean Jan 11, 2023
46bcf23
Print
jpdean Jan 11, 2023
6bc54ef
Merge branch 'mixed-topology-hackathon-23' of github.com:FEniCS/dolfi…
jpdean Jan 11, 2023
5e6633a
Fix offsets
jpdean Jan 11, 2023
f652eef
Fix python layer
chrisrichardson Jan 11, 2023
ab50554
Fix in python wrapper
chrisrichardson Jan 11, 2023
3cd927e
fix cpp build
IgorBaratta Jan 11, 2023
d9be3dd
Merge branch 'chris/mixed-geom' of github.com:FEniCS/dolfinx into chr…
IgorBaratta Jan 11, 2023
8946e62
Python layer
chrisrichardson Jan 11, 2023
5c176f6
Add method to set entity group offsets
jpdean Jan 11, 2023
dbf4f41
Fix test
chrisrichardson Jan 11, 2023
9468be1
Fix docs
chrisrichardson Jan 11, 2023
771adb0
Add method to get entity group offsets
jpdean Jan 11, 2023
b8c1ef2
Set offsets
jpdean Jan 11, 2023
1b46cca
Fix some tests
chrisrichardson Jan 11, 2023
81614c9
Add docs
jpdean Jan 11, 2023
faa63ed
Merge branch 'mixed-topology-hackathon-23' of github.com:FEniCS/dolfi…
jpdean Jan 11, 2023
ef274f9
merge
chrisrichardson Jan 11, 2023
34b278d
Fixups
chrisrichardson Jan 11, 2023
1e2bb3a
Fix test
chrisrichardson Jan 11, 2023
0ef8d30
Pass list of ElementDofLayouts to build_basic_dofmap
chrisrichardson Jan 12, 2023
0564c17
Add some mixed topology checks and limitations
chrisrichardson Jan 12, 2023
8ad0232
Add more multiple ElementDofLayouts for building dofmap
chrisrichardson Jan 12, 2023
e8f90da
Int type
chrisrichardson Jan 12, 2023
bbe7c10
Create dof array with mixture of elements
chrisrichardson Jan 13, 2023
18e78d8
Rename cell_type as cell_types
chrisrichardson Jan 13, 2023
e6429d7
resize array
chrisrichardson Jan 13, 2023
052caa2
int type
chrisrichardson Jan 13, 2023
75d5f1c
typo fix
chrisrichardson Jan 13, 2023
80261bd
More adjustments for multiple ElementDofLayouts
chrisrichardson Jan 13, 2023
97019d6
Minor fix
chrisrichardson Jan 13, 2023
24ecffa
Fix size_t again
chrisrichardson Jan 13, 2023
078f2fa
Fixes for ADIOS2
chrisrichardson Jan 13, 2023
192c771
Wrapper fixes
chrisrichardson Jan 13, 2023
3af10ee
Fix allocation
chrisrichardson Jan 13, 2023
74a76bb
Fix demos
chrisrichardson Jan 13, 2023
7dd91f8
Another place for cell_types()
chrisrichardson Jan 13, 2023
00413ba
Fix for submesh
chrisrichardson Jan 13, 2023
c6ae0ca
More renaming type->types
chrisrichardson Jan 13, 2023
5091dc7
Fix for zero size mesh
chrisrichardson Jan 14, 2023
0a77472
Merge branch 'main' into mixed-topology-hackathon-23
chrisrichardson Jan 14, 2023
98b4f31
Create CoordinateElements
chrisrichardson Jan 16, 2023
262e8f8
merge fix
chrisrichardson Jan 30, 2023
48519d3
typo
chrisrichardson Jan 30, 2023
99aa197
merge
chrisrichardson Feb 14, 2023
f75e025
Fixes for submesh
chrisrichardson Feb 14, 2023
1a56366
Set groups for submesh
chrisrichardson Feb 14, 2023
32b6fc6
Fix AdjacencyList creation after reordering geometry nodes
chrisrichardson Feb 15, 2023
d3e1e9c
Put in an actual Mesh
chrisrichardson Feb 20, 2023
5317b5a
Update basix interface to create_element
chrisrichardson Feb 28, 2023
05867f6
typo
chrisrichardson Mar 1, 2023
a684a1b
fix up for demo
chrisrichardson Mar 1, 2023
90cd1aa
ordering
chrisrichardson Mar 1, 2023
6539efd
merge
chrisrichardson Mar 1, 2023
2552910
Fix cmap->cmaps
chrisrichardson Mar 1, 2023
92d241f
cmaps
chrisrichardson Mar 1, 2023
94e7da4
Merge branch 'chris/basix-interface-change' into mixed-topology-hacka…
chrisrichardson Mar 1, 2023
fb09ef0
More fixes
chrisrichardson Mar 1, 2023
86ecac0
Merge branch 'main' into mixed-topology-hackathon-23
chrisrichardson Mar 20, 2023
b970947
Add a little more documentation
chrisrichardson Mar 20, 2023
687fb8b
merge
chrisrichardson Mar 21, 2023
02cbe61
fixes
chrisrichardson Mar 21, 2023
3b88b41
Suggested changes
chrisrichardson Mar 28, 2023
e7c916e
Difficult merge
chrisrichardson Mar 31, 2023
60c3b7b
Fixes
chrisrichardson Mar 31, 2023
255518a
Fix for functionspace
chrisrichardson Mar 31, 2023
18a91e4
another
chrisrichardson Mar 31, 2023
d926874
Undo unintended changes to demo
chrisrichardson Mar 31, 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
2 changes: 1 addition & 1 deletion cpp/demo/hyperelasticity/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ int main(int argc, char* argv[])
// Construct appropriate Basix element for stress
constexpr auto family = basix::element::family::P;
const auto cell_type
= mesh::cell_type_to_basix_type(mesh->topology().cell_type());
= mesh::cell_type_to_basix_type(mesh->topology().cell_types()[0]);
constexpr int k = 0;
constexpr bool discontinuous = true;

Expand Down
4 changes: 2 additions & 2 deletions cpp/demo/interpolation_different_meshes/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@ int main(int argc, char* argv[])
mesh::CellType::hexahedron));

basix::FiniteElement element_tet = basix::element::create_lagrange(
mesh::cell_type_to_basix_type(mesh_tet->topology().cell_type()), 1,
mesh::cell_type_to_basix_type(mesh_tet->topology().cell_types()[0]), 1,
basix::element::lagrange_variant::equispaced, false);
auto V_tet = std::make_shared<fem::FunctionSpace<double>>(
fem::create_functionspace(mesh_tet, element_tet, 3));

basix::FiniteElement element_hex = basix::element::create_lagrange(
mesh::cell_type_to_basix_type(mesh_hex->topology().cell_type()), 2,
mesh::cell_type_to_basix_type(mesh_hex->topology().cell_types()[0]), 2,
basix::element::lagrange_variant::equispaced, false);
auto V_hex = std::make_shared<fem::FunctionSpace<double>>(
fem::create_functionspace(mesh_hex, element_hex, 3));
Expand Down
24 changes: 24 additions & 0 deletions cpp/demo/mixed_topology/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
cmake_minimum_required(VERSION 3.16)
project(mixed_topology_testing)

# Find DOLFINx config file
find_package(DOLFINX REQUIRED)

# Set C++20 standard
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

include(CheckSymbolExists)
set(CMAKE_REQUIRED_INCLUDES ${PETSC_INCLUDE_DIRS})
check_symbol_exists(PETSC_USE_COMPLEX petscsystypes.h PETSC_SCALAR_COMPLEX)

# Add target to compile UFL files
if(PETSC_SCALAR_COMPLEX EQUAL 1)
set(SCALAR_TYPE "--scalar_type=double _Complex")
endif()

set(CMAKE_INCLUDE_CURRENT_DIR ON)

add_executable(${PROJECT_NAME} main.cpp)
target_link_libraries(${PROJECT_NAME} dolfinx)
149 changes: 149 additions & 0 deletions cpp/demo/mixed_topology/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#include <dolfinx/common/IndexMap.h>
#include <dolfinx/common/MPI.h>
#include <dolfinx/graph/AdjacencyList.h>
#include <dolfinx/mesh/Geometry.h>
#include <dolfinx/mesh/Mesh.h>
#include <dolfinx/mesh/Topology.h>
#include <dolfinx/mesh/cell_types.h>
#include <iostream>
#include <vector>

// Note: this demo is not currently intended to provide a fully functional
// example of using a mixed-topology mesh, but shows only the
// basic constrution. Experimental.

int main(int argc, char* argv[])
{
dolfinx::init_logging(argc, argv);
MPI_Init(&argc, &argv);

const int nx_s = 2;
const int nx_t = 2;
const int ny = 4;

const int num_s = nx_s * ny;
const int num_t = 2 * nx_t * ny;

std::vector<double> x;
for (int i = 0; i < nx_s + nx_t + 1; ++i)
{
for (int j = 0; j < ny + 1; ++j)
{
x.push_back(i);
x.push_back(j);
x.push_back(0);
}
}

std::vector<std::int64_t> cells;
std::vector<std::int32_t> offsets{0};
for (int i = 0; i < nx_s + nx_t; ++i)
{
for (int j = 0; j < ny; ++j)
{
const int v_0 = j + i * (ny + 1);
const int v_1 = v_0 + 1;
const int v_2 = v_0 + ny + 1;
const int v_3 = v_0 + ny + 2;

if (i < nx_s)
{
cells.push_back(v_0);
cells.push_back(v_1);
cells.push_back(v_3);
cells.push_back(v_2);

offsets.push_back(cells.size());
}
else
{
cells.push_back(v_0);
cells.push_back(v_1);
cells.push_back(v_2);

offsets.push_back(cells.size());

cells.push_back(v_1);
cells.push_back(v_2);
cells.push_back(v_3);

offsets.push_back(cells.size());
}
}
}

dolfinx::graph::AdjacencyList<std::int64_t> cells_list(cells, offsets);

std::vector<std::int64_t> original_global_index(num_s + num_t);
std::iota(original_global_index.begin(), original_global_index.end(), 0);

std::vector<int> ghost_owners;

std::vector<std::int32_t> cell_group_offsets{0, num_s, num_s + num_t,
num_s + num_t, num_s + num_t};

std::vector<std::int64_t> boundary_vertices;
for (int j = 0; j < ny + 1; ++j)
{
boundary_vertices.push_back(j);
boundary_vertices.push_back(j + (nx_s + nx_t + 1) * ny);
}
for (int i = 0; i < nx_s + nx_t + 1; ++i)
{
boundary_vertices.push_back((ny + 1) * i);
boundary_vertices.push_back(ny + (ny + 1) * i);
}

std::sort(boundary_vertices.begin(), boundary_vertices.end());
boundary_vertices.erase(
std::unique(boundary_vertices.begin(), boundary_vertices.end()),
boundary_vertices.end());

std::vector<dolfinx::mesh::CellType> cell_types{
dolfinx::mesh::CellType::quadrilateral,
dolfinx::mesh::CellType::triangle};
std::vector<dolfinx::fem::CoordinateElement> elements;
for (auto ct : cell_types)
elements.push_back(dolfinx::fem::CoordinateElement(ct, 1));

{
auto topo = dolfinx::mesh::create_topology(
MPI_COMM_WORLD, cells_list, original_global_index, ghost_owners,
cell_types, cell_group_offsets, boundary_vertices);

auto topo_cells = topo.connectivity(2, 0);

for (int i = 0; i < topo_cells->num_nodes(); ++i)
{
std::cout << i << " [";
for (auto q : topo_cells->links(i))
std::cout << q << " ";
std::cout << "]\n";
}

topo.create_connectivity(1, 0);

auto topo_facets = topo.connectivity(1, 0);
for (int i = 0; i < topo_facets->num_nodes(); ++i)
{
std::cout << i << " [";
for (auto q : topo_facets->links(i))
std::cout << q << " ";
std::cout << "]\n";
}

auto geom = dolfinx::mesh::create_geometry(MPI_COMM_WORLD, topo, elements,
cells_list, x, 2);

dolfinx::mesh::Mesh mesh(MPI_COMM_WORLD, topo, geom);
std::cout << "num cells = " << mesh.topology().index_map(2)->size_local()
<< "\n";
for (auto q : mesh.topology().entity_group_offsets(2))
std::cout << q << " ";
std::cout << "\n";
}

MPI_Finalize();

return 0;
}
17 changes: 13 additions & 4 deletions cpp/dolfinx/fem/DirichletBC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,15 @@ fem::locate_dofs_topological(mesh::Topology& topology, const DofMap& dofmap,
int dim, std::span<const std::int32_t> entities,
bool remote)
{
auto cell_types = topology.cell_types();
if (cell_types.size() > 1)
{
throw std::runtime_error("Multiple cell types in DirichletBC");
}

// Prepare an element - local dof layout for dofs on entities of the
// entity_dim
const int num_cell_entities
= mesh::cell_num_entities(topology.cell_type(), dim);
const int num_cell_entities = mesh::cell_num_entities(cell_types.back(), dim);
std::vector<std::vector<int>> entity_dofs;
for (int i = 0; i < num_cell_entities; ++i)
{
Expand Down Expand Up @@ -298,9 +303,13 @@ std::array<std::vector<std::int32_t>, 2> fem::locate_dofs_topological(
// Check that dof layouts are the same
assert(dofmap0.element_dof_layout() == dofmap1.element_dof_layout());

auto cell_types = topology.cell_types();
if (cell_types.size() > 1)
{
throw std::runtime_error("Multiple cell types in DirichletBC");
}
// Build vector of local dofs for each cell entity
const int num_cell_entities
= mesh::cell_num_entities(topology.cell_type(), dim);
const int num_cell_entities = mesh::cell_num_entities(cell_types.back(), dim);
std::vector<std::vector<int>> entity_dofs;
for (int i = 0; i < num_cell_entities; ++i)
{
Expand Down
4 changes: 2 additions & 2 deletions cpp/dolfinx/fem/DofMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ std::pair<DofMap, std::vector<std::int32_t>> DofMap::collapse(
// Create new element dof layout and reset parent
ElementDofLayout collapsed_dof_layout = layout.copy();

auto [_index_map, bs, dofmap]
= build_dofmap_data(comm, topology, collapsed_dof_layout, reorder_fn);
auto [_index_map, bs, dofmap] = build_dofmap_data(
comm, topology, {collapsed_dof_layout}, reorder_fn);
auto index_map
= std::make_shared<common::IndexMap>(std::move(_index_map));
return DofMap(layout, index_map, bs, std::move(dofmap), bs);
Expand Down
7 changes: 6 additions & 1 deletion cpp/dolfinx/fem/Expression.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,12 @@ class Expression
// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap
= _mesh->geometry().dofmap();
const std::size_t num_dofs_g = _mesh->geometry().cmap().dim();

// Get geometry data
auto cmaps = _mesh->geometry().cmaps();
assert(cmaps.size() == 1);

const std::size_t num_dofs_g = cmaps.back().dim();
std::span<const U> x_g = _mesh->geometry().x();

// Create data structures used in evaluation
Expand Down
2 changes: 1 addition & 1 deletion cpp/dolfinx/fem/FiniteElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ class FiniteElement
/// @return True if the map is the identity
bool map_ident() const noexcept;

/// @brief Points on the reference cell at which an expression need to
/// @brief Points on the reference cell at which an expression needs to
/// be evaluated in order to interpolate the expression in the finite
/// element space.
///
Expand Down
13 changes: 9 additions & 4 deletions cpp/dolfinx/fem/Function.h
Original file line number Diff line number Diff line change
Expand Up @@ -393,15 +393,20 @@ class Function
const std::size_t tdim = mesh->topology().dim();
auto map = mesh->topology().index_map(tdim);

// Get coordinate map
if (mesh->geometry().cmaps().size() > 1)
{
throw std::runtime_error(
"Function with multiple geometry maps not implemented.");
}
const CoordinateElement& cmap = mesh->geometry().cmaps()[0];

// Get geometry data
const graph::AdjacencyList<std::int32_t>& x_dofmap
= mesh->geometry().dofmap();
const std::size_t num_dofs_g = mesh->geometry().cmap().dim();
const std::size_t num_dofs_g = cmap.dim();
std::span<const U> x_g = mesh->geometry().x();

// Get coordinate map
const CoordinateElement& cmap = mesh->geometry().cmap();

// Get element
std::shared_ptr<const FiniteElement> element = _function_space->element();
assert(element);
Expand Down
8 changes: 6 additions & 2 deletions cpp/dolfinx/fem/FunctionSpace.h
Original file line number Diff line number Diff line change
Expand Up @@ -216,12 +216,16 @@ class FunctionSpace
const auto [X, Xshape] = _element->interpolation_points();

// Get coordinate map
const CoordinateElement& cmap = _mesh->geometry().cmap();
if (_mesh->geometry().cmaps().size() > 1)
{
throw std::runtime_error("Mixed topology not supported");
}
const CoordinateElement& cmap = _mesh->geometry().cmaps()[0];

// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap
= _mesh->geometry().dofmap();
const std::size_t num_dofs_g = _mesh->geometry().cmap().dim();
const std::size_t num_dofs_g = cmap.dim();
std::span<const T> x_g = _mesh->geometry().x();

// Array to hold coordinates to return
Expand Down
12 changes: 8 additions & 4 deletions cpp/dolfinx/fem/assemble_matrix_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ void assemble_cells(

// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap = geometry.dofmap();
const std::size_t num_dofs_g = geometry.cmap().dim();
const std::size_t num_dofs_g = geometry.cmaps()[0].dim();
auto x = geometry.x();

// Iterate over active cells
Expand Down Expand Up @@ -144,7 +144,7 @@ void assemble_exterior_facets(

// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap = geometry.dofmap();
const std::size_t num_dofs_g = geometry.cmap().dim();
const std::size_t num_dofs_g = geometry.cmaps()[0].dim();
auto x = geometry.x();

// Data structures used in assembly
Expand Down Expand Up @@ -240,7 +240,7 @@ void assemble_interior_facets(

// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap = geometry.dofmap();
const std::size_t num_dofs_g = geometry.cmap().dim();
const std::size_t num_dofs_g = geometry.cmaps()[0].dim();
auto x = geometry.x();

// Data structures used in assembly
Expand Down Expand Up @@ -445,7 +445,11 @@ void assemble_matrix(
else
get_perm = [](std::size_t) { return 0; };

int num_cell_facets = mesh::cell_num_entities(mesh->topology().cell_type(),
auto cell_types = mesh->topology().cell_types();
if (cell_types.size() > 1)
throw std::runtime_error("Multiple cell types in the assembler.");

int num_cell_facets = mesh::cell_num_entities(cell_types.back(),
mesh->topology().dim() - 1);
const std::vector<int> c_offsets = a.coefficient_offsets();
for (int i : a.integral_ids(IntegralType::interior_facet))
Expand Down
13 changes: 9 additions & 4 deletions cpp/dolfinx/fem/assemble_scalar_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ T assemble_cells(const mesh::Geometry<scalar_value_type_t<T>>& geometry,

// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap = geometry.dofmap();
const std::size_t num_dofs_g = geometry.cmap().dim();
const std::size_t num_dofs_g = geometry.cmaps()[0].dim();
auto x = geometry.x();

// Create data structures used in assembly
Expand Down Expand Up @@ -74,7 +74,7 @@ T assemble_exterior_facets(

// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap = geometry.dofmap();
const std::size_t num_dofs_g = geometry.cmap().dim();
const std::size_t num_dofs_g = geometry.cmaps()[0].dim();
auto x = geometry.x();

// Create data structures used in assembly
Expand Down Expand Up @@ -117,7 +117,7 @@ T assemble_interior_facets(

// Prepare cell geometry
const graph::AdjacencyList<std::int32_t>& x_dofmap = geometry.dofmap();
const std::size_t num_dofs_g = geometry.cmap().dim();
const std::size_t num_dofs_g = geometry.cmaps()[0].dim();
auto x = geometry.x();

// Create data structures used in assembly
Expand Down Expand Up @@ -199,7 +199,12 @@ T assemble_scalar(
const std::vector<std::uint8_t>& perms
= mesh->topology().get_facet_permutations();

int num_cell_facets = mesh::cell_num_entities(mesh->topology().cell_type(),
auto cell_types = mesh->topology().cell_types();
if (cell_types.size() > 1)
{
throw std::runtime_error("MUltiple cell types in the assembler");
}
int num_cell_facets = mesh::cell_num_entities(cell_types.back(),
mesh->topology().dim() - 1);
const std::vector<int> c_offsets = M.coefficient_offsets();
for (int i : M.integral_ids(IntegralType::interior_facet))
Expand Down
Loading