18 #ifndef ASSEMBLY_DG_HH_
19 #define ASSEMBLY_DG_HH_
35 template <
unsigned int dim,
class Model>
42 static constexpr
const char *
name() {
return "MassAssemblyDG"; }
75 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
79 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
82 for (
unsigned int i=0; i<
ndofs_; i++)
84 for (
unsigned int j=0; j<
ndofs_; j++)
87 for (
auto p : this->
bulk_points(element_patch_idx) )
95 for (
unsigned int i=0; i<
ndofs_; i++)
99 for (
auto p : this->
bulk_points(element_patch_idx) )
144 template <
template<
IntDim...>
class DimAssembly>
153 double h_max = 0, h_min = numeric_limits<double>::infinity();
154 for (
unsigned int i=0; i<e->
n_nodes(); i++)
155 for (
unsigned int j=i+1; j<e->
n_nodes(); j++)
157 double dist = arma::norm(*e.
node(i) - *e.
node(j));
158 h_max = max(h_max, dist);
159 h_min = min(h_min, dist);
177 delta += dot(diff_coef(p)*nv, nv);
180 return n == 0 ? 0 : (delta/n);
195 const double &diff_delta,
212 template <
class Po
intType>
215 double side_flux = 0;
217 side_flux += arma::dot(advection_coef(p), normal(p))*JxW(p);
226 template <
unsigned int dim,
class Model>
233 static constexpr
const char *
name() {
return "StiffnessAssemblyDG"; }
263 for (
auto a :
averages)
if (a !=
nullptr)
delete[] a;
264 for (
auto a :
waverages)
if (a !=
nullptr)
delete[] a;
265 for (
auto a :
jumps)
if (a !=
nullptr)
delete[] a;
290 for (
unsigned int s=0; s<2; s++)
301 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
302 if (!cell.
is_own())
return;
307 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
309 for (
unsigned int i=0; i<
ndofs_; i++)
310 for (
unsigned int j=0; j<
ndofs_; j++)
313 for (
auto p : this->
bulk_points(element_patch_idx) )
315 for (
unsigned int i=0; i<
ndofs_; i++)
320 for (
unsigned int j=0; j<
ndofs_; j++)
334 ASSERT_EQ(cell_side.
dim(), dim).error(
"Dimension of element mismatch!");
344 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
349 double transport_flux = side_flux/side.
measure();
355 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
364 transport_flux += gamma_l;
371 double flux_times_JxW;
386 flux_times_JxW = transport_flux*
JxW_side_(p);
388 for (
unsigned int i=0; i<
ndofs_; i++)
390 for (
unsigned int j=0; j<
ndofs_; j++)
412 ASSERT_EQ(edge_side_range.
begin()->element().dim(), dim).error(
"Dimension of element mismatch!");
415 double gamma_l, omega[2], transport_flux, delta[2], delta_sum;
416 double aniso1, aniso2;
417 double local_alpha=0.0;
421 auto dh_edge_cell =
eq_data_->
dh_->cell_accessor_from_element( edge_side.elem_idx() );
425 auto zero_edge_side = *edge_side_range.
begin();
426 auto p = *( this->
edge_points(zero_edge_side).begin() );
430 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
433 double pflux = 0, nflux = 0;
439 pflux += fluxes[sid];
441 nflux += fluxes[sid];
452 for (
unsigned int i=0; i<
ndofs_; i++)
462 for(
DHCellSide edge_side1 : edge_side_range )
465 for(
DHCellSide edge_side2 : edge_side_range )
468 if (s2<=s1)
continue;
469 ASSERT(edge_side1.is_valid()).error(
"Invalid side of edge.");
471 auto p = *( this->
edge_points(edge_side1).begin() );
476 if (fluxes[s2] > 0 && fluxes[s1] < 0)
477 transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
478 else if (fluxes[s2] < 0 && fluxes[s1] > 0)
479 transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
483 gamma_l = 0.5*fabs(transport_flux);
489 auto p2 = p1.point_on(edge_side2);
490 delta[0] += dot(
eq_fields_->diffusion_coef[sbi](p1)*normal_vector,normal_vector);
491 delta[1] += dot(
eq_fields_->diffusion_coef[sbi](p2)*normal_vector,normal_vector);
497 delta_sum = delta[0] + delta[1];
500 if (fabs(delta_sum) > 0)
502 omega[0] = delta[1]/delta_sum;
503 omega[1] = delta[0]/delta_sum;
504 double h = edge_side1.diameter();
507 gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
510 for (
int i=0; i<2; i++) omega[i] = 0;
513 int sd[2];
bool is_side_own[2];
514 sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
515 sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
521 auto p2 = p1.point_on(edge_side2);
522 for (
unsigned int i=0; i<
ndofs_; i++)
533 for (
int n=0; n<2; n++)
535 if (!is_side_own[n])
continue;
537 for (
int m=0; m<2; m++)
539 for (
unsigned int i=0; i<
ndofs_; i++)
540 for (
unsigned int j=0; j<
ndofs_; j++)
547 for (
unsigned int i=0; i<
ndofs_; i++)
549 for (
unsigned int j=0; j<
ndofs_; j++)
580 if (dim == 1)
return;
581 ASSERT_EQ(cell_lower_dim.
dim(), dim-1).error(
"Dimension of element mismatch!");
587 for(
unsigned int i=0; i<n_indices; ++i) {
594 for(
unsigned int i=0; i<n_indices; ++i) {
600 bool own_element_id[2];
601 own_element_id[0] = cell_lower_dim.
is_own();
602 own_element_id[1] = cell_higher_dim.
is_own();
604 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
613 auto p_low = p_high.lower_dim(cell_lower_dim);
624 double transport_flux = arma::dot(
eq_fields_->advection_coef[sbi](p_high),
normal_(p_high));
628 if (!own_element_id[is_high_i])
continue;
676 template <
template<
IntDim...>
class DimAssembly>
685 template <
unsigned int dim,
class Model>
692 static constexpr
const char *
name() {
return "SourcesAssemblyDG"; }
725 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
733 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
739 for (
auto p : this->
bulk_points(element_patch_idx) )
743 for (
unsigned int i=0; i<
ndofs_; i++)
748 for (
unsigned int i=0; i<
ndofs_; i++)
750 for (
auto p : this->
bulk_points(element_patch_idx) )
795 template <
template<
IntDim...>
class DimAssembly>
804 template <
unsigned int dim,
class Model>
811 static constexpr
const char *
name() {
return "BdrConditionAssemblyDG"; }
856 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
863 double transport_flux = side_flux/cell_side.
measure();
867 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
872 auto p_bdr = p.point_bdr(bc_elm);
873 double bc_term = -transport_flux*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
874 for (
unsigned int i=0; i<
ndofs_; i++)
877 for (
unsigned int i=0; i<
ndofs_; i++)
883 double transport_flux = side_flux/cell_side.
measure();
893 auto p_bdr = p.point_bdr(bc_elm);
894 double bc_term = gamma_l*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
896 for (
unsigned int i=0; i<
ndofs_; i++)
902 for (
unsigned int i=0; i<
ndofs_; i++)
910 for (
unsigned int i=0; i<
ndofs_; i++)
917 auto p_bdr = p.point_bdr(bc_elm);
920 for (
unsigned int i=0; i<
ndofs_; i++)
924 for (
unsigned int i=0; i<
ndofs_; i++)
927 auto p_bdr = p.point_bdr(bc_elm);
938 auto p_bdr = p.point_bdr(bc_elm);
941 for (
unsigned int i=0; i<
ndofs_; i++)
945 for (
unsigned int i=0; i<
ndofs_; i++)
948 auto p_bdr = p.point_bdr(bc_elm);
959 for (
unsigned int i=0; i<
ndofs_; i++)
1006 template <
template<
IntDim...>
class DimAssembly>
1015 template <
unsigned int dim,
class Model>
1022 static constexpr
const char *
name() {
return "InitProjectionAssemblyDG"; }
1052 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1056 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1058 for (
unsigned int i=0; i<
ndofs_; i++)
1061 for (
unsigned int j=0; j<
ndofs_; j++)
1065 for (
auto p : this->
bulk_points(element_patch_idx) )
1069 for (
unsigned int i=0; i<
ndofs_; i++)
1071 for (
unsigned int j=0; j<
ndofs_; j++)
1099 template <
template<
IntDim...>
class DimAssembly>
1108 template <
unsigned int dim,
class Model>
1115 static constexpr
const char *
name() {
return "InitConditionAssemblyDG"; }
1124 for(
unsigned int i = 0; i<RefElement<dim>::n_nodes; i++)
1143 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1147 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1150 for (
auto p : this->
bulk_points(element_patch_idx) )
1152 double val =
eq_fields_->init_condition[sbi](p);
1169 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.
JoinValues< dim > join_values()
Return JoinValues object.
PatchFEValues< 3 > * fe_values_
Common FEValues object over all dimensions.
BulkValues< dim > bulk_values()
Return BulkValues object.
unsigned int n_dofs()
Return BulkValues object.
SideValues< dim > side_values()
Return SideValues object.
Range< BulkPoint > bulk_points(unsigned int element_patch_idx) const
Return BulkPoint range of appropriate dimension.
Range< EdgePoint > edge_points(const DHCellSide &cell_side) const
Return EdgePoint range of appropriate dimension.
Quadrature * quad_
Quadrature used in assembling methods.
Quadrature * quad_low_
Quadrature used in assembling methods (dim-1).
Range< CouplingPoint > coupling_points(const DHCellSide &cell_side) const
Return CouplingPoint range of appropriate dimension.
int active_integrals_
Holds mask of active integrals.
Range< BoundaryPoint > boundary_points(const DHCellSide &cell_side) const
Return BoundaryPoint range of appropriate dimension.
ElementCacheMap * element_cache_map_
ElementCacheMap shared with GenericAssembly object.
static constexpr const char * name()
FieldSet used_fields_
Sub field set contains fields used in calculation.
vector< PetscScalar > local_flux_balance_vector_
Auxiliary vector for set_boundary_conditions method.
void boundary_side_integral(DHCellSide cell_side)
Implements AssemblyBase::boundary_side_integral.
BdrConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
FeQArray< Scalar > ref_scalar_side_
TransportDG< Model >::EqData EqData
TransportDG< Model >::EqFields EqFields
FeQArray< Scalar > conc_shape_
void begin() override
Implements AssemblyBase::begin.
~BdrConditionAssemblyDG()
Destructor.
PetscScalar local_flux_balance_rhs_
Auxiliary variable for set_boundary_conditions method.
FeQArray< Vector > ref_scalar_grad_side_
FeQArray< Vector > conc_grad_
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
EqFields * eq_fields_
Data objects shared with TransportDG.
void end() override
Implements AssemblyBase::end.
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
unsigned int ndofs_
Number of dofs.
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...
Directing class of FieldValueCache.
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.
FieldSet used_fields_
Sub field set contains fields used in calculation.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
static constexpr const char * name()
~InitConditionAssemblyDG()
Destructor.
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
InitConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data)
Constructor.
EqFields * eq_fields_
Data objects shared with TransportDG.
TransportDG< Model >::EqData EqData
TransportDG< Model >::EqFields EqFields
EqFields * eq_fields_
Data objects shared with TransportDG.
FeQArray< Scalar > init_shape_
FeQArray< Scalar > ref_scalar_
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
TransportDG< Model >::EqData EqData
FieldSet used_fields_
Sub field set contains fields used in calculation.
unsigned int ndofs_
Number of dofs.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
InitProjectionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
static constexpr const char * name()
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
~InitProjectionAssemblyDG()
Destructor.
TransportDG< Model >::EqFields EqFields
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
virtual void rhs_set_values(int nrow, int *rows, double *vals)=0
virtual void mat_set_values(int nrow, int *rows, int ncol, int *cols, double *vals)=0
void set_values(int nrow, int *rows, int ncol, int *cols, PetscScalar *mat_vals, PetscScalar *rhs_vals)
Set values in the system matrix and values in the right-hand side vector on corresponding rows.
static constexpr double almost_zero
vector< LongIdx > dof_indices_
Vector of global DOF indices.
vector< PetscScalar > local_mass_balance_vector_
Same as previous.
TransportDG< Model >::EqFields EqFields
MassAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
FieldSet used_fields_
Sub field set contains fields used in calculation.
FeQArray< Scalar > ref_scalar_
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
void end() override
Implements AssemblyBase::end.
~MassAssemblyDG()
Destructor.
void begin() override
Implements AssemblyBase::begin.
static constexpr const char * name()
FeQArray< Scalar > conc_shape_
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
unsigned int ndofs_
Number of dofs.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
TransportDG< Model >::EqData EqData
EqFields * eq_fields_
Data objects shared with TransportDG.
vector< PetscScalar > local_retardation_balance_vector_
Auxiliary vector for assemble mass matrix.
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.
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
TransportDG< Model >::EqData EqData
TransportDG< Model >::EqFields EqFields
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
~SourcesAssemblyDG()
Destructor.
SourcesAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
vector< PetscScalar > local_source_balance_vector_
Auxiliary vector for set_sources method.
void end() override
Implements AssemblyBase::end.
static constexpr const char * name()
EqFields * eq_fields_
Data objects shared with TransportDG.
vector< PetscScalar > local_source_balance_rhs_
Auxiliary vector for set_sources method.
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
FieldSet used_fields_
Sub field set contains fields used in calculation.
unsigned int ndofs_
Number of dofs.
FeQArray< Scalar > conc_shape_
vector< LongIdx > dof_indices_
Vector of global DOF indices.
void begin() override
Implements AssemblyBase::begin.
FeQArray< Scalar > ref_scalar_
TransportDG< Model >::EqData EqData
FeQArray< Vector > conc_grad_sidw_
FeQArray< Scalar > ref_scalar_
void edge_integral(RangeConvert< DHEdgeSide, DHCellSide > edge_side_range)
Assembles the fluxes between sides of elements of the same dimension.
FieldSet used_fields_
Sub field set contains fields used in calculation.
unsigned int ndofs_
Number of dofs.
vector< vector< LongIdx > > side_dof_indices_
Vector of vectors of side DOF indices.
FeQArray< Vector > conc_grad_
StiffnessAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
void boundary_side_integral(DHCellSide cell_side)
Assembles the fluxes on the boundary.
vector< double * > jumps
Auxiliary storage for jumps of shape functions.
vector< double * > waverages
Auxiliary storage for weighted averages of shape functions.
void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side)
Assembles the fluxes between elements of different dimensions.
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
vector< LongIdx > side_dof_indices_vb_
Vector of side DOF indices (assemble element-side fluxex)
FeQArray< Scalar > conc_shape_
FeQArray< Vector > ref_scalar_grad_
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assembles the cell (volume) integral into the stiffness matrix.
FeQArray< Vector > ref_scalar_grad_side_
FeQArray< Scalar > conc_shape_side_
TransportDG< Model >::EqFields EqFields
vector< double * > averages
Auxiliary storage for averages of shape functions.
FeQArray< Scalar > ref_scalar_side_
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
~StiffnessAssemblyDG()
Destructor.
static constexpr const char * name()
vector< LongIdx > dof_indices_
Vector of global DOF indices.
FeQJoin< Scalar > conc_join_shape_
EqFields * eq_fields_
Data objects shared with TransportDG.
unsigned int qsize_lower_dim_
Size of quadrature of dim-1.
const TimeStep & step(int index=-1) const
unsigned int index() const
std::shared_ptr< DOFHandlerMultiDim > dh_
Object for distribution of dofs.
std::vector< VectorMPI > output_vec
Vector of solution data.
LinSys ** ls_dt
Linear algebra system for the time derivative (actually it is used only for handling the matrix struc...
int dg_variant
DG variant ((non-)symmetric/incomplete.
std::shared_ptr< Balance > balance_
LinSys ** ls
Linear algebra system for the transport equation.
std::vector< Vec > ret_vec
Auxiliary vectors for calculation of sources in balance due to retardation (e.g. sorption).
unsigned int max_edg_sides
Maximal number of edge sides (evaluate from dim 1,2,3)
MultiField< 3, FieldValue< 3 >::Scalar > dg_penalty
Penalty enforcing inter-element continuity of solution (for each substance).
MultiField< 3, FieldValue< 3 >::Scalar > fracture_sigma
Transition parameter for diffusive transfer on fractures (for each substance).
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,...
Definitions of particular quadrature rules on simplices.
Discontinuous Galerkin method for equation of transport with dispersion.