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