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"; }
74 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
78 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
81 for (
unsigned int i=0; i<
ndofs_; i++)
83 for (
unsigned int j=0; j<
ndofs_; j++)
86 for (
auto p : this->
bulk_points(element_patch_idx) )
94 for (
unsigned int i=0; i<
ndofs_; i++)
98 for (
auto p : this->
bulk_points(element_patch_idx) )
142 template <
template<
IntDim...>
class DimAssembly>
151 double h_max = 0, h_min = numeric_limits<double>::infinity();
152 for (
unsigned int i=0; i<e->
n_nodes(); i++)
153 for (
unsigned int j=i+1; j<e->
n_nodes(); j++)
155 double dist = arma::norm(*e.
node(i) - *e.
node(j));
156 h_max = max(h_max, dist);
157 h_min = min(h_min, dist);
176 delta += dot(diff_coef(p)*nv, nv);
179 return n == 0 ? 0 : (delta/n);
194 const double &diff_delta,
211 template <
class Po
intType>
214 double side_flux = 0;
216 side_flux += arma::dot(advection_coef(p), normal(p))*JxW(p);
225 template <
unsigned int dim,
class Model>
232 static constexpr
const char *
name() {
return "StiffnessAssemblyDG"; }
258 for (
auto a :
averages)
if (a !=
nullptr)
delete[] a;
259 for (
auto a :
waverages)
if (a !=
nullptr)
delete[] a;
260 for (
auto a :
jumps)
if (a !=
nullptr)
delete[] a;
285 for (
unsigned int s=0; s<2; s++)
296 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
297 if (!cell.
is_own())
return;
302 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
304 for (
unsigned int i=0; i<
ndofs_; i++)
305 for (
unsigned int j=0; j<
ndofs_; j++)
308 for (
auto p : this->
bulk_points(element_patch_idx) )
310 for (
unsigned int i=0; i<
ndofs_; i++)
315 for (
unsigned int j=0; j<
ndofs_; j++)
329 ASSERT_EQ(cell_side.
dim(), dim).error(
"Dimension of element mismatch!");
339 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
344 double transport_flux = side_flux/side.
measure();
350 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
359 transport_flux += gamma_l;
366 double flux_times_JxW;
381 flux_times_JxW = transport_flux*
JxW_side_(p);
383 for (
unsigned int i=0; i<
ndofs_; i++)
385 for (
unsigned int j=0; j<
ndofs_; j++)
407 ASSERT_EQ(edge_side_range.
begin()->element().dim(), dim).error(
"Dimension of element mismatch!");
410 double gamma_l, omega[2], transport_flux, delta[2], delta_sum;
411 double aniso1, aniso2;
412 double local_alpha=0.0;
416 auto dh_edge_cell =
eq_data_->
dh_->cell_accessor_from_element( edge_side.elem_idx() );
420 auto zero_edge_side = *edge_side_range.
begin();
421 auto p = *( this->
edge_points(zero_edge_side).begin() );
425 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
428 double pflux = 0, nflux = 0;
434 pflux += fluxes[sid];
436 nflux += fluxes[sid];
447 for (
unsigned int i=0; i<
ndofs_; i++)
457 for(
DHCellSide edge_side1 : edge_side_range )
460 for(
DHCellSide edge_side2 : edge_side_range )
463 if (s2<=s1)
continue;
464 ASSERT(edge_side1.is_valid()).error(
"Invalid side of edge.");
466 auto p = *( this->
edge_points(edge_side1).begin() );
471 if (fluxes[s2] > 0 && fluxes[s1] < 0)
472 transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
473 else if (fluxes[s2] < 0 && fluxes[s1] > 0)
474 transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
478 gamma_l = 0.5*fabs(transport_flux);
484 auto p2 = p1.point_on(edge_side2);
485 delta[0] += dot(
eq_fields_->diffusion_coef[sbi](p1)*normal_vector,normal_vector);
486 delta[1] += dot(
eq_fields_->diffusion_coef[sbi](p2)*normal_vector,normal_vector);
492 delta_sum = delta[0] + delta[1];
495 if (fabs(delta_sum) > 0)
497 omega[0] = delta[1]/delta_sum;
498 omega[1] = delta[0]/delta_sum;
499 double h = edge_side1.diameter();
502 gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
505 for (
int i=0; i<2; i++) omega[i] = 0;
508 int sd[2];
bool is_side_own[2];
509 sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
510 sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
516 auto p2 = p1.point_on(edge_side2);
517 for (
unsigned int i=0; i<
ndofs_; i++)
528 for (
int n=0; n<2; n++)
530 if (!is_side_own[n])
continue;
532 for (
int m=0; m<2; m++)
534 for (
unsigned int i=0; i<
ndofs_; i++)
535 for (
unsigned int j=0; j<
ndofs_; j++)
542 for (
unsigned int i=0; i<
ndofs_; i++)
544 for (
unsigned int j=0; j<
ndofs_; j++)
575 if (dim == 1)
return;
576 ASSERT_EQ(cell_lower_dim.
dim(), dim-1).error(
"Dimension of element mismatch!");
582 for(
unsigned int i=0; i<n_indices; ++i) {
589 for(
unsigned int i=0; i<n_indices; ++i) {
595 bool own_element_id[2];
596 own_element_id[0] = cell_lower_dim.
is_own();
597 own_element_id[1] = cell_higher_dim.
is_own();
599 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
608 auto p_low = p_high.lower_dim(cell_lower_dim);
619 double transport_flux = arma::dot(
eq_fields_->advection_coef[sbi](p_high),
normal_(p_high));
622 uint is_high_i = conc_shape_i.is_high_dim();
623 if (!own_element_id[is_high_i])
continue;
624 uint i_mat_idx = conc_shape_i.join_idx();
625 double diff_shape_i = conc_shape_i(p_high) - conc_shape_i(p_low);
627 uint j_mat_idx = conc_shape_j.join_idx();
629 sigma * diff_shape_i * (conc_shape_j(p_high) - conc_shape_j(p_low))
630 + diff_shape_i * ( max(0.,transport_flux) * conc_shape_j(p_high) + min(0.,transport_flux) * conc_shape_j(p_low))
669 template <
template<
IntDim...>
class DimAssembly>
678 template <
unsigned int dim,
class Model>
685 static constexpr
const char *
name() {
return "SourcesAssemblyDG"; }
717 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
725 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
731 for (
auto p : this->
bulk_points(element_patch_idx) )
735 for (
unsigned int i=0; i<
ndofs_; i++)
740 for (
unsigned int i=0; i<
ndofs_; i++)
742 for (
auto p : this->
bulk_points(element_patch_idx) )
786 template <
template<
IntDim...>
class DimAssembly>
795 template <
unsigned int dim,
class Model>
802 static constexpr
const char *
name() {
return "BdrConditionAssemblyDG"; }
845 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
852 double transport_flux = side_flux/cell_side.
measure();
856 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
861 auto p_bdr = p.point_bdr(bc_elm);
862 double bc_term = -transport_flux*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
863 for (
unsigned int i=0; i<
ndofs_; i++)
866 for (
unsigned int i=0; i<
ndofs_; i++)
872 double transport_flux = side_flux/cell_side.
measure();
882 auto p_bdr = p.point_bdr(bc_elm);
883 double bc_term = gamma_l*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
885 for (
unsigned int i=0; i<
ndofs_; i++)
891 for (
unsigned int i=0; i<
ndofs_; i++)
899 for (
unsigned int i=0; i<
ndofs_; i++)
906 auto p_bdr = p.point_bdr(bc_elm);
909 for (
unsigned int i=0; i<
ndofs_; i++)
913 for (
unsigned int i=0; i<
ndofs_; i++)
916 auto p_bdr = p.point_bdr(bc_elm);
927 auto p_bdr = p.point_bdr(bc_elm);
930 for (
unsigned int i=0; i<
ndofs_; i++)
934 for (
unsigned int i=0; i<
ndofs_; i++)
937 auto p_bdr = p.point_bdr(bc_elm);
948 for (
unsigned int i=0; i<
ndofs_; i++)
993 template <
template<
IntDim...>
class DimAssembly>
1002 template <
unsigned int dim,
class Model>
1009 static constexpr
const char *
name() {
return "InitProjectionAssemblyDG"; }
1038 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1042 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1044 for (
unsigned int i=0; i<
ndofs_; i++)
1047 for (
unsigned int j=0; j<
ndofs_; j++)
1051 for (
auto p : this->
bulk_points(element_patch_idx) )
1055 for (
unsigned int i=0; i<
ndofs_; i++)
1057 for (
unsigned int j=0; j<
ndofs_; j++)
1084 template <
template<
IntDim...>
class DimAssembly>
1093 template <
unsigned int dim,
class Model>
1100 static constexpr
const char *
name() {
return "InitConditionAssemblyDG"; }
1109 for(
unsigned int i = 0; i<RefElement<dim>::n_nodes; i++)
1128 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1132 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1135 for (
auto p : this->
bulk_points(element_patch_idx) )
1137 double val =
eq_fields_->init_condition[sbi](p);
1154 template <
template<
IntDim...>
class DimAssembly>
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.
double advective_flux(Field< 3, FieldValue< 3 >::VectorFixed > &advection_coef, Range< PointType > pts, ElQ< Scalar > &JxW, ElQ< Vector > normal)
Computes advective flux.
#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.
TransportDG< Model >::EqData EqData
TransportDG< Model >::EqFields EqFields
void begin() override
Implements AssemblyBase::begin.
~BdrConditionAssemblyDG()
Destructor.
PetscScalar local_flux_balance_rhs_
Auxiliary variable for set_boundary_conditions method.
FeQ< Scalar > conc_shape_
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
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.
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.
FeQ< Scalar > init_shape_
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.
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()
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
FeQ< Scalar > conc_shape_
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.
Iter< Object > 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.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
void begin() override
Implements AssemblyBase::begin.
FeQ< Scalar > conc_shape_
TransportDG< Model >::EqData EqData
FeQ< Scalar > conc_shape_
void edge_integral(RangeConvert< DHEdgeSide, DHCellSide > edge_side_range)
Assembles the fluxes between sides of elements of the same dimension.
FeQ< Vector > conc_grad_sidw_
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.
Range< JoinShapeAccessor< Scalar > > conc_join_shape_
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)
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assembles the cell (volume) integral into the stiffness matrix.
TransportDG< Model >::EqFields EqFields
vector< double * > averages
Auxiliary storage for averages of shape functions.
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.
FeQ< Scalar > conc_shape_side_
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.