1 #include <boost/foreach.hpp>
24 using namespace Input::Type;
29 "Linear isotherm runs the concentration exchange between liquid and solid.")
31 "Langmuir isotherm runs the concentration exchange between liquid and solid.")
33 "Freundlich isotherm runs the concentration exchange between liquid and solid.");
38 =
Record(
"Adsorption",
"AUXILIARY RECORD. Should not be directly part of the input tree.")
40 "Names of the substances that take part in the adsorption model.")
42 "Density of the solvent.")
44 "Number of equidistant substeps, molar mass and isotherm intersections")
46 "Specifies molar masses of all the adsorbing species.")
48 "Specifies solubility limits of all the adsorbing species.")
50 "Specifies highest aqueous concentration in interpolation table.")
51 .
declare_key(
"input_fields",
Array(EqData(
"").input_data_set_.make_field_descriptor_type(
"Sorption")), Default::obligatory(),
52 "Containes region specific data necessary to construct isotherms.")
53 .declare_key(
"reaction_liquid",
ReactionTerm::input_type, Default::optional(),
"Reaction model following the sorption in the liquid.")
54 .declare_key(
"reaction_solid",
ReactionTerm::input_type, Default::optional(),
"Reaction model following the sorption in the solid.");
59 ADD_FIELD(rock_density,
"Rock matrix density.",
"0.0");
60 rock_density.units(
UnitSI().kg().m(-3) );
62 ADD_FIELD(sorption_type,
"Considered adsorption is described by selected isotherm.");
63 sorption_type.input_selection(&sorption_type_selection);
66 ADD_FIELD(isotherm_mult,
"Multiplication parameters (k, omega) in either Langmuir c_s = omega * (alpha*c_a)/(1- alpha*c_a) or in linear c_s = k * c_a isothermal description.",
"1.0");
67 isotherm_mult.units(
UnitSI().mol().kg(-1) );
69 ADD_FIELD(isotherm_other,
"Second parameters (alpha, ...) defining isotherm c_s = omega * (alpha*c_a)/(1- alpha*c_a).",
"1.0");
72 ADD_FIELD(init_conc_solid,
"Initial solid concentration of substances."
73 " Vector, one value for every substance.",
"0");
74 init_conc_solid.units(
UnitSI().mol().kg(-1) );
76 input_data_set_ += *
this;
85 output_fields += *
this;
86 output_fields += conc_solid.name(output_field_name).units(
UnitSI().kg().m(-3) );
94 case SorptionRecord::mobile:
95 rec =
IT::Record(
"SorptionMobile",
"Adsorption model in the mobile zone, following the dual porosity model.")
98 .
declare_key(
"output_fields",
IT::Array(make_output_selection(
"conc_solid",
"SorptionMobile_Output")),
99 IT::Default(
"conc_solid"),
"List of fields to write to output stream.");
101 case SorptionRecord::immobile:
102 rec =
IT::Record(
"SorptionImmobile",
"Adsorption model in the immobile zone, following the dual porosity model.")
105 .
declare_key(
"output_fields",
IT::Array(make_output_selection(
"conc_immobile_solid",
"SorptionImmobile_Output")),
106 IT::Default(
"conc_immobile_solid"),
"List of fields to write to output stream.");
110 rec =
IT::Record(
"Sorption",
"Adsorption model in the reaction term of transport.")
113 .
declare_key(
"output_fields",
IT::Array(make_output_selection(
"conc_solid",
"Sorption_Output")),
114 IT::Default(
"conc_solid"),
"List of fields to write to output stream.");
140 for (
unsigned int sbi = 0; sbi <
names_.size(); sbi++)
164 xprintf(
UsrErr,
"Sorption model cannot have another descendant sorption model.\n");
167 xprintf(
UsrErr,
"Sorption model cannot have descendant dual porosity model.\n");
171 xprintf(
UsrErr,
"Semchem chemistry model is not supported at current time.\n");
174 xprintf(
UsrErr,
"Unknown reactions type in Sorption model.\n");
191 xprintf(
UsrErr,
"Sorption model cannot have another descendant sorption model.\n");
194 xprintf(
UsrErr,
"Sorption model cannot have descendant dual porosity model.\n");
198 xprintf(
UsrErr,
"Semchem chemistry model is not supported at current time.\n");
201 xprintf(
UsrErr,
"Unknown reactions type in Sorption model.\n");
212 ASSERT(
time_ !=
nullptr,
"Time governor has not been set yet.\n");
222 for(
unsigned int i_reg = 0; i_reg < nr_of_regions; i_reg++)
225 for(
unsigned int i_subst = 0; i_subst <
n_substances_; i_subst++)
234 for (
unsigned int sbi = 0; sbi <
names_.size(); sbi++)
267 unsigned int k, global_idx, i_subst = 0;
271 for(; spec_iter != substances_array.
end(); ++spec_iter, i_subst++)
275 for(k = 0; k <
names_.size(); k++)
277 if (*spec_iter ==
names_[k])
286 xprintf(
UsrErr,
"Wrong name of %d-th substance - not found in global set of transported substances.\n",
311 xprintf(
UsrErr,
"Number of 'substeps'=%d in isotherm interpolation table must be be >0.\n",
322 else xprintf(
UsrErr,
"Number of molar masses %d has to match number of adsorbing species %d.\n",
331 xprintf(
UsrErr,
"Number of given solubility limits %d has to match number of adsorbing species %d.\n",
340 if( interp_table_limits )
345 xprintf(
UsrErr,
"Number of given table limits %d has to match number of adsorbing species %d.\n",
356 ASSERT(
n_substances_ > 0,
"Number of substances is wrong, they might have not been set yet.\n");
372 for (
unsigned int sbi=0; sbi<
names_.size(); sbi++)
375 std::shared_ptr<FieldElementwise<3, FieldValue<3>::Scalar> > output_field_ptr(
387 ASSERT(
time_ !=
nullptr,
"Time governor has not been set yet.\n");
455 for(
unsigned int i_subst = 0; i_subst <
n_substances_; i_subst++)
466 int reg_idx = elem->region().bulk_idx();
467 unsigned int i_subst, subst_id;
473 if (isotherms_vec[0].is_precomputed())
495 return concentrations;
509 for (sbi = 0; sbi < n_subst; sbi++) {
530 for (sbi = 0; sbi <
names_.size(); sbi++) {
void output_type(OutputTime::DiscreteSpace rt)
unsigned int size() const
get global size
void set_input_list(Input::Array input_list)
virtual void zero_time_step()
void allocate_output_mpi(void)
Allocates petsc vectors, prepares them for output and creates vector scatter.
void set_limit_side(LimitSide side)
MultiField< 3, FieldValue< 3 >::Scalar > conc_solid
Calculated sorbed concentrations, for output only.
OutputTime * output_stream_
Pointer to a transport output stream.
void init(const vector< string > &names)
ReactionTerm * reaction_liquid
std::vector< std::vector< Isotherm > > isotherms
virtual ~SorptionBase(void)
void initialize_substance_ids()
Reads names of substances from input and creates indexing to global vector of substance,.
double ** concentration_matrix_
unsigned int bulk_size() const
virtual void initialize()
Initialize fields.
EqData(const string &output_field_name)
Collect all fields.
Input::Type::Selection output_selection
Vec * vconc_solid_out
PETSC sorbed concentration vector output (gathered - sequential)
double ** compute_reaction(double **concentrations, int loc_el)
vector< string > names_
Names belonging to substances.
void zero_time_step() override
static Input::Type::Record input_type
RegionSet get_region_set(const string &set_name) const
static Input::Type::Record input_type
int * row_4_el_
Indices of rows belonging to elements.
std::vector< double > molar_masses_
const RegionDB & region_db() const
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
static Input::Type::Selection sorption_type_selection
Field< 3, FieldValue< 3 >::Vector > init_conc_solid
Initial sorbed concentrations.
std::vector< double > table_limit_
#define ADD_FIELD(name,...)
std::vector< unsigned int > substance_global_idx_
Mapping from local indexing of substances to global.
void initialize_fields()
Initializes field sets.
static Input::Type::AbstractRecord input_type
unsigned int n_elements() const
static Input::Type::Record input_type
Distribution * distribution_
Pointer to reference to distribution of elements between processors.
void output_data(void) override
Output method.
static constexpr Mask input_copy
A field that is input of its equation and cna not read from input, thus muzt be set by copy...
Vec * vconc_solid
PETSC sorbed concentration vector (parallel).
FieldSet output_fields
Fields indended for output, i.e. all input fields plus those representing solution.
void initialize_from_input()
Initializes private members of sorption from the input record.
std::vector< double > solubility_vec_
unsigned int n_interpolation_steps_
#define ASSERT_LESS(a, b)
#define START_TIMER(tag)
Starts a timer with specified tag.
virtual void isotherm_reinit(std::vector< Isotherm > &isotherms, const ElementAccessor< 3 > &elm)=0
Reinitializes the isotherm.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
ReactionTerm * reaction_solid
static Input::Type::Record input_type
static Input::Type::Record record_factory(SorptionRecord::Type)
Creates the input record for different cases of sorption model (simple or in dual porosity)...
double ** conc_solid_out
sorbed concentration array output (gathered - sequential)
void output_vector_gather(void) override
Gathers all the parallel vectors to enable them to be output.
Input::Array output_array
void update_solution(void) override
Updates the solution.
static Input::Type::AbstractRecord input_type
void * xmalloc(size_t size)
Memory allocation with checking.
void set_time(const TimeGovernor &time)
virtual void set_time_governor(TimeGovernor &time)
Support classes for parallel programing.
void set_n_components(unsigned int n_comp)
virtual void update_solution()
void output(OutputTime *stream)
Input::Record input_record_
int * el_4_loc_
Indices of elements belonging to local dofs.
void add_admissible_field_names(const Input::Array &in_array, const Input::Type::Selection &in_sel)
Registers names of output fields that can be written using this stream.
void set_initial_condition()
Reads and sets initial condition for concentration in solid.
bool is_constant(Region reg) const
ReactionTerm & names(const std::vector< string > &names)
Sets the names of substances considered in transport.
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
#define END_TIMER(tag)
Ends a timer with specified tag.
arma::vec::fixed< spacedim > centre() const
void set_mesh(const Mesh &mesh)
VecScatter vconc_out_scatter
Output vector scatter.
unsigned int n_substances_
Class for representation SI units of Fields.
#define MPI_Barrier(comm)
EqData * data_
Pointer to equation data. The object is constructed in descendants.
static UnitSI & dimensionless()
Returns dimensionless unit.
ReactionTerm & concentration_matrix(double **concentration, Distribution *conc_distr, int *el_4_loc, int *row_4_el)
void set_mesh(const Mesh &mesh) override
ElementVector element
Vector of elements of the mesh.
FieldSet input_data_set_
Input data set - fields in this set are read from the input file.
unsigned int lsize(int proc) const
get local size
void initialize() override
Prepares the object to usage.