9 #include <dolfinx/fem/FunctionSpace.h>
10 #include <dolfinx/mesh/Mesh.h>
11 #include <dolfinx/mesh/MeshTags.h>
76 const std::vector<std::shared_ptr<const fem::FunctionSpace>>&
81 std::vector<std::pair<
82 int, std::function<
void(T*,
const T*,
const T*,
const double*,
83 const int*,
const std::uint8_t*)>>>,
88 const std::shared_ptr<const mesh::Mesh>&
mesh =
nullptr)
97 if (_mesh != V->mesh())
98 throw std::runtime_error(
"Incompatible mesh");
100 throw std::runtime_error(
"No mesh could be associated with the Form.");
103 for (
auto& integral_type : integrals)
107 auto it = _integrals.emplace(
108 type, std::map<
int, std::pair<kern, std::vector<std::int32_t>>>());
111 for (
auto& integral : integral_type.second.first)
112 it.first->second.insert({integral.first, {integral.second, {}}});
116 if (integral_type.second.second)
118 assert(_mesh == integral_type.second.second->mesh());
119 set_domains(type, *integral_type.second.second);
125 set_default_domains(*_mesh);
140 int rank()
const {
return _function_spaces.size(); }
144 std::shared_ptr<const mesh::Mesh>
mesh()
const {
return _mesh; }
148 const std::vector<std::shared_ptr<const fem::FunctionSpace>>&
151 return _function_spaces;
159 const std::function<void(T*,
const T*,
const T*,
const double*,
const int*,
160 const std::uint8_t*)>&
163 auto it0 = _integrals.find(type);
164 if (it0 == _integrals.end())
165 throw std::runtime_error(
"No kernels for requested type.");
166 auto it1 = it0->second.find(i);
167 if (it1 == it0->second.end())
168 throw std::runtime_error(
"No kernel for requested domain index.");
170 return it1->second.first;
177 std::set<IntegralType> set;
178 for (
auto& type : _integrals)
179 set.insert(type.first);
188 if (
auto it = _integrals.find(type); it == _integrals.end())
191 return it->second.size();
202 std::vector<int> ids;
203 if (
auto it = _integrals.find(type); it != _integrals.end())
205 for (
auto&
kernel : it->second)
206 ids.push_back(
kernel.first);
219 auto it0 = _integrals.find(type);
220 if (it0 == _integrals.end())
221 throw std::runtime_error(
"No mesh entities for requested type.");
222 auto it1 = it0->second.find(i);
223 if (it1 == it0->second.end())
224 throw std::runtime_error(
"No mesh entities for requested domain index.");
225 return it1->second.second;
229 const std::vector<std::shared_ptr<const fem::Function<T>>>
232 return _coefficients;
245 std::vector<int> n{0};
246 for (
const auto& c : _coefficients)
249 throw std::runtime_error(
"Not all form coefficients have been set.");
250 n.push_back(n.back() + c->function_space()->element()->space_dimension());
256 const std::vector<std::shared_ptr<const fem::Constant<T>>>&
constants()
const
272 auto it0 = _integrals.find(type);
273 assert(it0 != _integrals.end());
275 std::shared_ptr<const mesh::Mesh>
mesh = marker.
mesh();
277 const int tdim = topology.
dim();
279 if (type == IntegralType::exterior_facet
280 or type == IntegralType::interior_facet)
283 mesh->topology_mutable().create_connectivity(dim, tdim);
285 else if (type == IntegralType::vertex)
288 if (dim != marker.
dim())
290 throw std::runtime_error(
"Invalid MeshTags dimension:"
291 + std::to_string(marker.
dim()));
295 std::map<int, std::pair<kern, std::vector<std::int32_t>>>& integrals
299 const std::vector<int>& values = marker.
values();
300 const std::vector<std::int32_t>& tagged_entities = marker.
indices();
302 const auto entity_end
303 = std::lower_bound(tagged_entities.begin(), tagged_entities.end(),
310 if (type == IntegralType::exterior_facet)
315 std::set<std::int32_t> fwd_shared;
316 if (topology.
index_map(tdim)->num_ghosts() == 0)
318 const std::vector<std::int32_t>& fwd_indices
319 = topology.
index_map(tdim - 1)->scatter_fwd_indices().array();
320 fwd_shared.insert(fwd_indices.begin(), fwd_indices.end());
323 for (
auto f = tagged_entities.begin(); f != entity_end; ++f)
327 if (f_to_c->num_links(*f) == 1
328 and fwd_shared.find(*f) == fwd_shared.end())
330 const std::size_t i = std::distance(tagged_entities.cbegin(), f);
331 if (
auto it = integrals.find(values[i]); it != integrals.end())
332 it->second.second.push_back(*f);
336 else if (type == IntegralType::interior_facet)
338 for (
auto f = tagged_entities.begin(); f != entity_end; ++f)
340 if (f_to_c->num_links(*f) == 2)
342 const std::size_t i = std::distance(tagged_entities.cbegin(), f);
343 if (
auto it = integrals.find(values[i]); it != integrals.end())
344 it->second.second.push_back(*f);
353 for (
auto e = tagged_entities.begin(); e != entity_end; ++e)
355 const std::size_t i = std::distance(tagged_entities.cbegin(), e);
356 if (
auto it = integrals.find(values[i]); it != integrals.end())
357 it->second.second.push_back(*e);
370 const int tdim = topology.
dim();
373 if (
auto kernels = _integrals.find(IntegralType::cell);
374 kernels != _integrals.end())
376 if (
auto it = kernels->second.find(-1); it != kernels->second.end())
378 std::vector<std::int32_t>& active_entities = it->second.second;
379 const int num_cells = topology.
index_map(tdim)->size_local();
380 active_entities.resize(num_cells);
381 std::iota(active_entities.begin(), active_entities.end(), 0);
387 if (
auto kernels = _integrals.find(IntegralType::exterior_facet);
388 kernels != _integrals.end())
390 if (
auto it = kernels->second.find(-1); it != kernels->second.end())
392 std::vector<std::int32_t>& active_entities = it->second.second;
393 active_entities.clear();
396 mesh.topology_mutable().create_connectivity(tdim - 1, tdim);
399 std::set<std::int32_t> fwd_shared_facets;
402 if (topology.
index_map(tdim)->num_ghosts() == 0)
404 const std::vector<std::int32_t>& fwd_indices
405 = topology.
index_map(tdim - 1)->scatter_fwd_indices().array();
406 fwd_shared_facets.insert(fwd_indices.begin(), fwd_indices.end());
409 const int num_facets = topology.
index_map(tdim - 1)->size_local();
410 for (
int f = 0; f < num_facets; ++f)
412 if (f_to_c->num_links(f) == 1
413 and fwd_shared_facets.find(f) == fwd_shared_facets.end())
415 active_entities.push_back(f);
423 if (
auto kernels = _integrals.find(IntegralType::interior_facet);
424 kernels != _integrals.end())
426 if (
auto it = kernels->second.find(-1); it != kernels->second.end())
428 std::vector<std::int32_t>& active_entities = it->second.second;
431 mesh.topology_mutable().create_connectivity(tdim - 1, tdim);
433 const int num_facets = topology.
index_map(tdim - 1)->size_local();
435 active_entities.clear();
436 active_entities.reserve(num_facets);
437 for (
int f = 0; f < num_facets; ++f)
439 if (f_to_c->num_links(f) == 2)
440 active_entities.push_back(f);
447 std::vector<std::shared_ptr<const fem::FunctionSpace>> _function_spaces;
450 std::vector<std::shared_ptr<const fem::Function<T>>> _coefficients;
453 std::vector<std::shared_ptr<const fem::Constant<T>>> _constants;
456 std::shared_ptr<const mesh::Mesh> _mesh;
458 using kern = std::function<void(T*,
const T*,
const T*,
const double*,
459 const int*,
const std::uint8_t*)>;
461 std::map<int, std::pair<kern, std::vector<std::int32_t>>>>
465 bool _needs_facet_permutations;
A constant value which can be attached to a Form. Constants may be scalar (rank 0),...
Definition: Constant.h:19
This class represents a function in a finite element function space , given by.
Definition: Function.h:47
A Mesh consists of a set of connected and numbered mesh topological entities, and geometry data.
Definition: Mesh.h:53
Topology stores the topology of a mesh, consisting of mesh entities and connectivity (incidence relat...
Definition: Topology.h:56
int dim() const noexcept
Return the topological dimension of the mesh.
Definition: Topology.cpp:163
std::shared_ptr< const graph::AdjacencyList< std::int32_t > > connectivity(int d0, int d1) const
Return connectivity from entities of dimension d0 to entities of dimension d1.
Definition: Topology.cpp:253
std::shared_ptr< const common::IndexMap > index_map(int dim) const
Get the IndexMap that described the parallel distribution of the mesh entities.
Definition: Topology.cpp:172
Finite element method functionality.
Definition: assemble_matrix_impl.h:23
IntegralType
Type of integral.
Definition: Form.h:27