50 using namespace
Input::Type;
54 return Selection(
"DG_variant",
"Type of penalty term.")
55 .
add_value(non_symmetric,
"non-symmetric",
"non-symmetric weighted interior penalty DG method")
56 .
add_value(incomplete,
"incomplete",
"incomplete weighted interior penalty DG method")
57 .
add_value(symmetric,
"symmetric",
"symmetric weighted interior penalty DG method")
80 std::string equation_name = std::string(Model::ModelEqData::name()) +
"_DG";
81 return Model::get_input_type(
"DG",
"Discontinuous Galerkin (DG) solver")
83 "Solver for the linear system.")
86 .make_field_descriptor_type(equation_name)),
88 "Input fields of the equation.")
90 "Variant of the interior penalty discontinuous Galerkin method.")
92 "Polynomial order for the finite element in DG method (order 0 is suitable if there is no diffusion/dispersion).")
94 EqFields().output_fields.make_output_type(equation_name,
""),
95 IT::Default(
"{ \"fields\": [ " + Model::ModelEqData::default_output_field() +
"] }"),
96 "Specification of output fields and output times.")
100 template<
class Model>
102 Input::register_class< TransportDG<Model>,
Mesh &,
const Input::Record>(std::string(Model::ModelEqData::name()) +
"_DG") +
107 template<
class Model>
111 .
name(
"fracture_sigma")
113 "Coefficient of diffusive transfer through fractures (for each substance).")
121 "Penalty parameter influencing the discontinuity of the solution (for each substance). " 122 "Its default value 1 is sufficient in most cases. Higher value diminishes the inter-element jumps.")
135 .
description(
"Subdomain ids of the domain decomposition.");
146 template<
class Model>
149 double h_max = 0, h_min = numeric_limits<double>::infinity();
150 for (
unsigned int i=0; i<e->
n_nodes(); i++)
151 for (
unsigned int j=i+1; j<e->
n_nodes(); j++)
153 double dist = arma::norm(*e.
node(i) - *e.
node(j));
154 h_max = max(h_max, dist);
155 h_min = min(h_min, dist);
162 template<
class Model>
171 double delta = 0, h = 0;
180 for (
unsigned int i=0; i<side.
n_nodes(); i++)
181 for (
unsigned int j=i+1; j<side.
n_nodes(); j++) {
182 double dist = arma::norm(*side.
node(i) - *side.
node(j));
189 for (
int k=0; k<K_size; k++)
190 delta += dot(K[k]*normal_vector,normal_vector);
193 gamma = 0.5*fabs(flux) + alpha/h*delta*elem_anisotropy(side.
element());
198 template<
typename Model>
200 :
Model(init_mesh, in_rec),
212 eq_fields_->add_coords_field();
214 Model::init_balance(in_rec);
218 eq_fields_->set_mesh(init_mesh);
225 eq_data_->dg_order = in_rec.
val<
unsigned int>(
"dg_order");
227 Model::init_from_input(in_rec);
230 shared_ptr<DiscreteSpace> ds = make_shared<EqualOrderDiscreteSpace>(Model::mesh_, fe);
231 eq_data_->dh_ = make_shared<DOFHandlerMultiDim>(*Model::mesh_);
238 template<
class Model>
243 eq_data_->set_time_governor(Model::time_);
249 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
250 eq_data_->gamma[sbi].resize(Model::mesh_->boundary_.size());
253 eq_data_->max_edg_sides = max(Model::mesh_->max_edge_sides(1), max(Model::mesh_->max_edge_sides(2), Model::mesh_->max_edge_sides(3)));
259 eq_fields_->output_field.set_mesh(*Model::mesh_);
263 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
266 auto output_field_ptr = create_field_fe< 3, FieldValue<3>::Scalar >(
eq_data_->dh_);
267 eq_fields_->output_field[sbi].set(output_field_ptr, 0);
275 std::string petsc_default_opts;
276 if (
eq_data_->dh_->distr()->np() == 1)
277 petsc_default_opts =
"-ksp_type bcgs -pc_type ilu -pc_factor_levels 2 -ksp_diagonal_scale_fix -pc_factor_fill 6.0";
279 petsc_default_opts =
"-ksp_type bcgs -ksp_diagonal_scale_fix -pc_type asm -pc_asm_overlap 4 -sub_pc_type ilu -sub_pc_factor_levels 3 -sub_pc_factor_fill 6.0";
287 shared_ptr<DiscreteSpace> ds = make_shared<EqualOrderDiscreteSpace>(Model::mesh_, fe);
288 eq_data_->dh_p0 = make_shared<DOFHandlerMultiDim>(*Model::mesh_);
289 eq_data_->dh_p0->distribute_dofs(ds);
297 for (
unsigned int sbi = 0; sbi <
eq_data_->n_substances(); sbi++) {
305 eq_data_->conc_fe[sbi] = create_field_fe< 3, FieldValue<3>::Scalar >(
eq_data_->dh_p0);
319 Model::balance_->allocate(
eq_data_->dh_->distr()->lsize(), mass_assembly_->eval_points()->max_size());
321 int qsize = mass_assembly_->
eval_points()->max_size();
323 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
325 eq_data_->dif_coef[sbi].resize(qsize);
330 template<
class Model>
338 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
372 template<
class Model>
376 eq_fields_->mark_input_times( *(Model::time_) );
378 std::stringstream ss;
386 for (
unsigned int sbi = 0; sbi <
eq_data_->n_substances(); sbi++)
393 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
395 Model::balance_->calculate_instant(
eq_data_->subst_idx_[sbi],
eq_data_->ls[sbi]->get_solution());
405 template<
class Model>
409 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
412 eq_data_->ls[i]->start_allocation();
417 eq_data_->ls_dt[i]->start_allocation();
419 VecZeroEntries(
eq_data_->ret_vec[i]);
425 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
427 VecAssemblyBegin(
eq_data_->ret_vec[i]);
428 VecAssemblyEnd(
eq_data_->ret_vec[i]);
436 template<
class Model>
441 Model::time_->next_time();
442 Model::time_->view(
"TDG");
451 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
453 eq_data_->ls_dt[i]->start_add_assembly();
454 eq_data_->ls_dt[i]->mat_zero_entries();
455 VecZeroEntries(
eq_data_->ret_vec[i]);
458 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
460 eq_data_->ls_dt[i]->finish_assembly();
461 VecAssemblyBegin(
eq_data_->ret_vec[i]);
462 VecAssemblyEnd(
eq_data_->ret_vec[i]);
468 MatConvert(*(
eq_data_->ls_dt[i]->get_matrix() ), MATSAME, MAT_INITIAL_MATRIX, &
mass_matrix[i]);
482 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
484 eq_data_->ls[i]->start_add_assembly();
485 eq_data_->ls[i]->mat_zero_entries();
488 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
504 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
506 eq_data_->ls[i]->start_add_assembly();
507 eq_data_->ls[i]->rhs_zero_entries();
511 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
515 if (
rhs[i] ==
nullptr) VecDuplicate(*(
eq_data_->ls[i]->get_rhs() ), &
rhs[i]);
539 for (
unsigned int i=0; i<
eq_data_->n_substances(); i++)
542 MatAXPY(m, 1./Model::time_->dt(),
mass_matrix[i], SUBSET_NONZERO_PATTERN);
543 eq_data_->ls[i]->set_matrix(m, DIFFERENT_NONZERO_PATTERN);
545 VecDuplicate(
rhs[i], &w);
546 VecWAXPY(w, 1./Model::time_->dt(),
mass_vec[i],
rhs[i]);
565 template<
class Model>
569 for (
auto cell :
eq_data_->dh_->own_range() )
571 LocDofVec loc_dof_indices = cell.get_loc_dof_indices();
572 unsigned int n_dofs=loc_dof_indices.n_rows;
577 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
579 eq_data_->conc_fe[sbi]->vec().set(dof_p0, 0);
581 for (
unsigned int j=0; j<n_dofs; ++j)
582 eq_data_->conc_fe[sbi]->vec().add( dof_p0,
eq_data_->ls[sbi]->get_solution_array()[loc_dof_indices[j]] );
584 eq_data_->conc_fe[sbi]->vec().set( dof_p0, max(
eq_data_->conc_fe[sbi]->vec().get(dof_p0)/n_dofs, 0.) );
592 template<
class Model>
605 Model::output_data();
608 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
609 Model::balance_->calculate_instant(
eq_data_->subst_idx_[sbi],
eq_data_->ls[sbi]->get_solution());
610 Model::balance_->output();
617 template<
class Model>
620 if (Model::balance_->cumulative())
622 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
624 Model::balance_->calculate_cumulative(
eq_data_->subst_idx_[sbi],
eq_data_->ls[sbi]->get_solution());
638 template<
class Model>
641 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
642 eq_data_->ls[sbi]->start_allocation();
645 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
646 eq_data_->ls[sbi]->start_add_assembly();
649 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); sbi++)
651 eq_data_->ls[sbi]->finish_assembly();
657 template<
class Model>
660 el_4_loc = Model::mesh_->get_el_4_loc();
661 el_ds = Model::mesh_->get_el_ds();
665 template<
class Model>
668 if (solution_changed)
670 for (
auto cell :
eq_data_->dh_->own_range() )
672 LocDofVec loc_dof_indices = cell.get_loc_dof_indices();
673 unsigned int n_dofs=loc_dof_indices.n_rows;
678 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
680 double old_average = 0;
681 for (
unsigned int j=0; j<n_dofs; ++j)
682 old_average +=
eq_data_->ls[sbi]->get_solution_array()[loc_dof_indices[j]];
683 old_average /= n_dofs;
685 for (
unsigned int j=0; j<n_dofs; ++j)
686 eq_data_->ls[sbi]->get_solution_array()[loc_dof_indices[j]]
687 +=
eq_data_->conc_fe[sbi]->vec().get(dof_p0) - old_average;
692 for (
unsigned int sbi=0; sbi<
eq_data_->n_substances(); ++sbi)
696 template<
class Model>
699 return Model::mesh_->get_row_4_el();
Input::Record input_rec
Record with input specification.
GenericAssembly< SourcesAssemblyDim > * sources_assembly_
MultiField< 3, FieldValue< 3 >::Scalar > dg_penalty
Penalty enforcing inter-element continuity of solution (for each substance).
static auto subdomain(Mesh &mesh) -> IndexField
void get_par_info(LongIdx *&el_4_loc, Distribution *&el_ds)
unsigned int n_nodes() const
arma::Col< IntIdx > LocDofVec
std::shared_ptr< EvalPoints > eval_points() const
Geter to EvalPoints object.
double elem_anisotropy(ElementAccessor< 3 > e) const
Compute and return anisotropy of given element.
static constexpr Mask in_main_matrix
A field is part of main "stiffness matrix" of the equation.
Solver based on the original PETSc solver using MPIAIJ matrix and succesive Schur complement construc...
Transport with dispersion implemented using discontinuous Galerkin method.
GenericAssembly< StiffnessAssemblyDim > * stiffness_assembly_
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
void set_from_input(const Input::Record in_rec) override
GenericAssembly< MassAssemblyDim > * mass_assembly_
general assembly objects, hold assembly objects of appropriate dimension
vector< VectorMPI > output_vec
Array for storing the output solution data.
Field< 3, FieldValue< 3 >::Scalar > region_id
void update_solution() override
Computes the solution in one time instant.
Fields computed from the mesh data.
void set_initial_condition()
Calculates the dispersivity (diffusivity) tensor from the velocity field.
Cell accessor allow iterate over DOF handler cells.
Class FEValues calculates finite element data on the actual cells such as shape function values...
void chkerr(unsigned int ierr)
Replacement of new/delete operator in the spirit of xmalloc.
std::shared_ptr< EqFields > eq_fields_
Fields for model parameters.
LocDofVec get_loc_dof_indices() const
Returns the local indices of dofs associated to the cell on the local process.
Discontinuous Galerkin method for equation of transport with dispersion.
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
ElementAccessor< 3 > element() const
Returns iterator to the element of the side.
vector< double > ret_sources_prev
NodeAccessor< 3 > node(unsigned int ni) const
std::vector< Mat > mass_matrix
The mass matrix.
void calculate_cumulative_balance()
static constexpr bool value
TransportDG(Mesh &init_mesh, const Input::Record in_rec)
Constructor.
void initialize() override
void output_data()
Postprocesses the solution and writes to output file.
unsigned int dim() const
Returns dimension of the side, that is dimension of the element minus one.
void compute_p0_interpolation()
Compute P0 interpolation of the solution (used in reaction term).
static constexpr Mask in_time_term
A field is part of time term of the equation.
FieldCommon & input_default(const string &input_default)
Definitions of basic Lagrangean finite elements with polynomial shape functions.
static constexpr Mask equation_external_output
Match an output field, that can be also copy of other field.
GenericAssembly< BdrConditionAssemblyDim > * bdr_cond_assembly_
static auto region_id(Mesh &mesh) -> IndexField
#define START_TIMER(tag)
Starts a timer with specified tag.
std::vector< Vec > rhs
Vector of right hand side.
static constexpr Mask in_rhs
A field is part of the right hand side of the equation.
Field< 3, FieldValue< 3 >::Scalar > subdomain
GenericAssembly< InitConditionAssemblyDim > * init_cond_assembly_
void set_DG_parameters_boundary(Side side, const int K_size, const std::vector< arma::mat33 > &K, const double flux, const arma::vec3 &normal_vector, const double alpha, double &gamma)
Sets up parameters of the DG method on a given boundary edge.
NodeAccessor< 3 > node(unsigned int i) const
Returns node for given local index i on the side.
Discontinuous Galerkin method for equation of transport with dispersion.
std::vector< Mat > stiffness_matrix
The stiffness matrix.
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
FieldCommon & description(const string &description)
bool allocation_done
Indicates whether matrices have been preallocated.
std::shared_ptr< EqData > eq_data_
Data for model parameters.
static const Input::Type::Record & get_input_type()
Declare input record type for the equation TransportDG.
Discontinuous Galerkin method for equation of transport with dispersion.
void update_after_reactions(bool solution_changed)
vector< double > ret_sources
Temporary values of increments due to retardation (e.g. sorption)
Generic class of assemblation.
MultiField< 3, FieldValue< 3 >::Scalar > fracture_sigma
Transition parameter for diffusive transfer on fractures (for each substance).
std::shared_ptr< Balance > balance() const
Access to balance object of Model.
Definitions of particular quadrature rules on simplices.
#define WarningOut()
Macro defining 'warning' record of log.
FieldCommon & name(const string &name)
#define END_TIMER(tag)
Ends a timer with specified tag.
Discontinuous Galerkin method for equation of transport with dispersion.
static const Input::Type::Record & get_input_type()
std::vector< Vec > mass_vec
Mass from previous time instant (necessary when coefficients of mass matrix change in time)...
FieldCommon & flags(FieldFlag::Flags::Mask mask)
~TransportDG() override
Destructor.
static UnitSI & dimensionless()
Returns dimensionless unit.
static bool print_message_table(ostream &stream, std::string equation_name)
Definitions of Raviart-Thomas finite elements.
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
void zero_time_step() override
Initialize solution in the zero time.
unsigned int n_nodes() const
Returns number of nodes of the side.
EquationOutput output_fields