71 ConvectionTransport::get_input_type().size();
73 const
IT::Record &ConvectionTransport::get_input_type()
84 "Specification of output fields and output times.")
92 .
description(
"Boundary condition for concentration of substances.")
97 .
description(
"Initial values for concentration of substances.")
113 .
description(
"Subdomain ids of the domain decomposition.");
121 : q_(
QGauss::make_array(0))
160 is_mass_diag_changed(false),
161 sources_corr(nullptr),
175 dh_ = make_shared<DOFHandlerMultiDim>(init_mesh);
176 shared_ptr<DiscreteSpace> ds = make_shared<EqualOrderDiscreteSpace>( &init_mesh, fe);
177 dh_->distribute_dofs(ds);
205 auto output_field_ptr = create_field_fe< 3, FieldValue<3>::Scalar >(
dh_);
207 vconc[sbi] = output_field_ptr->get_data_vec().petsc_vec();
208 conc[sbi] = &(output_field_ptr->get_data_vec().data()[0]);
302 LongIdx index = dh_cell.local_idx();
315 unsigned int sbi, n_subst;
319 tm_diag =
new double*[n_subst];
321 for (sbi = 0; sbi < n_subst; sbi++) {
327 conc =
new double*[n_subst];
328 vconc =
new Vec[n_subst];
344 vpconc =
new Vec[n_subst];
351 for (sbi = 0; sbi < n_subst; sbi++) {
356 VecZeroEntries(
vpconc[sbi]);
400 ASSERT_DBG(dh_cell.get_loc_dof_indices().size() == 1);
401 IntIdx local_p0_dof = dh_cell.get_loc_dof_indices()[0];
402 LongIdx glob_p0_dof =
dh_->get_local_to_global_map()[local_p0_dof];
404 for(
DHCellSide dh_side: dh_cell.side_range()) {
405 if (dh_side.side().is_boundary()) {
409 double aij = -(flux / elm.
measure() );
415 VecSetValue(
bcvcorr[sbi], glob_p0_dof, value * aij, ADD_VALUES);
420 {local_p0_dof}, {0.0}, flux*
value);
424 VecSetValue(
bcvcorr[sbi], glob_p0_dof, 0, ADD_VALUES);
428 {local_p0_dof}, {flux}, 0.0);
451 double csection, source, diag;
468 ASSERT_DBG(dh_cell.get_loc_dof_indices().size() == 1);
469 IntIdx local_p0_dof = dh_cell.get_loc_dof_indices()[0];
485 diag = src_sigma * csection;
486 tm_diag[sbi][local_p0_dof] = - diag;
489 max_cfl = std::max(max_cfl, fabs(diag));
492 {- src_sigma * elm.
measure() * csection},
513 std::stringstream ss;
541 bool cfl_changed =
false;
549 DebugOut() <<
"CFL changed - flow.\n";
556 DebugOut() <<
"CFL changed - mass matrix.\n";
566 DebugOut() <<
"CFL changed - source.\n";
574 VecCreateMPI(PETSC_COMM_WORLD,
el_ds->
lsize(),PETSC_DETERMINE, &cfl);
627 DebugOut() <<
"SRC - rescale dt.\n";
661 for (
unsigned int sbi = 0; sbi <
n_substances(); sbi++) {
735 ASSERT_DBG(dh_cell.get_loc_dof_indices().size() == 1);
736 IntIdx local_p0_dof = dh_cell.get_loc_dof_indices()[0];
743 balance_->add_mass_values(
subst_idx[sbi], dh_cell, {local_p0_dof}, {csection*por_m*elm.measure()}, 0);
745 VecSetValue(
mass_diag,
dh_->get_local_to_global_map()[local_p0_dof], csection*por_m, INSERT_VALUES);
772 double flux, flux2, edg_flux;
776 unsigned int loc_el = 0;
778 new_i =
row_4_el[ dh_cell.elm_idx() ];
780 for(
DHCellSide cell_side : dh_cell.side_range() ) {
782 if (! cell_side.side().is_boundary()) {
787 if ( flux2 > 0) edg_flux+= flux2;
790 if (edge_side != cell_side) {
791 j = edge_side.element().idx();
796 if ( flux2 > 0.0 && flux <0.0)
797 aij = -(flux * flux2 / ( edg_flux * dh_cell.elm().measure() ) );
799 MatSetValue(
tm, new_i, new_j, aij, INSERT_VALUES);
803 aii -= (flux / dh_cell.elm().measure() );
806 for(
DHCellSide neighb_side : dh_cell.neighb_sides() )
808 ASSERT( neighb_side.elem_idx() != dh_cell.elm_idx() ).error(
"Elm. same\n");
809 new_j =
row_4_el[ neighb_side.elem_idx() ];
814 if (flux > 0.0) aij = flux / dh_cell.elm().measure();
816 MatSetValue(
tm, new_i, new_j, aij, INSERT_VALUES);
821 aii -= (-flux) / dh_cell.elm().measure();
822 aij = (-flux) / neighb_side.element().measure();
824 MatSetValue(
tm, new_j, new_i, aij, INSERT_VALUES);
827 MatSetValue(
tm, new_i, new_i, aii, INSERT_VALUES);
833 MatAssemblyBegin(
tm, MAT_FINAL_ASSEMBLY);
834 MatAssemblyEnd(
tm, MAT_FINAL_ASSEMBLY);
849 el_distribution_out = this->
el_ds;
883 if (cell_side.
dim()==3)
return calculate_side_flux<3>(cell_side);
884 else if (cell_side.
dim()==2)
return calculate_side_flux<2>(cell_side);
885 else return calculate_side_flux<1>(cell_side);
888 template<
unsigned int dim>
891 ASSERT_EQ(cell_side.
dim(), dim).error(
"Element dimension mismatch!");
void output_type(OutputTime::DiscreteSpace rt)
const Element * element() const
static auto subdomain(Mesh &mesh) -> IndexField
Quadrature & q(unsigned int dim)
bool is_mass_diag_changed
Flag indicates that porosity or cross_section changed during last time.
Transformed quadrature weight for cell sides.
RegionSet get_region_set(const std::string &set_name) const
void update_solution() override
double end_time() const
End time.
LongIdx * get_row_4_el() const
double transport_matrix_time
Field< 3, FieldValue< 3 >::VectorFixed > flow_flux
Flow flux, can be result of water flow model.
double calculate_side_flux(const DHCellSide &cell)
Calculate flux on side of given element specified by dimension.
unsigned int dim() const
Return dimension of element appropriate to the side.
const std::vector< std::string > & names()
QGauss::array q_
Quadratures used in assembling methods.
void alloc_transport_vectors()
unsigned int n_substances() override
Returns number of transported substances.
void output(TimeStep step)
double fix_dt_until_mark()
Fixing time step until fixed time mark.
MultiField< 3, FieldValue< 3 >::Scalar > conc_mobile
Calculated concentrations in the mobile zone.
void create_mass_matrix()
void next_time()
Proceed to the next time according to current estimated time step.
void initialize() override
std::shared_ptr< OutputTime > output_stream_
TimeMark::Type target_mark_type
TimeMark type for time marks denoting end of every time interval where transport matrix remains const...
void set_initial_condition()
Field< 3, FieldValue< 3 >::Scalar > region_id
double transport_bc_time
Time of the last update of the boundary condition terms.
MultiField< 3, FieldValue< 3 >::Scalar > sources_density
Concentration sources - density of substance source, only positive part is used.
void set_boundary_conditions()
Fields computed from the mesh data.
EquationOutput output_fields
Fields indended for output, i.e. all input fields plus those representing solution.
Cell accessor allow iterate over DOF handler cells.
Class FEValues calculates finite element data on the actual cells such as shape function values...
MultiField< 3, FieldValue< 3 >::Scalar > sources_conc
BCMultiField< 3, FieldValue< 3 >::Scalar > bc_conc
void chkerr(unsigned int ierr)
Replacement of new/delete operator in the spirit of xmalloc.
double side_flux(const DHCellSide &cell_side)
Wrapper of following method, call side_flux with correct template parameter.
const RegionDB & region_db() const
void set_balance_object(std::shared_ptr< Balance > balance) override
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
double ** conc
Concentrations for phase, substance, element.
const TimeStep & step(int index=-1) const
virtual ~ConvectionTransport()
static Input::Type::Abstract & get_input_type()
Common specification of the input record for secondary equations.
MultiField< 3, FieldValue< 3 >::Scalar > init_conc
Initial concentrations.
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
void zero_time_step() override
Side side() const
Return Side of given cell and side_idx.
void reinit(const ElementAccessor< spacedim > &cell)
Update cell-dependent data (gradients, Jacobians etc.)
static TimeMarks & marks()
Basic time management class.
virtual ElementAccessor< 3 > element_accessor(unsigned int idx) const
Create and return ElementAccessor to element of given idx.
const Input::Record input_rec
Record with input specification.
Base class for quadrature rules on simplices in arbitrary dimensions.
static constexpr bool value
Symmetric Gauss-Legendre quadrature formulae on simplices.
Field< 3, FieldValue< 3 >::Scalar > subdomain
const string _equation_name
arma::vec::fixed< spacedim > centre() const
Computes the barycenter.
Discontinuous Lagrangean finite element on dim dimensional simplex.
Transformed quadrature points.
static constexpr Mask equation_result
Match result fields. These are never given by input or copy of input.
RangeConvert< DHEdgeSide, DHCellSide > edge_sides() const
Returns range of all sides looped over common Edge.
FieldCommon & input_default(const string &input_default)
TimeMark::Type equation_fixed_mark_type() const
MultiField< 3, FieldValue< 3 >::Scalar > sources_sigma
Concentration sources - Robin type, in_flux = sources_sigma * (sources_conc - mobile_conc) ...
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.
ElementAccessor< 3 > element() const
static auto region_id(Mesh &mesh) -> IndexField
ConvectionTransport(Mesh &init_mesh, const Input::Record in_rec)
void initialize(Quadrature &_quadrature, FiniteElement< DIM > &_fe, UpdateFlags _flags)
Initialize structures and calculates cell-independent data.
bool is_changed_dt() const
#define START_TIMER(tag)
Starts a timer with specified tag.
SubstanceList substances_
Transported substances.
LongIdx * get_row_4_el() override
Return global array of order of elements within parallel vector.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
FEValues< 3 > & fe_values(unsigned int dim)
double ** get_concentration_matrix() override
Getter for array of concentrations per element.
Field< 3, FieldValue< 3 >::Scalar > porosity
Mobile porosity - usually saturated water content in the case of unsaturated flow model...
std::shared_ptr< Balance > balance_
object for calculation and writing the mass balance to file.
std::shared_ptr< DOFHandlerMultiDim > dh_
double measure() const
Computes the measure of the element.
vector< unsigned int > subst_idx
List of indices used to call balance methods for a set of quantities.
Shape function gradients.
Distribution * get_el_ds() const
std::shared_ptr< Balance > balance() const
FEValues< 3 > fe_values_[3]
FESideValues objects for side flux calculating.
Field< 3, FieldValue< 3 >::Scalar > water_content
Water content - result of unsaturated water flow model or porosity.
Vec * vconc
Concentration vectors for mobile phase.
void mark_input_times(const TimeGovernor &tg)
TimeMark add(const TimeMark &mark)
void create_transport_matrix_mpi()
Support classes for parallel programing.
void alloc_transport_structs_mpi()
int set_upper_constraint(double upper, std::string message)
Sets upper constraint for the next time step estimating.
int LongIdx
Define type that represents indices of large arrays (elements, nodes, dofs etc.)
FieldCommon & description(const string &description)
bool is_convection_matrix_scaled
void set_input_list(Input::Array input_list, const TimeGovernor &tg)
virtual unsigned int n_elements(bool boundary=false) const
Returns count of boundary or bulk elements.
void initialize(std::shared_ptr< OutputTime > stream, Mesh *mesh, Input::Record in_rec, const TimeGovernor &tg)
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
void set_components(const std::vector< string > &names)
void compute_concentration_sources()
Assembles concentration sources for each substance. note: the source of concentration is multiplied b...
bool evaluate_time_constraint(double &time_constraint) override
FiniteElement< 1 > * fe1_
Vec vcfl_flow_
Parallel vector for flow contribution to CFL condition.
void set_target_time(double target_time) override
virtual void output_data() override
Write computed fields.
bool set_time(const TimeStep &time, LimitSide limit_side)
void get_par_info(LongIdx *&el_4_loc, Distribution *&el_ds) override
Return array of indices of local elements and parallel distribution of elements.
Distributed sparse graphs, partitioning.
Vec vcfl_source_
Parallel vector for source term contribution to CFL condition.
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
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.
#define OLD_ASSERT_EQUAL(a, b)
double ** cumulative_corr
void set_mesh(const Mesh &mesh)
Class used for marking specified times at which some events occur.
FETransportObjects feo_
Finite element objects.
FieldCommon & flags(FieldFlag::Flags::Mask mask)
double JxW(const unsigned int point_no)
Return the product of Jacobian determinant and the quadrature weight at given quadrature point...
Field< 3, FieldValue< 3 >::Scalar > cross_section
Pointer to DarcyFlow field cross_section.
Class for representation SI units of Fields.
#define MPI_Barrier(comm)
static UnitSI & dimensionless()
Returns dimensionless unit.
#define DebugOut()
Macro defining 'debug' record of log.
static bool print_message_table(ostream &stream, std::string equation_name)
Other possible transformation of coordinates:
FiniteElement< 3 > * fe3_
FiniteElement< 0 > * fe0_
Finite elements for the solution of the advection-diffusion equation.
LongIdx * get_el_4_loc() const
Implementation of range helper class.
Side accessor allows to iterate over sides of DOF handler cell.
#define FLOW123D_FORCE_LINK_IN_CHILD(x)
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual)
void make_transport_partitioning()
double cfl_max_step
Time step constraint coming from CFL condition.
FiniteElement< 2 > * fe2_
unsigned int lsize(int proc) const
get local size
arma::vec::fixed< spacedim > normal_vector(unsigned int point_no)
Returns the normal vector to a side at given quadrature point.
arma::vec3 centre() const
Side centre.