18 #ifndef GENERIC_ASSEMBLY_HH_ 19 #define GENERIC_ASSEMBLY_HH_ 41 std::array<std::shared_ptr<BulkIntegral>, 3>
bulk_;
42 std::array<std::shared_ptr<EdgeIntegral>, 3>
edge_;
43 std::array<std::shared_ptr<CouplingIntegral>, 2>
coupling_;
44 std::array<std::shared_ptr<BoundaryIntegral>, 3>
boundary_;
57 template <
template<
IntDim...>
class DimAssembly>
72 : cell(dhcell), subset_index(subset_idx) {}
76 : cell(other.cell), subset_index(other.subset_index) {}
94 : edge_side_range(other.edge_side_range), subset_index(other.subset_index) {}
98 : edge_side_range(range), subset_index(subset_idx) {}
115 : cell(dhcell), bulk_subset_index(bulk_idx), side(dhside), side_subset_index(side_idx) {}
119 : cell(other.cell), bulk_subset_index(other.bulk_subset_index), side(other.side), side_subset_index(other.side_subset_index) {}
138 : bdr_subset_index(bdr_idx), side(dhside), side_subset_index(side_idx) {}
142 : bdr_subset_index(other.bdr_subset_index), side(other.side), side_subset_index(other.side_subset_index) {}
153 GenericAssembly(
typename DimAssembly<1>::EqFields *eq_fields,
typename DimAssembly<1>::EqData *eq_data)
154 : multidim_assembly_(eq_fields, eq_data),
155 bulk_integral_data_(20, 10),
156 edge_integral_data_(12, 6),
157 coupling_integral_data_(12, 6),
158 boundary_integral_data_(8, 4)
160 eval_points_ = std::make_shared<EvalPoints>();
162 multidim_assembly_[1_d]->create_integrals(eval_points_, integrals_);
163 multidim_assembly_[2_d]->create_integrals(eval_points_, integrals_);
164 multidim_assembly_[3_d]->create_integrals(eval_points_, integrals_);
165 element_cache_map_.init(eval_points_);
166 multidim_assembly_[1_d]->initialize(&element_cache_map_);
167 multidim_assembly_[2_d]->initialize(&element_cache_map_);
168 multidim_assembly_[3_d]->initialize(&element_cache_map_);
169 active_integrals_ = multidim_assembly_[1_d]->n_active_integrals();
174 return multidim_assembly_;
188 void assemble(std::shared_ptr<DOFHandlerMultiDim> dh) {
190 this->reallocate_cache();
191 multidim_assembly_[1_d]->begin();
193 bool add_into_patch =
false;
194 for(
auto cell_it = dh->local_range().begin(); cell_it != dh->local_range().end(); )
197 if (!add_into_patch) {
198 element_cache_map_.start_elements_update();
199 add_into_patch =
true;
203 this->add_integrals_of_computing_step(*cell_it);
207 bulk_integral_data_.revert_temporary();
208 edge_integral_data_.revert_temporary();
209 coupling_integral_data_.revert_temporary();
210 boundary_integral_data_.revert_temporary();
211 element_cache_map_.eval_point_data_.revert_temporary();
212 this->assemble_integrals();
213 add_into_patch =
false;
215 bulk_integral_data_.make_permanent();
216 edge_integral_data_.make_permanent();
217 coupling_integral_data_.make_permanent();
218 boundary_integral_data_.make_permanent();
219 element_cache_map_.eval_point_data_.make_permanent();
221 this->assemble_integrals();
222 add_into_patch =
false;
227 if (add_into_patch) {
228 this->assemble_integrals();
231 multidim_assembly_[1_d]->end();
237 return element_cache_map_;
242 template<
unsigned int dim>
244 for (
unsigned int i=0; i<bulk_integral_data_.permanent_size(); ++i) {
245 if (bulk_integral_data_[i].cell.dim() != dim)
continue;
246 multidim_assembly_[
Dim<dim>{}]->cell_integral(bulk_integral_data_[i].cell, element_cache_map_.position_in_cache(bulk_integral_data_[i].cell.elm().mesh_idx()));
257 template<
unsigned int dim>
259 for (
unsigned int i=0; i<boundary_integral_data_.permanent_size(); ++i) {
260 if (boundary_integral_data_[i].side.dim() != dim)
continue;
261 multidim_assembly_[
Dim<dim>{}]->boundary_side_integral(boundary_integral_data_[i].side);
266 template<
unsigned int dim>
268 for (
unsigned int i=0; i<edge_integral_data_.permanent_size(); ++i) {
269 auto range = edge_integral_data_[i].edge_side_range;
270 if (range.begin()->dim() != dim)
continue;
271 multidim_assembly_[
Dim<dim>{}]->edge_integral(edge_integral_data_[i].edge_side_range);
276 template<
unsigned int dim>
278 for (
unsigned int i=0; i<coupling_integral_data_.permanent_size(); ++i) {
279 if (coupling_integral_data_[i].side.dim() != dim)
continue;
280 multidim_assembly_[
Dim<dim>{}]->dimjoin_intergral(coupling_integral_data_[i].cell, coupling_integral_data_[i].side);
287 element_cache_map_.create_patch();
290 multidim_assembly_[1_d]->eq_fields_->cache_update(element_cache_map_);
292 element_cache_map_.finish_elements_update();
296 this->assemble_cell_integrals<1>();
297 this->assemble_cell_integrals<2>();
298 this->assemble_cell_integrals<3>();
304 this->assemble_boundary_side_integrals<1>();
305 this->assemble_boundary_side_integrals<2>();
306 this->assemble_boundary_side_integrals<3>();
312 this->assemble_edge_integrals<1>();
313 this->assemble_edge_integrals<2>();
314 this->assemble_edge_integrals<3>();
320 this->assemble_neighbour_integrals<2>();
321 this->assemble_neighbour_integrals<3>();
325 bulk_integral_data_.reset();
326 edge_integral_data_.reset();
327 coupling_integral_data_.reset();
328 boundary_integral_data_.reset();
329 element_cache_map_.clear_element_eval_points_map();
340 this->add_volume_integral(cell);
346 if ( (cell_side.side().edge().n_sides() == 1) && (cell_side.side().is_boundary()) ) {
347 this->add_boundary_integral(cell_side);
351 if ( (cell_side.n_edge_sides() >= 2) && (cell_side.edge_sides().begin()->element().idx() == cell.
elm_idx())) {
352 this->add_edge_integral(cell_side);
359 if (cell.
dim() != neighb_side.dim()-1)
continue;
360 this->add_coupling_integral(cell, neighb_side, add_low);
368 uint subset_idx = integrals_.bulk_[cell.
dim()-1]->get_subset_idx();
369 bulk_integral_data_.emplace_back(cell, subset_idx);
374 for (
uint i=
uint( eval_points_->subset_begin(cell.
dim(), subset_idx) );
375 i<
uint( eval_points_->subset_end(cell.
dim(), subset_idx) ); ++i) {
376 element_cache_map_.eval_point_data_.emplace_back(reg_idx, cell.
elm_idx(), i, cell.
local_idx());
383 edge_integral_data_.emplace_back(range, integrals_.edge_[range.begin()->dim()-1]->get_subset_idx());
386 unsigned int reg_idx = edge_side.element().region_idx().idx();
387 for (
auto p : integrals_.edge_[range.begin()->dim()-1]->points(edge_side, &element_cache_map_) ) {
388 element_cache_map_.eval_point_data_.emplace_back(reg_idx, edge_side.elem_idx(), p.eval_point_idx(), edge_side.cell().local_idx());
395 coupling_integral_data_.emplace_back(cell, integrals_.coupling_[cell.
dim()-1]->get_subset_low_idx(), ngh_side,
396 integrals_.coupling_[cell.
dim()-1]->get_subset_high_idx());
400 for (
auto p : integrals_.coupling_[cell.
dim()-1]->points(ngh_side, &element_cache_map_) ) {
401 element_cache_map_.eval_point_data_.emplace_back(reg_idx_high, ngh_side.
elem_idx(), p.eval_point_idx(), ngh_side.
cell().
local_idx());
404 auto p_low = p.lower_dim(cell);
405 element_cache_map_.eval_point_data_.emplace_back(reg_idx_low, cell.
elm_idx(), p_low.eval_point_idx(), cell.
local_idx());
412 boundary_integral_data_.emplace_back(integrals_.boundary_[bdr_side.
dim()-1]->get_subset_low_idx(), bdr_side,
413 integrals_.boundary_[bdr_side.
dim()-1]->get_subset_high_idx());
416 for (
auto p : integrals_.boundary_[bdr_side.
dim()-1]->points(bdr_side, &element_cache_map_) ) {
417 element_cache_map_.eval_point_data_.emplace_back(reg_idx, bdr_side.
elem_idx(), p.eval_point_idx(), bdr_side.
cell().
local_idx());
422 element_cache_map_.eval_point_data_.emplace_back(bdr_reg, bdr_side.
cond().
bc_ele_idx(), p_bdr.eval_point_idx(), -1);
428 multidim_assembly_[1_d]->eq_fields_->cache_reallocate(this->element_cache_map_, multidim_assembly_[1_d]->used_fields_);
429 DebugOut() <<
"Order of evaluated fields (" << DimAssembly<1>::name() <<
"):" << multidim_assembly_[1_d]->eq_fields_->print_dependency();
void add_coupling_integral(const DHCellAccessor &cell, const DHCellSide &ngh_side, bool add_low)
Add data of coupling integral to appropriate data structure.
Range< DHCellSide > side_range() const
Returns range of cell sides.
unsigned int elm_idx() const
Return serial idx to element of loc_ele_idx_.
DHCellSide side
Specified cell side (higher dim element)
void add_edge_integral(const DHCellSide &cell_side)
Add data of edge integral to appropriate data structure.
std::shared_ptr< EvalPoints > eval_points() const
Geter to EvalPoints object.
void assemble_edge_integrals()
Assembles the edge integrals for the given dimension.
RevertableList< EdgeIntegralData > edge_integral_data_
Holds data for computing edge integrals.
BulkIntegralData()
Default constructor.
unsigned int dim() const
Return dimension of element appropriate to the side.
unsigned int side_subset_index
Index (order) of higher dim subset in EvalPoints object.
static unsigned int get()
Return number of stored elements.
unsigned int subset_index
Index (order) of subset in EvalPoints object.
unsigned int elem_idx() const
int active_integrals_
Holds mask of active integrals.
void reallocate_cache()
Calls cache_reallocate method on.
BoundaryIntegralData(unsigned int bdr_idx, DHCellSide dhside, unsigned int side_idx)
Constructor with data mebers initialization.
std::array< std::shared_ptr< CouplingIntegral >, 2 > coupling_
Coupling integrals between elements of dimensions 1-2, 2-3.
void assemble(std::shared_ptr< DOFHandlerMultiDim > dh)
General assemble methods.
unsigned int dim() const
Return dimension of element appropriate to cell.
unsigned int local_idx() const
Return local index to element (index of DOF handler).
BulkIntegralData(DHCellAccessor dhcell, unsigned int subset_idx)
Constructor with data mebers initialization.
MixedPtr< DimAssembly, 1 > multidim_assembly() const
Getter to set of assembly objects.
Directing class of FieldValueCache.
Iter< Object > make_iter(Object obj)
void assemble_cell_integrals()
Assembles the cell integrals for the given dimension.
Cell accessor allow iterate over DOF handler cells.
EdgeIntegralData(const EdgeIntegralData &other)
Copy constructor.
unsigned int bulk_subset_index
Index (order) of lower dim subset in EvalPoints object.
BoundaryIntegralData()
Default constructor.
RevertableList< CouplingIntegralData > coupling_integral_data_
Holds data for computing couplings integrals.
bool is_own() const
Return true if accessor represents own element (false for ghost element)
EdgeIntegralData()
Default constructor.
BulkIntegralData(const BulkIntegralData &other)
Copy constructor.
const ElementCacheMap & cache_map() const
Return ElementCacheMap.
void assemble_integrals()
Call assemblations when patch is filled.
std::array< std::shared_ptr< EdgeIntegral >, 3 > edge_
Edge integrals between elements of dimensions 1, 2, 3.
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
unsigned int bdr_subset_index
Index (order) of subset on boundary element in EvalPoints object.
RangeConvert< DHEdgeSide, DHCellSide > edge_sides() const
Returns range of all sides looped over common Edge.
CouplingIntegralData(DHCellAccessor dhcell, unsigned int bulk_idx, DHCellSide dhside, unsigned int side_idx)
Constructor with data mebers initialization.
void add_boundary_integral(const DHCellSide &bdr_side)
Add data of boundary integral to appropriate data structure.
unsigned int side_subset_index
Index (order) of subset on side of bulk element in EvalPoints object.
RangeConvert< DHEdgeSide, DHCellSide > edge_side_range
Specified cell side (element)
ElementAccessor< 3 > element() const
RangeConvert< DHNeighbSide, DHCellSide > neighb_sides() const
Returns range of neighbour cell of lower dimension corresponding to cell of higher dimension...
DHCellAccessor cell
Specified cell (element)
#define START_TIMER(tag)
Starts a timer with specified tag.
ElementCacheMap element_cache_map_
ElementCacheMap according to EvalPoints.
unsigned int IntDim
A dimension index type.
BoundaryIntegralData(const BoundaryIntegralData &other)
Copy constructor.
RevertableList< BoundaryIntegralData > boundary_integral_data_
Holds data for computing boundary integrals.
std::array< std::shared_ptr< BulkIntegral >, 3 > bulk_
Bulk integrals of elements of dimensions 1, 2, 3.
DHCellSide side
Specified cell side (bulk element)
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
CouplingIntegralData()
Default constructor.
MixedPtr< DimAssembly, 1 > multidim_assembly_
Assembly object.
Struct is a container that encapsulates variable size arrays.
RevertableList< BulkIntegralData > bulk_integral_data_
Holds data for computing bulk integrals.
Generic class of assemblation.
std::array< std::shared_ptr< BoundaryIntegral >, 3 > boundary_
Boundary integrals betwwen elements of dimensions 1, 2, 3 and boundaries.
RegionIdx region_idx() const
Definitions of particular quadrature rules on simplices.
GenericAssembly(typename DimAssembly< 1 >::EqFields *eq_fields, typename DimAssembly< 1 >::EqData *eq_data)
Constructor.
void add_integrals_of_computing_step(DHCellAccessor cell)
#define END_TIMER(tag)
Ends a timer with specified tag.
std::shared_ptr< EvalPoints > eval_points_
EvalPoints object shared by all integrals.
void add_volume_integral(const DHCellAccessor &cell)
Add data of volume integral to appropriate data structure.
void assemble_boundary_side_integrals()
Assembles the boundary side integrals for the given dimension.
void assemble_neighbour_integrals()
Assembles the neighbours integrals for the given dimension.
#define DebugOut()
Macro defining 'debug' record of log.
unsigned int subset_index
Index (order) of subset in EvalPoints object.
EdgeIntegralData(RangeConvert< DHEdgeSide, DHCellSide > range, unsigned int subset_idx)
Constructor with data mebers initialization.
CouplingIntegralData(const CouplingIntegralData &other)
Copy constructor.
ActiveIntegrals
Allow set mask of active integrals.
Side accessor allows to iterate over sides of DOF handler cell.
ElementAccessor< 3 > element_accessor()
Set of all used integral necessary in assemblation.
unsigned int idx() const
Returns a global index of the region.
Class allows to iterate over sides of edge.
AssemblyIntegrals integrals_
Holds integral objects.