18 #ifndef ASSEMBLY_DG_HH_
19 #define ASSEMBLY_DG_HH_
37 template <
unsigned int dim,
class Model>
44 static constexpr
const char *
name() {
return "MassAssemblyDG"; }
76 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
80 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
83 for (
unsigned int i=0; i<
ndofs_; i++)
85 for (
unsigned int j=0; j<
ndofs_; j++)
88 for (
auto p : this->
bulk_points(element_patch_idx) )
96 for (
unsigned int i=0; i<
ndofs_; i++)
100 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"; }
259 for (
auto a :
averages)
if (a !=
nullptr)
delete[] a;
260 for (
auto a :
waverages)
if (a !=
nullptr)
delete[] a;
261 for (
auto a :
jumps)
if (a !=
nullptr)
delete[] a;
286 for (
unsigned int s=0; s<2; s++)
297 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
298 if (!cell.
is_own())
return;
303 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
305 for (
unsigned int i=0; i<
ndofs_; i++)
306 for (
unsigned int j=0; j<
ndofs_; j++)
309 for (
auto p : this->
bulk_points(element_patch_idx) )
311 for (
unsigned int i=0; i<
ndofs_; i++)
316 for (
unsigned int j=0; j<
ndofs_; j++)
330 ASSERT_EQ(cell_side.
dim(), dim).error(
"Dimension of element mismatch!");
340 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
345 double transport_flux = side_flux/side.
measure();
351 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
360 transport_flux += gamma_l;
367 double flux_times_JxW;
382 flux_times_JxW = transport_flux*
JxW_side_(p);
384 for (
unsigned int i=0; i<
ndofs_; i++)
386 for (
unsigned int j=0; j<
ndofs_; j++)
408 ASSERT_EQ(edge_side_range.
begin()->element().dim(), dim).error(
"Dimension of element mismatch!");
411 double gamma_l, omega[2], transport_flux, delta[2], delta_sum;
412 double aniso1, aniso2;
413 double local_alpha=0.0;
417 auto dh_edge_cell =
eq_data_->
dh_->cell_accessor_from_element( edge_side.elem_idx() );
421 auto zero_edge_side = *edge_side_range.
begin();
422 auto p = *( this->
edge_points(zero_edge_side).begin() );
426 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
429 double pflux = 0, nflux = 0;
435 pflux += fluxes[sid];
437 nflux += fluxes[sid];
448 for (
unsigned int i=0; i<
ndofs_; i++)
458 for(
DHCellSide edge_side1 : edge_side_range )
461 for(
DHCellSide edge_side2 : edge_side_range )
464 if (s2<=s1)
continue;
465 ASSERT(edge_side1.is_valid()).error(
"Invalid side of edge.");
467 auto p = *( this->
edge_points(edge_side1).begin() );
472 if (fluxes[s2] > 0 && fluxes[s1] < 0)
473 transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
474 else if (fluxes[s2] < 0 && fluxes[s1] > 0)
475 transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
479 gamma_l = 0.5*fabs(transport_flux);
485 auto p2 = p1.point_on(edge_side2);
486 delta[0] += dot(
eq_fields_->diffusion_coef[sbi](p1)*normal_vector,normal_vector);
487 delta[1] += dot(
eq_fields_->diffusion_coef[sbi](p2)*normal_vector,normal_vector);
493 delta_sum = delta[0] + delta[1];
496 if (fabs(delta_sum) > 0)
498 omega[0] = delta[1]/delta_sum;
499 omega[1] = delta[0]/delta_sum;
500 double h = edge_side1.diameter();
503 gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
506 for (
int i=0; i<2; i++) omega[i] = 0;
509 int sd[2];
bool is_side_own[2];
510 sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
511 sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
517 auto p2 = p1.point_on(edge_side2);
518 for (
unsigned int i=0; i<
ndofs_; i++)
529 for (
int n=0; n<2; n++)
531 if (!is_side_own[n])
continue;
533 for (
int m=0; m<2; m++)
535 for (
unsigned int i=0; i<
ndofs_; i++)
536 for (
unsigned int j=0; j<
ndofs_; j++)
543 for (
unsigned int i=0; i<
ndofs_; i++)
545 for (
unsigned int j=0; j<
ndofs_; j++)
576 if (dim == 1)
return;
577 ASSERT_EQ(cell_lower_dim.
dim(), dim-1).error(
"Dimension of element mismatch!");
583 for(
unsigned int i=0; i<n_indices; ++i) {
590 for(
unsigned int i=0; i<n_indices; ++i) {
596 bool own_element_id[2];
597 own_element_id[0] = cell_lower_dim.
is_own();
598 own_element_id[1] = cell_higher_dim.
is_own();
600 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
609 auto p_low = p_high.lower_dim(cell_lower_dim);
620 double transport_flux = arma::dot(
eq_fields_->advection_coef[sbi](p_high),
normal_(p_high));
624 if (!own_element_id[is_high_i])
continue;
668 template <
template<
IntDim...>
class DimAssembly>
677 template <
unsigned int dim,
class Model>
684 static constexpr
const char *
name() {
return "SourcesAssemblyDG"; }
716 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
724 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
730 for (
auto p : this->
bulk_points(element_patch_idx) )
734 for (
unsigned int i=0; i<
ndofs_; i++)
739 for (
unsigned int i=0; i<
ndofs_; i++)
741 for (
auto p : this->
bulk_points(element_patch_idx) )
785 template <
template<
IntDim...>
class DimAssembly>
794 template <
unsigned int dim,
class Model>
801 static constexpr
const char *
name() {
return "BdrConditionAssemblyDG"; }
844 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
851 double transport_flux = side_flux/cell_side.
measure();
855 unsigned int bc_type =
eq_fields_->bc_type[sbi](p_bdr);
860 auto p_bdr = p.point_bdr(bc_elm);
861 double bc_term = -transport_flux*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
862 for (
unsigned int i=0; i<
ndofs_; i++)
865 for (
unsigned int i=0; i<
ndofs_; i++)
871 double transport_flux = side_flux/cell_side.
measure();
881 auto p_bdr = p.point_bdr(bc_elm);
882 double bc_term = gamma_l*
eq_fields_->bc_dirichlet_value[sbi](p_bdr)*
JxW_(p);
884 for (
unsigned int i=0; i<
ndofs_; i++)
890 for (
unsigned int i=0; i<
ndofs_; i++)
898 for (
unsigned int i=0; i<
ndofs_; i++)
905 auto p_bdr = p.point_bdr(bc_elm);
908 for (
unsigned int i=0; i<
ndofs_; i++)
912 for (
unsigned int i=0; i<
ndofs_; i++)
915 auto p_bdr = p.point_bdr(bc_elm);
926 auto p_bdr = p.point_bdr(bc_elm);
929 for (
unsigned int i=0; i<
ndofs_; i++)
933 for (
unsigned int i=0; i<
ndofs_; i++)
936 auto p_bdr = p.point_bdr(bc_elm);
947 for (
unsigned int i=0; i<
ndofs_; i++)
992 template <
template<
IntDim...>
class DimAssembly>
1001 template <
unsigned int dim,
class Model>
1008 static constexpr
const char *
name() {
return "InitProjectionAssemblyDG"; }
1037 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1041 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1043 for (
unsigned int i=0; i<
ndofs_; i++)
1046 for (
unsigned int j=0; j<
ndofs_; j++)
1050 for (
auto p : this->
bulk_points(element_patch_idx) )
1054 for (
unsigned int i=0; i<
ndofs_; i++)
1056 for (
unsigned int j=0; j<
ndofs_; j++)
1083 template <
template<
IntDim...>
class DimAssembly>
1092 template <
unsigned int dim,
class Model>
1099 static constexpr
const char *
name() {
return "InitConditionAssemblyDG"; }
1108 for(
unsigned int i = 0; i<RefElement<dim>::n_nodes; i++)
1127 ASSERT_EQ(cell.
dim(), dim).error(
"Dimension of element mismatch!");
1131 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
1134 for (
auto p : this->
bulk_points(element_patch_idx) )
1136 double val =
eq_fields_->init_condition[sbi](p);
1153 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.
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 > 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_
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.
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.
TransportDG< Model >::EqData EqData
FeQArray< Vector > conc_grad_sidw_
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_
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assembles the cell (volume) integral into the stiffness matrix.
FeQArray< Scalar > conc_shape_side_
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.
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.
Declares top level factory classes of FE operations.
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.
Discontinuous Galerkin method for equation of transport with dispersion.