18 #ifndef ASSEMBLY_DG_HH_
19 #define ASSEMBLY_DG_HH_
36 template <
unsigned int dim,
class TEqData>
43 static constexpr
const char *
name() {
return "DG_Mass_Assembly"; }
72 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
76 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
79 for (
unsigned int i=0; i<
ndofs_; i++)
81 for (
unsigned int j=0; j<
ndofs_; j++)
92 for (
unsigned int i=0; i<
ndofs_; i++)
141 template <
template<
IntDim...>
class DimAssembly>
150 double h_max = 0, h_min = numeric_limits<double>::infinity();
151 for (
unsigned int i=0; i<e->
n_nodes(); i++)
152 for (
unsigned int j=i+1; j<e->
n_nodes(); j++)
154 double dist = arma::norm(*e.
node(i) - *e.
node(j));
155 h_max = max(h_max, dist);
156 h_min = min(h_min, dist);
174 delta += dot(diff_coef(p)*nv, nv);
177 return n == 0 ? 0 : (delta/n);
192 const double &diff_delta,
209 template <
class Po
intType>
212 double side_flux = 0;
214 side_flux += arma::dot(advection_coef(p), normal(p))*JxW(p);
223 template <
unsigned int dim,
class TEqData>
230 static constexpr
const char *
name() {
return "DG_Stiffness_Assembly"; }
265 for (
auto a :
averages)
if (a !=
nullptr)
delete[] a;
266 for (
auto a :
waverages)
if (a !=
nullptr)
delete[] a;
267 for (
auto a :
jumps)
if (a !=
nullptr)
delete[] a;
279 for (
unsigned int sid=0; sid<
eq_data_->max_edg_sides; sid++)
285 for (
unsigned int s=0; s<
eq_data_->max_edg_sides; s++)
289 for (
unsigned int s=0; s<2; s++)
300 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
301 if (!cell.
is_own())
return;
306 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
308 for (
unsigned int i=0; i<
ndofs_; i++)
309 for (
unsigned int j=0; j<
ndofs_; j++)
314 for (
unsigned int i=0; i<
ndofs_; i++)
319 for (
unsigned int j=0; j<
ndofs_; j++)
333 ASSERT_EQ(cell_side.
dim(), dim).error(
"Dimension of element mismatch!");
343 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
348 double transport_flux = side_flux/side.
measure();
354 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
363 transport_flux += gamma_l;
370 double flux_times_JxW;
385 flux_times_JxW = transport_flux*
JxW_bdr_(p);
387 for (
unsigned int i=0; i<
ndofs_; i++)
389 for (
unsigned int j=0; j<
ndofs_; j++)
411 ASSERT_EQ(edge_side_range.
begin()->element().dim(), dim).error(
"Dimension of element mismatch!");
414 double gamma_l, omega[2], transport_flux, delta[2], delta_sum;
415 double aniso1, aniso2;
416 double local_alpha=0.0;
420 auto dh_edge_cell =
eq_data_->dh_->cell_accessor_from_element( edge_side.elem_idx() );
424 auto zero_edge_side = *edge_side_range.
begin();
429 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
432 double pflux = 0, nflux = 0;
438 pflux += fluxes[sid];
440 nflux += fluxes[sid];
451 for (
unsigned int i=0; i<
ndofs_; i++)
461 for(
DHCellSide edge_side1 : edge_side_range )
464 for(
DHCellSide edge_side2 : edge_side_range )
467 if (s2<=s1)
continue;
468 ASSERT(edge_side1.is_valid()).error(
"Invalid side of edge.");
475 if (fluxes[s2] > 0 && fluxes[s1] < 0)
476 transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
477 else if (fluxes[s2] < 0 && fluxes[s1] > 0)
478 transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
482 gamma_l = 0.5*fabs(transport_flux);
488 auto p2 = p1.point_on(edge_side2);
489 delta[0] += dot(
eq_fields_->diffusion_coef[sbi](p1)*normal_vector,normal_vector);
490 delta[1] += dot(
eq_fields_->diffusion_coef[sbi](p2)*normal_vector,normal_vector);
496 delta_sum = delta[0] + delta[1];
499 if (fabs(delta_sum) > 0)
501 omega[0] = delta[1]/delta_sum;
502 omega[1] = delta[0]/delta_sum;
503 double h = edge_side1.diameter();
506 gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
509 for (
int i=0; i<2; i++) omega[i] = 0;
512 int sd[2];
bool is_side_own[2];
513 sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
514 sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
520 auto p2 = p1.point_on(edge_side2);
521 for (
unsigned int i=0; i<
ndofs_; i++)
532 for (
int n=0; n<2; n++)
534 if (!is_side_own[n])
continue;
536 for (
int m=0; m<2; m++)
538 for (
unsigned int i=0; i<
ndofs_; i++)
539 for (
unsigned int j=0; j<
ndofs_; j++)
546 for (
unsigned int i=0; i<
ndofs_; i++)
548 for (
unsigned int j=0; j<
ndofs_; j++)
579 if (dim == 3)
return;
580 ASSERT_EQ(cell_lower_dim.
dim(), dim).error(
"Dimension of element mismatch!");
586 for(
unsigned int i=0; i<n_indices; ++i) {
593 for(
unsigned int i=0; i<n_indices; ++i) {
599 bool own_element_id[2];
600 own_element_id[0] = cell_lower_dim.
is_own();
601 own_element_id[1] = cell_higher_dim.
is_own();
603 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
612 auto p_low = p_high.lower_dim(cell_lower_dim);
627 if (!own_element_id[is_high_i])
continue;
682 template <
template<
IntDim...>
class DimAssembly>
691 template <
unsigned int dim,
class TEqData>
698 static constexpr
const char *
name() {
return "DG_Sources_Assembly"; }
727 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
735 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
745 for (
unsigned int i=0; i<
ndofs_; i++)
750 for (
unsigned int i=0; i<
ndofs_; i++)
797 template <
template<
IntDim...>
class DimAssembly>
806 template <
unsigned int dim,
class TEqData>
813 static constexpr
const char *
name() {
return "DG_BdrCondition_Assembly"; }
853 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
860 double transport_flux = side_flux/cell_side.
measure();
864 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
869 auto p_bdr = p.point_bdr(bc_elm);
870 double bc_term = -transport_flux*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
871 for (
unsigned int i=0; i<
ndofs_; i++)
874 for (
unsigned int i=0; i<
ndofs_; i++)
880 double transport_flux = side_flux/cell_side.
measure();
890 auto p_bdr = p.point_bdr(bc_elm);
891 double bc_term = gamma_l*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
893 for (
unsigned int i=0; i<
ndofs_; i++)
899 for (
unsigned int i=0; i<
ndofs_; i++)
906 if (
eq_data_->time_->step().index() > 0)
907 for (
unsigned int i=0; i<
ndofs_; i++)
914 auto p_bdr = p.point_bdr(bc_elm);
917 for (
unsigned int i=0; i<
ndofs_; i++)
921 for (
unsigned int i=0; i<
ndofs_; i++)
924 auto p_bdr = p.point_bdr(bc_elm);
935 auto p_bdr = p.point_bdr(bc_elm);
938 for (
unsigned int i=0; i<
ndofs_; i++)
942 for (
unsigned int i=0; i<
ndofs_; i++)
945 auto p_bdr = p.point_bdr(bc_elm);
956 for (
unsigned int i=0; i<
ndofs_; i++)
1002 template <
template<
IntDim...>
class DimAssembly>
1011 template <
unsigned int dim,
class TEqData>
1018 static constexpr
const char *
name() {
return "DG_InitProjection_Assembly"; }
1044 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1048 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1050 for (
unsigned int i=0; i<
ndofs_; i++)
1053 for (
unsigned int j=0; j<
ndofs_; j++)
1061 for (
unsigned int i=0; i<
ndofs_; i++)
1063 for (
unsigned int j=0; j<
ndofs_; j++)
1091 template <
template<
IntDim...>
class DimAssembly>
1100 template <
unsigned int dim,
class TEqData>
1107 static constexpr
const char *
name() {
return "DG_InitCondition_Assembly"; }
1116 for(
unsigned int i = 0; i<RefElement<dim>::n_nodes; i++)
1134 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1138 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1143 double val =
eq_fields_->init_condition[sbi](p);
1163 template <
template<
IntDim...>
class DimAssembly>
double advective_flux(Field< 3, FieldValue< 3 >::VectorFixed > &advection_coef, Range< PointType > pts, FeQ< Scalar > &JxW, ElQ< Vector > normal)
Computes advective flux.
double elem_anisotropy(ElementAccessor< 3 > e)
double DG_penalty_boundary(Side side, const double &diff_delta, const double flux, const double alpha)
Computes the penalty parameter of the DG method on a given boundary edge.
double diffusion_delta(Field< 3, FieldValue< 3 >::TensorFixed > &diff_coef, Range< BoundaryPoint > pts, const arma::vec3 &nv)
Computes average normal diffusivity over a set of points.
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
unsigned int n_dofs_high()
Return number of DOFs of higher dim element.
unsigned int n_dofs()
Return number of DOFs.
Quadrature * quad_
Quadrature used in assembling methods.
std::shared_ptr< CouplingIntegralAcc< dim > > create_coupling_integral(Quadrature *quad)
std::shared_ptr< EdgeIntegralAcc< dim > > create_edge_integral(Quadrature *quad)
AssemblyInternals * asm_internals_
Holds shared internals data with GeneriAssembly.
std::shared_ptr< BoundaryIntegralAcc< dim > > create_boundary_integral(Quadrature *quad)
std::shared_ptr< BulkIntegralAcc< dim > > create_bulk_integral(Quadrature *quad)
Quadrature * quad_low_
Quadrature used in assembling methods (dim-1).
void initialize()
Initialize auxiliary vectors and other data members.
void boundary_side_integral(DHCellSide cell_side)
Implements AssemblyBase::boundary_side_integral.
std::shared_ptr< BoundaryIntegralAcc< dim > > conc_integral_
Boundary integral of assembly class.
void begin() override
Implements AssemblyBase::begin.
PetscScalar local_flux_balance_rhs_
Auxiliary variable for set_boundary_conditions method.
TEqData::EqFields EqFields
unsigned int ndofs_
Number of dofs.
vector< PetscScalar > local_flux_balance_vector_
Auxiliary vector for set_boundary_conditions method.
FieldSet used_fields_
Sub field set contains fields used in calculation.
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
~BdrConditionAssemblyDG()
Destructor.
FeQArray< Scalar > conc_shape_
BdrConditionAssemblyDG(EqData *eq_data, AssemblyInternals *asm_internals)
Constructor.
static constexpr const char * name()
FeQArray< Vector > conc_grad_
EqFields * eq_fields_
Data objects shared with TransportDG.
void end() override
Implements AssemblyBase::end.
ElementAccessor< 3 > element_accessor()
Cell accessor allow iterate over DOF handler cells.
bool is_own() const
Return true if accessor represents own element (false for ghost element)
LocDofVec get_loc_dof_indices() const
Returns the local indices of dofs associated to the cell on the local process.
unsigned int get_dof_indices(std::vector< LongIdx > &indices) const
Fill vector of the global indices of dofs associated to the cell.
unsigned int dim() const
Return dimension of element appropriate to cell.
ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
Side accessor allows to iterate over sides of DOF handler cell.
Side side() const
Return Side of given cell and side_idx.
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
unsigned int dim() const
Return dimension of element appropriate to the side.
ElementAccessor< 3 > element() const
NodeAccessor< 3 > node(unsigned int ni) const
unsigned int idx() const
We need this method after replacing Region by RegionIdx, and movinf RegionDB instance into particular...
unsigned int n_nodes() const
FeQ< ValueType > shape(unsigned int i_shape_fn_idx) const
bool is_high_dim(unsigned int i_join_idx) const
unsigned int n_dofs_both() const
unsigned int n_dofs_low() const
unsigned int n_dofs_high() const
FeQ< ValueType > shape(unsigned int i_join_idx) const
Container for various descendants of FieldCommonBase.
Class template representing a field with values dependent on: point, element, and region.
Generic class of assemblation.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
InitConditionAssemblyDG(EqData *eq_data, AssemblyInternals *asm_internals)
Constructor.
std::shared_ptr< BulkIntegralAcc< dim > > init_integral_
Bulk integral of assembly class.
FieldSet used_fields_
Sub field set contains fields used in calculation.
EqFields * eq_fields_
Data objects shared with TransportDG.
TEqData::EqFields EqFields
static constexpr const char * name()
~InitConditionAssemblyDG()
Destructor.
void initialize()
Initialize auxiliary vectors and other data members.
static constexpr const char * name()
FeQArray< Scalar > init_shape_
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
void initialize()
Initialize auxiliary vectors and other data members.
~InitProjectionAssemblyDG()
Destructor.
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
std::shared_ptr< BulkIntegralAcc< dim > > init_integral_
Bulk integral of assembly class.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
InitProjectionAssemblyDG(EqData *eq_data, AssemblyInternals *asm_internals)
Constructor.
EqFields * eq_fields_
Data objects shared with TransportDG.
unsigned int ndofs_
Number of dofs.
TEqData::EqFields EqFields
FieldSet used_fields_
Sub field set contains fields used in calculation.
static constexpr double almost_zero
FieldSet used_fields_
Sub field set contains fields used in calculation.
static constexpr const char * name()
FeQArray< Scalar > conc_shape_
unsigned int ndofs_
Number of dofs.
MassAssemblyDG(EqData *eq_data, AssemblyInternals *asm_internals)
Constructor.
EqFields * eq_fields_
Data objects shared with TransportDG.
void begin() override
Implements AssemblyBase::begin.
vector< PetscScalar > local_retardation_balance_vector_
Auxiliary vector for assemble mass matrix.
void initialize()
Initialize auxiliary vectors and other data members.
~MassAssemblyDG()
Destructor.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
void end() override
Implements AssemblyBase::end.
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
TEqData::EqFields EqFields
std::shared_ptr< BulkIntegralAcc< dim > > conc_integral_
Bulk integral of assembly class.
vector< PetscScalar > local_mass_balance_vector_
Same as previous.
Base class for quadrature rules on simplices in arbitrary dimensions.
unsigned int size() const
Returns number of quadrature points.
Armor::Array< double >::ArrayMatSet set(uint i)
double weight(unsigned int i) const
Returns the ith weight.
IterConvert< ObjectIn, ObjectOut > begin()
Iterator to begin item of range.
static LocalPoint node_coords(unsigned int nid)
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
double measure() const
Calculate metrics of the side.
ElementAccessor< 3 > element() const
Returns iterator to the element of the side.
double diameter() const
Calculate the side diameter.
std::shared_ptr< BulkIntegralAcc< dim > > conc_integral_
Bulk integral of assembly class.
SourcesAssemblyDG(EqData *eq_data, AssemblyInternals *asm_internals)
Constructor.
EqFields * eq_fields_
Data objects shared with TransportDG.
~SourcesAssemblyDG()
Destructor.
FieldSet used_fields_
Sub field set contains fields used in calculation.
void initialize()
Initialize auxiliary vectors and other data members.
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
static constexpr const char * name()
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
vector< PetscScalar > local_source_balance_rhs_
Auxiliary vector for set_sources method.
void begin() override
Implements AssemblyBase::begin.
FeQArray< Scalar > conc_shape_
vector< PetscScalar > local_source_balance_vector_
Auxiliary vector for set_sources method.
TEqData::EqFields EqFields
unsigned int ndofs_
Number of dofs.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
void end() override
Implements AssemblyBase::end.
vector< double * > averages
Auxiliary storage for averages of shape functions.
std::shared_ptr< BoundaryIntegralAcc< dim > > conc_bdr_integral_
Boundary integral of assembly class.
void initialize()
Initialize auxiliary vectors and other data members.
FeQArray< Scalar > conc_shape_bdr_
unsigned int ndofs_
Number of dofs.
FieldSet used_fields_
Sub field set contains fields used in calculation.
FeQJoin< Scalar > conc_join_shape_
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
EqFields * eq_fields_
Data objects shared with TransportDG.
unsigned int qsize_lower_dim_
Size of quadrature of dim-1.
FeQArray< Scalar > conc_shape_side_
void edge_integral(RangeConvert< DHEdgeSide, DHCellSide > edge_side_range)
Assembles the fluxes between sides of elements of the same dimension.
~StiffnessAssemblyDG()
Destructor.
void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side)
Assembles the fluxes between elements of different dimensions.
ElQ< Vector > normal_bdr_
void boundary_side_integral(DHCellSide cell_side)
Assembles the fluxes on the boundary.
FeQArray< Vector > conc_grad_sidw_
ElQ< Vector > normal_join_
std::shared_ptr< CouplingIntegralAcc< dim > > conc_join_integral_
Coupling integral of assembly class.
static constexpr const char * name()
FeQArray< Vector > conc_grad_bdr_
StiffnessAssemblyDG(EqData *eq_data, AssemblyInternals *asm_internals)
Constructor.
vector< LongIdx > side_dof_indices_vb_
Vector of side DOF indices (assemble element-side fluxex)
vector< double * > waverages
Auxiliary storage for weighted averages of shape functions.
FeQArray< Scalar > conc_shape_
FeQArray< Vector > conc_grad_
std::shared_ptr< EdgeIntegralAcc< dim > > conc_edge_integral_
Edge integral of assembly class.
vector< vector< LongIdx > > side_dof_indices_
Vector of vectors of side DOF indices.
TEqData::EqFields EqFields
vector< LongIdx > dof_indices_
Vector of global DOF indices.
vector< double * > jumps
Auxiliary storage for jumps of shape functions.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assembles the cell (volume) integral into the stiffness matrix.
std::shared_ptr< BulkIntegralAcc< dim > > conc_bulk_integral_
Bulk integral of assembly class.
Definitions of basic Lagrangean finite elements with polynomial shape functions.
unsigned int IntDim
A dimension index type.
Class FEValues calculates finite element data on the actual cells such as shape function values,...
Store finite element reinit functions.
Definitions of particular quadrature rules on simplices.
Holds common data shared between GenericAssemblz and Assembly<dim> classes.
Discontinuous Galerkin method for equation of transport with dispersion.