65 namespace IT = Input::Type;
77 EqData().output_fields.make_output_field_selection(
"ConvectionTransport_Output")
134 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
146 if (it->val<
bool>(
"balance_on"))
152 balance_->allocate(el_ds->lsize(), 1);
198 for (sbi = 0; sbi <
n_subst_; sbi++) {
232 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
233 conc[sbi][index] = value(sbi);
254 for (sbi = 0; sbi < n_subst; sbi++) {
261 conc = (
double**)
xmalloc(n_subst *
sizeof(
double*));
264 for (sbi = 0; sbi < n_subst; sbi++) {
278 int sbi, n_subst, rank, np;
291 VecCreateMPIWithArray(PETSC_COMM_WORLD,1,
el_ds->
lsize(), PETSC_DECIDE,
294 for (sbi = 0; sbi < n_subst; sbi++) {
301 VecZeroEntries(
vconc[sbi]);
302 VecZeroEntries(
vpconc[sbi]);
309 VecZeroEntries(
out_conc[sbi].get_data_petsc());
325 unsigned int sbi, loc_el, loc_b = 0;
333 for (loc_el = 0; loc_el <
el_ds->
lsize(); loc_el++) {
335 if (elm->boundary_idx_ != NULL) {
341 Boundary *b = elm->side(si)->cond();
345 double aij = -(flux / (elm->measure() * csection * por_m) );
349 VecSetValue(
bcvcorr[sbi], new_i, value[sbi] * aij, ADD_VALUES);
391 double conc_diff, csection, por_m;
405 for (loc_el = 0; loc_el <
el_ds->
lsize(); loc_el++)
427 balance_->start_source_assembly(sbi);
430 for (loc_el = 0; loc_el <
el_ds->
lsize(); loc_el++)
442 balance_->finish_source_assembly(sbi);
450 for (loc_el = 0; loc_el <
el_ds->
lsize(); loc_el++)
453 if ( conc_diff > 0.0)
483 for (
unsigned int sbi=0; sbi<
n_subst_; ++sbi)
557 for (
unsigned int sbi = 0; sbi <
n_subst_; sbi++) {
567 END_TIMER(
"compute_concentration_sources");
608 int s, j, np, rank, new_j, new_i;
609 double max_sum, aij, aii;
616 double flux, flux2, edg_flux;
622 for(
int s=0; s < edg.
n_sides; s++) {
624 if ( flux > 0) edge_flow[i]+= flux;
634 for (
unsigned int loc_el = 0; loc_el <
el_ds->
lsize(); loc_el++) {
643 for (
unsigned int sbi=0; sbi<
n_subst_; ++sbi)
650 if (elm->side(si)->cond() == NULL) {
651 edg = elm->side(si)->edge();
652 edg_flux = edge_flow[ elm->side(si)->edge_idx() ];
656 if (edg->
side(s) != elm->side(si)) {
661 if ( flux2 > 0.0 && flux <0.0)
662 aij = -(flux * flux2 / ( edg_flux * elm->measure() * csection * por_m) );
664 MatSetValue(
tm, new_i, new_j, aij, INSERT_VALUES);
667 aii -= (flux / (elm->measure() * csection * por_m) );
670 aii -= (flux / (elm->measure() * csection * por_m) );
677 ASSERT( el2 != elm,
"Elm. same\n");
682 if (flux > 0.0) aij = flux / (elm->measure() * csection * por_m);
684 MatSetValue(
tm, new_i, new_j, aij, INSERT_VALUES);
689 aii -= (-flux) / (elm->measure() * csection * por_m);
690 aij = (-flux) / (el2->measure() *
694 MatSetValue(
tm, new_j, new_i, aij, INSERT_VALUES);
697 MatSetValue(
tm, new_i, new_i, aii, INSERT_VALUES);
699 if (fabs(aii) > max_sum)
712 MatAssemblyBegin(
tm, MAT_FINAL_ASSEMBLY);
713 MatAssemblyEnd(
tm, MAT_FINAL_ASSEMBLY);
735 for (sbi = 0; sbi <
n_subst_; sbi++) {
750 el_distribution_out = this->
el_ds;
770 for (
unsigned int sbi=0; sbi<
n_subst_; ++sbi)
772 VecDuplicate(
vpconc[sbi], &vpconc_diff);
773 VecGetArrayRead(
vpconc[sbi], &pconc);
774 VecGetArray(vpconc_diff, &pconc_diff);
775 for (
unsigned int loc_el=0; loc_el<
el_ds->
lsize(); ++loc_el)
778 pconc_diff[loc_el] =
sources_conc[sbi][loc_el] - pconc[loc_el];
780 pconc_diff[loc_el] = 0;
785 VecRestoreArray(vpconc_diff, &pconc_diff);
786 VecRestoreArrayRead(
vpconc[sbi], &pconc);
787 VecDestroy(&vpconc_diff);
798 for (
unsigned int sbi=0; sbi<
n_subst_; ++sbi)
800 VecDuplicate(
vconc[sbi], &vconc_diff);
801 VecGetArrayRead(
vconc[sbi], &conc);
802 VecGetArray(vconc_diff, &conc_diff);
803 for (
unsigned int loc_el=0; loc_el<
el_ds->
lsize(); ++loc_el)
806 conc_diff[loc_el] =
sources_conc[sbi][loc_el] - conc[loc_el];
808 conc_diff[loc_el] = 0;
812 balance_->calculate_source(sbi, vconc_diff);
815 VecRestoreArray(vconc_diff, &conc_diff);
816 VecRestoreArrayRead(
vconc[sbi], &conc);
817 VecDestroy(&vconc_diff);
void output_type(OutputTime::DiscreteSpace rt)
unsigned int size() const
get global size
void set_input_list(Input::Array input_list)
void compute_concentration_sources(unsigned int sbi)
void set_limit_side(LimitSide side)
std::vector< VectorSeqDouble > out_conc
double time_changed() const
void update_solution() override
double end_time() const
End time.
double transport_matrix_time
Field< 3, FieldValue< 3 >::Scalar > cross_section
Pointer to DarcyFlow field cross_section.
void id_maps(int n_ids, int *id_4_old, Distribution *&new_ds, int *&id_4_loc, int *&new_4_id)
const std::vector< std::string > & names()
void add_admissible_field_names(const Input::Array &in_array)
Registers names of output fields that can be written using this stream.
#define FOR_EDGE_SIDES(i, j)
#define FOR_ELEMENTS(_mesh_, __i)
void alloc_transport_vectors()
BCField< 3, FieldValue< 3 >::Vector > bc_conc
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 next_time()
Proceed to the next time according to current estimated time step.
TimeMark::Type target_mark_type
TimeMark type for time marks denoting end of every time interval where transport matrix remains const...
TimeMark::Type type_output()
void set_initial_condition()
void initialize(const Input::Array &in_array)
Read from input array.
void set_boundary_conditions()
void set_time(const TimeStep &time)
RegionSet get_region_set(const string &set_name) const
const MH_DofHandler * mh_dh
#define ELEMENT_FULL_ITER(_mesh_, i)
Fields computed from the mesh data.
Field< 3, FieldValue< 3 >::Vector > sources_conc
#define FOR_ELEMENT_SIDES(i, j)
bool is_current(const TimeMark::Type &mask) const
Field< 3, FieldValue< 3 >::Scalar > porosity
Mobile porosity.
const RegionDB & region_db() const
ElementAccessor< 3 > element_accessor(unsigned int idx, bool boundary=false)
double ** conc
Concentrations for phase, substance, element.
void calculate_instant_balance()
const TimeStep & step(int index=-1) const
virtual ~ConvectionTransport()
void get_par_info(int *&el_4_loc, Distribution *&el_ds)
#define ADD_FIELD(name,...)
Basic time management functionality for unsteady (and steady) solvers (class Equation).
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
Partitioning * get_part()
void zero_time_step() override
unsigned int size() const
static TimeMarks & marks()
void output_vector_gather()
Basic time management class.
Specification of transport model interface.
double estimate_dt() const
Estimate choice of next time step according to actual setting of constraints.
OutputTime * output_stream_
ConvectionTransport(Mesh &init_mesh, const Input::Record &in_rec)
void add(const TimeMark &mark)
unsigned int n_elements() const
bool is_local(unsigned int idx) const
identify local index
static OutputTime * create_output_stream(const Input::Record &in_rec)
This method delete all object instances of class OutputTime stored in output_streams vector...
static Input::Type::Selection sorption_type_selection
#define ASSERT_EQUAL(a, b)
Input::Record output_rec
Record with output specification.
TimeMark::Type equation_fixed_mark_type() const
static constexpr Mask equation_external_output
Match an output field, that can be also copy of other field.
unsigned int begin(int proc) const
get starting local index
static auto region_id(Mesh &mesh) -> IndexField
#define START_TIMER(tag)
Starts a timer with specified tag.
virtual Value::return_type const & value(const Point &p, const ElementAccessor< spacedim > &elm) const
boost::shared_ptr< Balance > balance_
(new) object for calculation and writing the mass balance to file.
void mark_input_times(TimeMark::Type mark_type)
unsigned int n_subst_
Number of transported substances.
vector< unsigned int > subst_idx
List of indices used to call balance methods for a set of quantities.
void mark_output_times(const TimeGovernor &tg)
Vec * vconc
Concentration vectors for mobile phase.
void * xmalloc(size_t size)
Memory allocation with checking.
#define INPUT_CHECK(i,...)
Debugging macros.
FieldSet output_fields
Fields indended for output, i.e. all input fields plus those representing solution.
Field< 3, FieldValue< 3 >::Integer > region_id
void create_transport_matrix_mpi()
Support classes for parallel programing.
#define MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm)
Field< 3, FieldValue< 3 >::Vector > sources_sigma
Concentration sources - Robin type, in_flux = sources_sigma * (sources_conc - mobile_conc) ...
void alloc_transport_structs_mpi()
double side_flux(const Side &side) const
temporary replacement for DofHandler accessor, flux through given side
bool is_convection_matrix_scaled
#define ELEMENT_FULL_ITER_NULL(_mesh_)
static Input::Type::Selection output_selection
void output(OutputTime *stream)
SubstanceList substances_
Transported substances.
void set_components(const std::vector< string > &names)
ElementFullIter element() const
int set_upper_constraint(double upper)
Sets upper constraint for the next time step estimating.
Field< 3, FieldValue< 3 >::Vector > sources_density
Concentration sources - density of substance source, only positive part is used.
VecScatter vconc_out_scatter
double ** sources_density
temporary arrays to store constant values of fields over time interval
arma::vec3 centre() const
void add_factory(std::shared_ptr< FactoryBase > factory)
virtual void output_data() override
Write computed fields.
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
Distributed sparse graphs, partitioning.
void set_target_time(double target_time)
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
void calculate_cumulative_balance()
FieldCommon & name(const string &name)
#define END_TIMER(tag)
Ends a timer with specified tag.
arma::vec::fixed< spacedim > centre() const
#define FOR_ELM_NEIGHS_VB(i, j)
ElementAccessor< 3 > element_accessor() const
Gets ElementAccessor of this element.
double ** cumulative_corr
void set_mesh(const Mesh &mesh)
Class used for marking specified times at which some events occur.
unsigned int n_substances() override
Returns number of trnasported substances.
FieldCommon & flags(FieldFlag::Flags::Mask mask)
unsigned int n_edges() const
double ** get_concentration_matrix()
Class for representation SI units of Fields.
#define MPI_Barrier(comm)
UnitSI & md(int exp=-1)
Method sets value of exponent for m^{-d}, where d is dimension of region.
static UnitSI & dimensionless()
Returns dimensionless unit.
SideIter side(const unsigned int i) const
Field< 3, FieldValue< 3 >::Vector > init_conc
Initial concentrations.
ElementAccessor< 3 > element_accessor()
void make_transport_partitioning()
ElementVector element
Vector of elements of the mesh.
unsigned int lsize(int proc) const
get local size