48 using namespace Input::Type;
52 =
Selection(
"DG_variant",
"Type of penalty term.")
53 .
add_value(non_symmetric,
"non-symmetric",
"non-symmetric weighted interior penalty DG method")
54 .
add_value(incomplete,
"incomplete",
"incomplete weighted interior penalty DG method")
55 .
add_value(symmetric,
"symmetric",
"symmetric weighted interior penalty DG method");
59 Selection(
"TransportDG_BC_Type",
"Types of boundary condition supported by the transport DG model (solute transport or heat transfer).")
60 .
add_value(
none,
"none",
"Homogeneous Neumann boundary condition. Zero flux")
62 "Dirichlet boundary condition."
66 .
add_value(neumann,
"neumann",
"Neumann boundary condition. Prescribe water outflow by the 'bc_flux' field.")
67 .
add_value(robin,
"robin",
"Robin boundary condition. Water outflow equal to $\\sigma (h - h^R)$. "
71 .
add_value(inflow,
"inflow",
"Prescribes the concentration in the inflow water on the inflow part of the boundary.");
75 Model::ModelEqData::get_output_selection_input_type(
"DG",
"DG solver")
76 .copy_values(EqData().make_output_field_selection(
"").close())
81 = Model::get_input_type(
"DG",
"DG solver")
83 "Linear solver for MH problem.")
86 "Variant of interior penalty discontinuous Galerkin method.")
88 "Polynomial order for finite element in DG method (order 0 is suitable if there is no diffusion/dispersion).")
89 .declare_key(
"output_fields",
Array(EqData::output_selection),
90 Default(Model::ModelEqData::default_output_field()),
91 "List of fields to write to output file.");
132 xprintf(
PrgErr,
"Unsupported polynomial order %d for finite elements in TransportDG ", fe_order);
152 dh_->distribute_dofs(*fe1_, *fe2_, *fe3_);
198 template<
class Model>
202 .
name(
"fracture_sigma")
204 "Coefficient of diffusive transfer through fractures (for each substance).")
212 "Penalty parameter influencing the discontinuity of the solution (for each substance). "
213 "Its default value 1 is sufficient in most cases. Higher value diminishes the inter-element jumps.")
221 "Boundary condition type, possible values: inflow, dirichlet, neumann, robin.")
229 .
description(
"Flux in Neumann boundary condition.")
234 .
name(
"bc_robin_sigma")
235 .
description(
"Conductivity coefficient in Robin boundary condition.")
248 template<
class Model>
257 static_assert(std::is_base_of<AdvectionDiffusionModel, Model>::value,
"");
275 data_.set_mesh(init_mesh);
288 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
296 int qsize = max(
feo->
q<0>()->size(), max(
feo->
q<1>()->size(), max(
feo->
q<2>()->size(),
feo->
q<3>()->size())));
303 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
311 for (
int sd=0; sd<max_edg_sides; sd++)
315 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
326 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
336 data_.output_field.set_up_components();
337 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
354 for (
unsigned int sbi = 0; sbi <
n_subst_; sbi++) {
370 if (it->val<
bool>(
"balance_on"))
381 max(
feo->
fe<1>()->n_dofs(), max(
feo->
fe<2>()->n_dofs(),
feo->
fe<3>()->n_dofs())));
386 template<
class Model>
391 if (feo->dh()->el_ds()->myp() == 0)
393 for (
unsigned int i=0; i<
n_subst_; i++)
395 VecDestroy(&output_vec[i]);
396 delete[] output_solution[i];
400 for (
unsigned int i=0; i<
n_subst_; i++)
404 MatDestroy(&stiffness_matrix[i]);
405 MatDestroy(&mass_matrix[i]);
407 VecDestroy(&mass_vec[i]);
411 delete[] stiffness_matrix;
412 delete[] mass_matrix;
418 delete output_stream;
422 template<
class Model>
426 VecScatter output_scatter;
428 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
431 ISCreateBlock(PETSC_COMM_SELF, ls[sbi]->size(), 1, idx, PETSC_COPY_VALUES, &is);
432 VecScatterCreate(ls[sbi]->get_solution(), is, output_vec[sbi], PETSC_NULL, &output_scatter);
433 VecScatterBegin(output_scatter, ls[sbi]->get_solution(), output_vec[sbi], INSERT_VALUES, SCATTER_FORWARD);
434 VecScatterEnd(output_scatter, ls[sbi]->get_solution(), output_vec[sbi], INSERT_VALUES, SCATTER_FORWARD);
435 VecScatterDestroy(&(output_scatter));
442 template<
class Model>
451 set_initial_condition();
452 for (
unsigned int sbi = 0; sbi <
n_subst_; sbi++)
453 ( (
LinSys_PETSC *)ls[sbi] )->set_initial_guess_nonzero();
458 balance_->units(Model::balance_units());
460 if (!allocation_done) preallocate();
462 for (
unsigned int sbi=0; sbi<
n_subst_; ++sbi)
464 balance_->calculate_mass(subst_idx[sbi], ls[sbi]->get_solution());
465 balance_->calculate_source(subst_idx[sbi], ls[sbi]->get_solution());
466 balance_->calculate_flux(subst_idx[sbi], ls[sbi]->get_solution());
471 balance_->calculate_mass(subst_idx[sbi], ls[sbi]->get_solution(), masses);
472 for (
auto reg_mass : masses)
475 sorption_sources[sbi] = mass;
483 template<
class Model>
486 for (
unsigned int i=0; i<
n_subst_; i++)
489 ls[i]->start_allocation();
490 stiffness_matrix[i] = NULL;
494 ls_dt[i]->start_allocation();
495 mass_matrix[i] = NULL;
497 assemble_stiffness_matrix();
498 assemble_mass_matrix();
500 set_boundary_conditions();
502 allocation_done =
true;
507 template<
class Model>
520 if (!allocation_done) preallocate();
525 for (
unsigned int i=0; i<
n_subst_; i++)
527 ls_dt[i]->start_add_assembly();
528 ls_dt[i]->mat_zero_entries();
530 assemble_mass_matrix();
531 for (
unsigned int i=0; i<
n_subst_; i++)
533 ls_dt[i]->finish_assembly();
536 if (mass_matrix[i] == NULL)
538 VecDuplicate(ls[i]->get_solution(), &mass_vec[i]);
539 MatMult(*(ls_dt[i]->get_matrix()), ls[i]->get_solution(), mass_vec[i]);
543 double total_mass = 0;
544 VecSum(mass_vec[i], &total_mass);
545 sorption_sources[i] -= total_mass;
549 if (stiffness_matrix[i] == NULL)
550 MatConvert(*( ls_dt[i]->get_matrix() ), MATSAME, MAT_INITIAL_MATRIX, &mass_matrix[i]);
552 MatCopy(*( ls_dt[i]->get_matrix() ), mass_matrix[i], DIFFERENT_NONZERO_PATTERN);
557 if (stiffness_matrix[0] == NULL
559 || Model::flux_changed)
563 for (
unsigned int i=0; i<
n_subst_; i++)
565 ls[i]->start_add_assembly();
566 ls[i]->mat_zero_entries();
568 assemble_stiffness_matrix();
569 for (
unsigned int i=0; i<
n_subst_; i++)
571 ls[i]->finish_assembly();
573 if (stiffness_matrix[i] == NULL)
574 MatConvert(*( ls[i]->get_matrix() ), MATSAME, MAT_INITIAL_MATRIX, &stiffness_matrix[i]);
576 MatCopy(*( ls[i]->get_matrix() ), stiffness_matrix[i], DIFFERENT_NONZERO_PATTERN);
583 || Model::flux_changed)
585 for (
unsigned int i=0; i<
n_subst_; i++)
587 ls[i]->start_add_assembly();
588 ls[i]->rhs_zero_entries();
591 set_boundary_conditions();
592 for (
unsigned int i=0; i<
n_subst_; i++)
594 ls[i]->finish_assembly();
596 VecDuplicate(*( ls[i]->get_rhs() ), &rhs[i]);
597 VecCopy(*( ls[i]->get_rhs() ), rhs[i]);
601 Model::flux_changed =
false;
622 for (
unsigned int i=0; i<
n_subst_; i++)
624 MatConvert(stiffness_matrix[i], MATSAME, MAT_INITIAL_MATRIX, &m);
625 MatAXPY(m, 1./
time_->
dt(), mass_matrix[i], SUBSET_NONZERO_PATTERN);
626 ls[i]->set_matrix(m, DIFFERENT_NONZERO_PATTERN);
628 VecDuplicate(rhs[i], &w);
629 VecWAXPY(w, 1./
time_->
dt(), mass_vec[i], rhs[i]);
637 MatMult(*(ls_dt[i]->get_matrix()), ls[i]->get_solution(), mass_vec[i]);
643 for (
unsigned int sbi=0; sbi<
n_subst_; ++sbi)
645 balance_->calculate_mass(subst_idx[sbi], ls[sbi]->get_solution());
646 balance_->calculate_source(subst_idx[sbi], ls[sbi]->get_solution());
647 balance_->calculate_flux(subst_idx[sbi], ls[sbi]->get_solution());
650 balance_->calculate_cumulative_sources(subst_idx[sbi], ls[sbi]->get_solution(),
time_->
dt());
651 balance_->calculate_cumulative_fluxes(subst_idx[sbi], ls[sbi]->get_solution(),
time_->
dt());
656 balance_->calculate_mass(subst_idx[sbi], ls[sbi]->get_solution(), masses);
657 for (
auto reg_mass : masses)
659 double total_mass = 0;
660 VecSum(mass_vec[sbi], &total_mass);
662 balance_->add_cumulative_source(subst_idx[sbi], mass-total_mass-sorption_sources[sbi]);
663 sorption_sources[sbi] = mass - total_mass;
672 template<
class Model>
679 Model::flux_changed =
true;
684 template<
class Model>
692 output_vector_gather();
694 data_.output(output_stream);
695 output_stream->write_time_frame();
704 template<
class Model>
709 balance_->start_mass_assembly(subst_idx);
710 assemble_mass_matrix<1>();
711 assemble_mass_matrix<2>();
712 assemble_mass_matrix<3>();
714 balance_->finish_mass_assembly(subst_idx);
719 template<
class Model>
template<
unsigned int dim>
723 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim>()->size();
725 PetscScalar local_mass_matrix[ndofs*ndofs];
729 for (
unsigned int i_cell=0; i_cell<feo->dh()->el_ds()->lsize(); i_cell++)
732 if (cell->dim() != dim)
continue;
734 fe_values.reinit(cell);
735 feo->dh()->get_dof_indices(cell, (
unsigned int*)&(dof_indices[0]));
738 Model::compute_mass_matrix_coefficient(fe_values.point_list(), ele_acc, mm_coef);
739 Model::compute_retardation_coefficient(fe_values.point_list(), ele_acc, ret_coef);
741 for (
unsigned int sbi=0; sbi<
n_subst_; ++sbi)
744 for (
unsigned int i=0; i<ndofs; i++)
746 for (
unsigned int j=0; j<ndofs; j++)
748 local_mass_matrix[i*ndofs+j] = 0;
749 for (
unsigned int k=0; k<qsize; k++)
750 local_mass_matrix[i*ndofs+j] += (mm_coef[k]+ret_coef[sbi][k])*fe_values.shape_value(j,k)*fe_values.shape_value(i,k)*fe_values.JxW(k);
755 local_mass_balance_vector[i] = 0;
756 for (
unsigned int k=0; k<qsize; k++)
757 local_mass_balance_vector[i] += mm_coef[k]*fe_values.shape_value(i,k)*fe_values.JxW(k);
762 balance_->add_mass_matrix_values(subst_idx[sbi], ele_acc.
region().
bulk_idx(), dof_indices, local_mass_balance_vector);
764 ls_dt[sbi]->mat_set_values(ndofs, &(dof_indices[0]), ndofs, &(dof_indices[0]), local_mass_matrix);
772 template<
class Model>
777 assemble_volume_integrals<1>();
778 assemble_volume_integrals<2>();
779 assemble_volume_integrals<3>();
783 assemble_fluxes_boundary<1>();
784 assemble_fluxes_boundary<2>();
785 assemble_fluxes_boundary<3>();
789 assemble_fluxes_element_element<1>();
790 assemble_fluxes_element_element<2>();
791 assemble_fluxes_element_element<3>();
795 assemble_fluxes_element_side<1>();
796 assemble_fluxes_element_side<2>();
797 assemble_fluxes_element_side<3>();
804 template<
class Model>
805 template<
unsigned int dim>
808 FEValues<dim,3> fv_rt(*feo->mapping<dim>(), *feo->q<dim>(), *feo->fe_rt<dim>(),
810 FEValues<dim,3> fe_values(*feo->mapping<dim>(), *feo->q<dim>(), *feo->fe<dim>(),
812 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim>()->size();
813 unsigned int dof_indices[ndofs];
816 PetscScalar local_matrix[ndofs*ndofs];
819 for (
unsigned int i_cell=0; i_cell<feo->dh()->el_ds()->lsize(); i_cell++)
822 if (cell->dim() != dim)
continue;
827 feo->dh()->get_dof_indices(cell, dof_indices);
829 calculate_velocity(cell, velocity, fv_rt);
830 Model::compute_advection_diffusion_coefficients(fe_values.
point_list(), velocity, ele_acc, ad_coef, dif_coef);
831 Model::compute_sources_sigma(fe_values.
point_list(), ele_acc, sources_sigma);
834 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
836 for (
unsigned int i=0; i<ndofs; i++)
837 for (
unsigned int j=0; j<ndofs; j++)
838 local_matrix[i*ndofs+j] = 0;
840 for (
unsigned int k=0; k<qsize; k++)
842 for (
unsigned int i=0; i<ndofs; i++)
845 double ad_dot_grad_i = arma::dot(ad_coef[sbi][k], fe_values.
shape_grad(i,k));
847 for (
unsigned int j=0; j<ndofs; j++)
848 local_matrix[i*ndofs+j] += (arma::dot(Kt_grad_i, fe_values.
shape_grad(j,k))
853 ls[sbi]->mat_set_values(ndofs, (
int *)dof_indices, ndofs, (
int *)dof_indices, local_matrix);
859 template<
class Model>
864 balance_->start_source_assembly(subst_idx);
869 balance_->finish_source_assembly(subst_idx);
873 template<
class Model>
874 template<
unsigned int dim>
877 FEValues<dim,3> fe_values(*feo->mapping<dim>(), *feo->q<dim>(), *feo->fe<dim>(),
879 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim>()->size();
884 PetscScalar local_rhs[ndofs];
889 for (
unsigned int i_cell=0; i_cell<feo->dh()->el_ds()->lsize(); i_cell++)
892 if (cell->dim() != dim)
continue;
894 fe_values.reinit(cell);
895 feo->dh()->get_dof_indices(cell, (
unsigned int *)&(dof_indices[0]));
897 Model::compute_source_coefficients(fe_values.point_list(), cell->element_accessor(), sources_conc, sources_density, sources_sigma);
900 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
902 fill_n(local_rhs, ndofs, 0);
903 local_source_balance_vector.assign(ndofs, 0);
904 local_source_balance_rhs.assign(ndofs, 0);
907 for (
unsigned int k=0; k<qsize; k++)
909 source = (sources_density[k][sbi] + sources_conc[k][sbi]*sources_sigma[k][sbi])*fe_values.JxW(k);
911 for (
unsigned int i=0; i<ndofs; i++)
913 local_rhs[i] += source*fe_values.shape_value(i,k);
917 local_source_balance_vector[i] -= sources_sigma[k][sbi]*fe_values.shape_value(i,k)*fe_values.JxW(k);
918 local_source_balance_rhs[i] += source*fe_values.shape_value(i,k);
922 ls[sbi]->rhs_set_values(ndofs, &(dof_indices[0]), local_rhs);
926 balance_->add_source_matrix_values(subst_idx[sbi], cell->region().bulk_idx(), dof_indices, local_source_balance_vector);
927 balance_->add_source_rhs_values(subst_idx[sbi], cell->region().bulk_idx(), dof_indices, local_source_balance_rhs);
935 template<
class Model>
936 template<
unsigned int dim>
942 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim-1>()->size(),
943 n_max_sides = ad_coef_edg.size();
945 PetscScalar local_matrix[ndofs*ndofs];
948 double gamma_l, omega[2], transport_flux;
950 for (
unsigned int sid=0; sid<n_max_sides; sid++)
952 side_dof_indices.push_back(
new unsigned int[ndofs]);
953 fe_values.push_back(
new FESideValues<dim,3>(*feo->mapping<dim>(), *feo->q<dim-1>(), *feo->fe<dim>(),
958 for (
unsigned int iedg=0; iedg<feo->dh()->n_loc_edges(); iedg++)
963 for (
int sid=0; sid<edg->
n_sides; sid++)
967 feo->dh()->get_dof_indices(cell, side_dof_indices[sid]);
968 fe_values[sid]->reinit(cell, edg->
side(sid)->
el_idx());
970 calculate_velocity(cell, side_velocity[sid], fsv_rt);
971 Model::compute_advection_diffusion_coefficients(fe_values[sid]->point_list(), side_velocity[sid], ele_acc, ad_coef_edg[sid], dif_coef_edg[sid]);
972 dg_penalty[sid] = data_.dg_penalty.value(cell->centre(), ele_acc);
976 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
979 for (
int sid=0; sid<edg->
n_sides; sid++)
982 for (
unsigned int k=0; k<qsize; k++)
983 fluxes[sid] += arma::dot(ad_coef_edg[sid][sbi][k], fe_values[sid]->normal_vector(k))*fe_values[sid]->JxW(k);
987 for (
int s1=0; s1<edg->
n_sides; s1++)
989 for (
int s2=s1+1; s2<edg->
n_sides; s2++)
995 arma::vec3 nv = fe_values[s1]->normal_vector(0);
998 set_DG_parameters_edge(*edg, s1, s2, qsize, dif_coef_edg[s1][sbi], dif_coef_edg[s2][sbi], fluxes, fe_values[0]->normal_vector(0), dg_penalty[s1][sbi], dg_penalty[s2][sbi], gamma_l, omega, transport_flux);
1004 #define AVERAGE(i,k,side_id) (fe_values[sd[side_id]]->shape_value(i,k)*0.5)
1005 #define WAVERAGE(i,k,side_id) (arma::dot(dif_coef_edg[sd[side_id]][sbi][k]*fe_values[sd[side_id]]->shape_grad(i,k),nv)*omega[side_id])
1006 #define JUMP(i,k,side_id) ((side_id==0?1:-1)*fe_values[sd[side_id]]->shape_value(i,k))
1009 for (
int n=0; n<2; n++)
1011 if (!feo->dh()->el_is_local(edg->
side(sd[n])->
element().
index()))
continue;
1013 for (
int m=0; m<2; m++)
1015 for (
unsigned int i=0; i<fe_values[sd[n]]->n_dofs(); i++)
1016 for (
unsigned int j=0; j<fe_values[sd[m]]->n_dofs(); j++)
1017 local_matrix[i*fe_values[sd[m]]->n_dofs()+j] = 0;
1019 for (
unsigned int k=0; k<qsize; k++)
1021 double flux_times_JxW = transport_flux*fe_values[0]->JxW(k);
1022 double gamma_times_JxW = gamma_l*fe_values[0]->JxW(k);
1024 for (
unsigned int i=0; i<fe_values[sd[n]]->n_dofs(); i++)
1026 double flux_JxW_jump_i = flux_times_JxW*
JUMP(i,k,n);
1027 double gamma_JxW_jump_i = gamma_times_JxW*
JUMP(i,k,n);
1028 double JxW_jump_i = fe_values[0]->JxW(k)*
JUMP(i,k,n);
1029 double JxW_var_wavg_i = fe_values[0]->JxW(k)*
WAVERAGE(i,k,n)*dg_variant;
1031 for (
unsigned int j=0; j<fe_values[sd[m]]->n_dofs(); j++)
1033 int index = i*fe_values[sd[m]]->n_dofs()+j;
1036 local_matrix[index] += flux_JxW_jump_i*
AVERAGE(j,k,m);
1039 local_matrix[index] += gamma_JxW_jump_i*
JUMP(j,k,m);
1042 local_matrix[index] -=
WAVERAGE(j,k,m)*JxW_jump_i;
1043 local_matrix[index] -=
JUMP(j,k,m)*JxW_var_wavg_i;
1047 ls[sbi]->mat_set_values(fe_values[sd[n]]->n_dofs(), (
int *)side_dof_indices[sd[n]], fe_values[sd[m]]->n_dofs(), (
int *)side_dof_indices[sd[m]], local_matrix);
1058 for (
unsigned int i=0; i<n_max_sides; i++)
1060 delete fe_values[i];
1061 delete[] side_dof_indices[i];
1066 template<
class Model>
1067 template<
unsigned int dim>
1070 FESideValues<dim,3> fe_values_side(*feo->mapping<dim>(), *feo->q<dim-1>(), *feo->fe<dim>(),
1074 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim-1>()->size();
1075 unsigned int side_dof_indices[ndofs];
1076 PetscScalar local_matrix[ndofs*ndofs];
1079 arma::vec dg_penalty;
1083 for (
unsigned int iedg=0; iedg<feo->dh()->n_loc_edges(); iedg++)
1086 if (edg->
n_sides > 1)
continue;
1088 if (edg->
side(0)->
dim() != dim-1)
continue;
1090 if (edg->
side(0)->
cond() == NULL)
continue;
1095 feo->dh()->get_dof_indices(cell, side_dof_indices);
1099 calculate_velocity(cell, side_velocity, fsv_rt);
1100 Model::compute_advection_diffusion_coefficients(fe_values_side.
point_list(), side_velocity, ele_acc, ad_coef, dif_coef);
1101 dg_penalty = data_.dg_penalty.value(cell->centre(), ele_acc);
1105 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1107 for (
unsigned int i=0; i<ndofs; i++)
1108 for (
unsigned int j=0; j<ndofs; j++)
1109 local_matrix[i*ndofs+j] = 0;
1113 double side_flux = 0;
1114 for (
unsigned int k=0; k<qsize; k++)
1115 side_flux += arma::dot(ad_coef[sbi][k], fe_values_side.
normal_vector(k))*fe_values_side.
JxW(k);
1116 double transport_flux = side_flux/side->
measure();
1118 if (bc_type[sbi] == EqData::dirichlet)
1121 set_DG_parameters_boundary(side, qsize, dif_coef[sbi], transport_flux, fe_values_side.
normal_vector(0), dg_penalty[sbi], gamma_l);
1122 gamma[sbi][side->
cond_idx()] = gamma_l;
1123 transport_flux += gamma_l;
1127 for (
unsigned int k=0; k<qsize; k++)
1129 double flux_times_JxW;
1130 if (bc_type[sbi] == EqData::robin)
1131 flux_times_JxW = (transport_flux + robin_sigma[k][sbi])*fe_values_side.
JxW(k);
1132 else if (bc_type[sbi] == EqData::inflow && side_flux < 0)
1135 flux_times_JxW = transport_flux*fe_values_side.
JxW(k);
1137 for (
unsigned int i=0; i<ndofs; i++)
1139 for (
unsigned int j=0; j<ndofs; j++)
1142 local_matrix[i*ndofs+j] += flux_times_JxW*fe_values_side.
shape_value(i,k)*fe_values_side.
shape_value(j,k);
1145 if (bc_type[sbi] == EqData::dirichlet)
1148 )*fe_values_side.
JxW(k);
1153 ls[sbi]->mat_set_values(ndofs, (
int *)side_dof_indices, ndofs, (
int *)side_dof_indices, local_matrix);
1159 template<
class Model>
1160 template<
unsigned int dim>
1164 if (dim == 1)
return;
1165 FEValues<dim-1,3> fe_values_vb(*feo->mapping<dim-1>(), *feo->q<dim-1>(), *feo->
fe<dim-1>(),
1171 FEValues<dim-1,3> fv_rt(*feo->mapping<dim-1>(), *feo->q<dim-1>(), *feo->fe_rt<dim-1>(),
1175 const unsigned int ndofs = feo->fe<dim>()->n_dofs();
1176 const unsigned int qsize = feo->q<dim-1>()->size();
1177 unsigned int side_dof_indices[2*ndofs], n_dofs[2];
1180 vector<double> csection_lower(qsize), csection_higher(qsize), mm_coef_lower(qsize), mm_coef_higher(qsize);
1181 PetscScalar local_matrix[4*ndofs*ndofs];
1182 double comm_flux[2][2];
1186 fv_sb[0] = &fe_values_vb;
1187 fv_sb[1] = &fe_values_side;
1190 for (
unsigned int inb=0; inb<feo->dh()->n_loc_nb(); inb++)
1197 feo->dh()->get_dof_indices(cell_sub, side_dof_indices);
1198 fe_values_vb.
reinit(cell_sub);
1199 n_dofs[0] = fv_sb[0]->n_dofs();
1202 feo->dh()->get_dof_indices(cell, side_dof_indices+n_dofs[0]);
1204 n_dofs[1] = fv_sb[1]->n_dofs();
1208 element_id[0] = cell_sub.
index();
1209 element_id[1] = cell.
index();
1213 calculate_velocity(cell, velocity_higher, fsv_rt);
1214 calculate_velocity(cell_sub, velocity_lower, fv_rt);
1215 Model::compute_advection_diffusion_coefficients(fe_values_vb.
point_list(), velocity_lower, cell_sub->element_accessor(), ad_coef_edg[0], dif_coef_edg[0]);
1216 Model::compute_advection_diffusion_coefficients(fe_values_vb.
point_list(), velocity_higher, cell->element_accessor(), ad_coef_edg[1], dif_coef_edg[1]);
1217 Model::compute_mass_matrix_coefficient(fe_values_vb.
point_list(), cell_sub->element_accessor(), mm_coef_lower);
1218 Model::compute_mass_matrix_coefficient(fe_values_vb.
point_list(), cell->element_accessor(), mm_coef_higher);
1219 data_.cross_section.value_list(fe_values_vb.
point_list(), cell_sub->element_accessor(), csection_lower);
1220 data_.cross_section.value_list(fe_values_vb.
point_list(), cell->element_accessor(), csection_higher);
1221 data_.fracture_sigma.value_list(fe_values_vb.
point_list(), cell_sub->element_accessor(), frac_sigma);
1223 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1225 for (
unsigned int i=0; i<n_dofs[0]+n_dofs[1]; i++)
1226 for (
unsigned int j=0; j<n_dofs[0]+n_dofs[1]; j++)
1227 local_matrix[i*(n_dofs[0]+n_dofs[1])+j] = 0;
1230 for (
unsigned int k=0; k<qsize; k++)
1240 double sigma = frac_sigma[k][sbi]*arma::dot(dif_coef_edg[0][sbi][k]*fe_values_side.
normal_vector(k),fe_values_side.
normal_vector(k))*
1241 2*csection_higher[k]*csection_higher[k]/(csection_lower[k]*csection_lower[k]);
1244 double transport_flux = arma::dot(ad_coef_edg[1][sbi][k], fe_values_side.
normal_vector(k));
1245 double por_lower_over_higher = mm_coef_lower[k]*csection_higher[k]/(mm_coef_higher[k]*csection_lower[k]);
1247 comm_flux[0][0] = (sigma-min(0.,transport_flux*por_lower_over_higher))*fv_sb[0]->JxW(k);
1248 comm_flux[0][1] = -(sigma-min(0.,transport_flux*por_lower_over_higher))*fv_sb[0]->JxW(k);
1249 comm_flux[1][0] = -(sigma+max(0.,transport_flux))*fv_sb[0]->JxW(k);
1250 comm_flux[1][1] = (sigma+max(0.,transport_flux))*fv_sb[0]->JxW(k);
1252 for (
int n=0; n<2; n++)
1254 if (!feo->dh()->el_is_local(element_id[n]))
continue;
1256 for (
unsigned int i=0; i<n_dofs[n]; i++)
1257 for (
int m=0; m<2; m++)
1258 for (
unsigned int j=0; j<n_dofs[m]; j++)
1259 local_matrix[(i+n*n_dofs[0])*(n_dofs[0]+n_dofs[1]) + m*n_dofs[0] + j] +=
1260 comm_flux[m][n]*fv_sb[m]->shape_value(j,k)*fv_sb[n]->shape_value(i,k);
1263 ls[sbi]->mat_set_values(n_dofs[0]+n_dofs[1], (
int *)side_dof_indices, n_dofs[0]+n_dofs[1], (
int *)side_dof_indices, local_matrix);
1274 template<
class Model>
1279 balance_->start_flux_assembly(subst_idx);
1280 set_boundary_conditions<1>();
1281 set_boundary_conditions<2>();
1282 set_boundary_conditions<3>();
1284 balance_->finish_flux_assembly(subst_idx);
1289 template<
class Model>
1290 template<
unsigned int dim>
1293 FESideValues<dim,3> fe_values_side(*feo->mapping<dim>(), *feo->q<dim-1>(), *feo->fe<dim>(),
1297 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim-1>()->size();
1299 unsigned int loc_b=0;
1300 double local_rhs[ndofs];
1302 PetscScalar local_flux_balance_rhs;
1308 for (
unsigned int loc_el = 0; loc_el < feo->dh()->el_ds()->lsize(); loc_el++)
1311 if (elm->boundary_idx_ ==
nullptr)
continue;
1315 Edge *edg = elm->side(si)->edge();
1316 if (edg->
n_sides > 1)
continue;
1318 if (edg->
side(0)->
cond() == NULL)
continue;
1320 if (edg->
side(0)->
dim() != dim-1)
1322 if (edg->
side(0)->
cond() !=
nullptr) ++loc_b;
1330 arma::uvec bc_type = data_.bc_type.value(side->
cond()->
element()->
centre(), ele_acc);
1332 fe_values_side.reinit(cell, side->
el_idx());
1333 fsv_rt.reinit(cell, side->
el_idx());
1334 calculate_velocity(cell, velocity, fsv_rt);
1336 Model::compute_advection_diffusion_coefficients(fe_values_side.point_list(), velocity, side->
element()->element_accessor(), ad_coef, dif_coef);
1337 Model::compute_dirichlet_bc(fe_values_side.point_list(), ele_acc, bc_values);
1338 data_.bc_flux.value_list(fe_values_side.point_list(), ele_acc, bc_fluxes);
1339 data_.bc_robin_sigma.value_list(fe_values_side.point_list(), ele_acc, bc_sigma);
1341 feo->dh()->get_dof_indices(cell, (
unsigned int *)&(side_dof_indices[0]));
1343 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1345 fill_n(local_rhs, ndofs, 0);
1346 local_flux_balance_vector.assign(ndofs, 0);
1347 local_flux_balance_rhs = 0;
1349 double side_flux = 0;
1350 for (
unsigned int k=0; k<qsize; k++)
1351 side_flux += arma::dot(ad_coef[sbi][k], fe_values_side.normal_vector(k))*fe_values_side.JxW(k);
1352 double transport_flux = side_flux/side->
measure();
1354 for (
unsigned int k=0; k<qsize; k++)
1359 if (bc_type[sbi] == EqData::inflow && side_flux < 0)
1361 bc_term = -transport_flux*bc_values[k][sbi]*fe_values_side.JxW(k);
1363 else if (bc_type[sbi] == EqData::dirichlet)
1365 bc_term = gamma[sbi][side->
cond_idx()]*bc_values[k][sbi]*fe_values_side.JxW(k);
1366 bc_grad = -bc_values[k][sbi]*fe_values_side.JxW(k)*dg_variant*(arma::trans(dif_coef[sbi][k])*fe_values_side.normal_vector(k));
1368 else if (bc_type[sbi] == EqData::neumann)
1370 bc_term = -bc_fluxes[k][sbi]*fe_values_side.JxW(k);
1372 else if (bc_type[sbi] == EqData::robin)
1374 bc_term = bc_sigma[k][sbi]*bc_values[k][sbi]*fe_values_side.JxW(k);
1377 for (
unsigned int i=0; i<ndofs; i++)
1379 local_rhs[i] += bc_term*fe_values_side.shape_value(i,k)
1380 + arma::dot(bc_grad,fe_values_side.shape_grad(i,k));
1384 if (bc_type[sbi] == EqData::dirichlet)
1386 local_flux_balance_vector[i] += (arma::dot(ad_coef[sbi][k], fe_values_side.normal_vector(k))*fe_values_side.shape_value(i,k)
1387 - arma::dot(dif_coef[sbi][k]*fe_values_side.shape_grad(i,k),fe_values_side.normal_vector(k))
1388 + gamma[sbi][side->
cond_idx()]*fe_values_side.shape_value(i,k))*fe_values_side.JxW(k);
1389 local_flux_balance_rhs -= (
time_->
tlevel() == 0?0:1)*bc_term*fe_values_side.shape_value(i,k);
1391 else if (bc_type[sbi] == EqData::inflow && side_flux < 0)
1393 local_flux_balance_rhs -= bc_term*fe_values_side.shape_value(i,k);
1395 else if (bc_type[sbi] == EqData::neumann)
1397 local_flux_balance_vector[i] += arma::dot(ad_coef[sbi][k], fe_values_side.normal_vector(k))*fe_values_side.JxW(k)*fe_values_side.shape_value(i,k);
1398 local_flux_balance_rhs -= bc_term*fe_values_side.shape_value(i,k);
1400 else if (bc_type[sbi] == EqData::robin)
1402 local_flux_balance_vector[i] += (arma::dot(ad_coef[sbi][k], fe_values_side.normal_vector(k)) + bc_sigma[k][sbi])*fe_values_side.JxW(k)*fe_values_side.shape_value(i,k);
1403 local_flux_balance_rhs -= bc_term*fe_values_side.shape_value(i,k);
1407 local_flux_balance_vector[i] += arma::dot(ad_coef[sbi][k], fe_values_side.normal_vector(k))*fe_values_side.JxW(k)*fe_values_side.shape_value(i,k);
1412 ls[sbi]->rhs_set_values(ndofs, &(side_dof_indices[0]), local_rhs);
1416 balance_->add_flux_matrix_values(subst_idx[sbi], loc_b, side_dof_indices, local_flux_balance_vector);
1417 balance_->add_flux_vec_value(subst_idx[sbi], loc_b, local_flux_balance_rhs);
1432 template<
class Model>
1433 template<
unsigned int dim>
1437 for (
unsigned int i=0; i<cell->n_nodes(); i++)
1438 node_nums[cell->node[i]] = i;
1442 for (
unsigned int k=0; k<fv.
n_points(); k++)
1444 velocity[k].zeros();
1445 for (
unsigned int sid=0; sid<cell->n_sides(); sid++)
1447 if (cell->side(sid)->dim() != dim-1)
continue;
1448 int num = dim*(dim+1)/2;
1449 for (
unsigned int i=0; i<cell->side(sid)->n_nodes(); i++)
1450 num -= node_nums[cell->side(sid)->node(i)];
1460 template<
class Model>
1469 const double alpha1,
1470 const double alpha2,
1473 double &transport_flux)
1477 double local_alpha = 0;
1489 for (
unsigned int i=0; i<s->n_nodes(); i++)
1490 for (
unsigned int j=i+1; j<s->n_nodes(); j++)
1491 h = max(h, s->node(i)->distance(*s->node(j)));
1495 double pflux = 0, nflux = 0;
1496 for (
int i=0; i<edg.
n_sides; i++)
1505 if (fluxes[s2] > 0 && fluxes[s1] < 0 && s1 < s2)
1506 transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
1507 else if (fluxes[s2] < 0 && fluxes[s1] > 0 && s1 < s2)
1508 transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
1510 transport_flux = fluxes[s1];
1514 gamma = 0.5*fabs(transport_flux);
1518 local_alpha = max(alpha1, alpha2);
1526 for (
int k=0; k<K_size; k++)
1527 delta[0] += dot(K1[k]*normal_vector,normal_vector);
1530 gamma += local_alpha/h*(delta[0]);
1536 for (
int k=0; k<K_size; k++)
1538 delta[0] += dot(K1[k]*normal_vector,normal_vector);
1539 delta[1] += dot(K2[k]*normal_vector,normal_vector);
1544 double delta_sum = delta[0] + delta[1];
1548 omega[0] = delta[1]/delta_sum;
1549 omega[1] = delta[0]/delta_sum;
1550 gamma += local_alpha/h*(delta[0]*delta[1]/delta_sum);
1553 for (
int i=0; i<2; i++) omega[i] = 0;
1562 template<
class Model>
1571 double delta = 0, h = 0;
1574 if (side->
dim() == 0)
1580 for (
unsigned int i=0; i<side->
n_nodes(); i++)
1581 for (
unsigned int j=i+1; j<side->
n_nodes(); j++)
1586 for (
int k=0; k<K_size; k++)
1587 delta += dot(K[k]*normal_vector,normal_vector);
1590 gamma = 0.5*fabs(flux) + alpha/h*delta;
1597 template<
class Model>
1601 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1602 ls[sbi]->start_allocation();
1603 prepare_initial_condition<1>();
1604 prepare_initial_condition<2>();
1605 prepare_initial_condition<3>();
1607 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1608 ls[sbi]->start_add_assembly();
1609 prepare_initial_condition<1>();
1610 prepare_initial_condition<2>();
1611 prepare_initial_condition<3>();
1613 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1615 ls[sbi]->finish_assembly();
1621 template<
class Model>
1622 template<
unsigned int dim>
1625 FEValues<dim,3> fe_values(*feo->mapping<dim>(), *feo->q<dim>(), *feo->fe<dim>(),
1627 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim>()->size();
1628 unsigned int dof_indices[ndofs];
1629 double matrix[ndofs*ndofs], rhs[ndofs];
1632 for (
unsigned int k=0; k<qsize; k++)
1633 init_values[k].resize(n_subst_);
1635 for (
unsigned int i_cell=0; i_cell<feo->dh()->el_ds()->lsize(); i_cell++)
1638 if (elem->dim() != dim)
continue;
1641 feo->dh()->get_dof_indices(elem, dof_indices);
1644 Model::compute_init_cond(fe_values.
point_list(), ele_acc, init_values);
1646 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1648 for (
unsigned int i=0; i<ndofs; i++)
1651 for (
unsigned int j=0; j<ndofs; j++)
1652 matrix[i*ndofs+j] = 0;
1655 for (
unsigned int k=0; k<qsize; k++)
1657 double rhs_term = init_values[k](sbi)*fe_values.
JxW(k);
1659 for (
unsigned int i=0; i<ndofs; i++)
1661 for (
unsigned int j=0; j<ndofs; j++)
1667 ls[sbi]->set_values(ndofs, (
int *)dof_indices, ndofs, (
int *)dof_indices, matrix, rhs);
1673 template<
class Model>
1676 calc_fluxes<1>(bcd_balance, bcd_plus_balance, bcd_minus_balance);
1677 calc_fluxes<2>(bcd_balance, bcd_plus_balance, bcd_minus_balance);
1678 calc_fluxes<3>(bcd_balance, bcd_plus_balance, bcd_minus_balance);
1681 template<
class Model>
1682 template<
unsigned int dim>
1689 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim-1>()->size();
1690 unsigned int dof_indices[ndofs];
1692 vector<arma::vec> bc_values(qsize, arma::vec(n_subst_)), bc_fluxes(qsize, arma::vec(n_subst_)), bc_sigma(qsize, arma::vec(n_subst_));
1695 for (
unsigned int iedg=0; iedg<feo->dh()->n_loc_edges(); iedg++)
1698 if (edg->
n_sides > 1)
continue;
1699 if (edg->
side(0)->
dim() != dim-1)
continue;
1701 if (edg->
side(0)->
cond() == NULL)
continue;
1710 fe_values.reinit(cell, side->
el_idx());
1711 fsv_rt.reinit(cell, side->
el_idx());
1712 feo->dh()->get_dof_indices(cell, dof_indices);
1713 calculate_velocity(cell, side_velocity, fsv_rt);
1714 Model::compute_advection_diffusion_coefficients(fe_values.point_list(), side_velocity, ele_acc, ad_coef, dif_coef);
1715 Model::compute_dirichlet_bc(fe_values.point_list(), side->
cond()->
element_accessor(), bc_values);
1717 data_.bc_robin_sigma.value_list(fe_values.point_list(), side->
cond()->
element_accessor(), bc_sigma);
1720 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1722 double mass_flux = 0;
1723 double water_flux = 0;
1724 for (
unsigned int k=0; k<qsize; k++)
1725 water_flux += arma::dot(ad_coef[sbi][k], fe_values.normal_vector(k))*fe_values.JxW(k);
1726 water_flux /= side->
measure();
1728 for (
unsigned int k=0; k<qsize; k++)
1732 for (
unsigned int i=0; i<ndofs; i++)
1734 conc += fe_values.shape_value(i,k)*ls[sbi]->get_solution_array()[dof_indices[i]-feo->dh()->loffset()];
1735 conc_grad += fe_values.shape_grad(i,k)*ls[sbi]->get_solution_array()[dof_indices[i]-feo->dh()->loffset()];
1739 if (bc_type[sbi] == EqData::inflow && water_flux < 0)
1740 mass_flux += water_flux*bc_values[k][sbi]*fe_values.JxW(k);
1742 mass_flux += water_flux*conc*fe_values.JxW(k);
1744 if (bc_type[sbi] == EqData::dirichlet)
1747 mass_flux -= arma::dot(dif_coef[sbi][k]*conc_grad,fe_values.normal_vector(k))*fe_values.JxW(k);
1750 mass_flux -= gamma[sbi][side->
cond_idx()]*(bc_values[k][sbi] - conc)*fe_values.JxW(k);
1752 else if (bc_type[sbi] == EqData::neumann)
1755 mass_flux += bc_fluxes[k][sbi]*fe_values.JxW(k);
1757 else if (bc_type[sbi] == EqData::robin)
1760 mass_flux += bc_sigma[k][sbi]*(conc - bc_values[k][sbi])*fe_values.JxW(k);
1764 bcd_balance[sbi][bc_region_idx] += mass_flux;
1765 if (mass_flux >= 0) bcd_plus_balance[sbi][bc_region_idx] += mass_flux;
1766 else bcd_minus_balance[sbi][bc_region_idx] += mass_flux;
1772 template<
class Model>
1775 calc_elem_sources<1>(mass, src_balance);
1776 calc_elem_sources<2>(mass, src_balance);
1777 calc_elem_sources<3>(mass, src_balance);
1780 template<
class Model>
1781 template<
unsigned int dim>
1784 FEValues<dim,3> fe_values(*feo->mapping<dim>(), *feo->q<dim>(), *feo->fe<dim>(),
1786 const unsigned int ndofs = feo->fe<dim>()->n_dofs(), qsize = feo->q<dim>()->size();
1787 unsigned int dof_indices[ndofs];
1791 double mass_sum, sources_sum, conc, conc_diff;
1793 for (
unsigned int i_cell=0; i_cell<feo->dh()->el_ds()->lsize(); i_cell++)
1796 if (elem->dim() != dim)
continue;
1798 Region r = elem->element_accessor().region();
1800 unsigned int region_idx = r.
bulk_idx();
1803 fe_values.reinit(elem);
1804 feo->dh()->get_dof_indices(elem, dof_indices);
1806 Model::compute_mass_matrix_coefficient(fe_values.point_list(), ele_acc, mm_coef);
1807 Model::compute_source_coefficients(fe_values.point_list(), ele_acc, sources_conc, sources_density, sources_sigma);
1809 for (
unsigned int sbi=0; sbi<
n_subst_; sbi++)
1814 for (
unsigned int k=0; k<qsize; k++)
1817 for (
unsigned int i=0; i<ndofs; i++)
1818 conc += fe_values.shape_value(i,k)*ls[sbi]->get_solution_array()[dof_indices[i]-feo->dh()->loffset()];
1820 mass_sum += mm_coef[k]*conc*fe_values.JxW(k);
1822 conc_diff = sources_conc[k][sbi] - conc;
1823 sources_sum += (sources_density[k][sbi] + conc_diff*sources_sigma[k][sbi])*fe_values.JxW(k);
1826 mass[sbi][region_idx] += mass_sum;
1827 src_balance[sbi][region_idx] += sources_sum;
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
Distribution * el_ds() const
Returns the distribution of number of element to local processes.
void assemble_fluxes_element_element()
Assembles the fluxes between elements of the same dimension.
void set_sources()
Assembles the right hand side due to volume sources.
void set_boundary_conditions()
Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions.
Transformed quadrature weight for cell sides.
FiniteElement< dim, 3 > * fe()
vector< double > mm_coef
Mass matrix coefficients.
void assemble_fluxes_element_side()
Assembles the fluxes between elements of different dimensions.
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...
Input::Record output_rec
Record with output specification.
static constexpr Mask allow_output
The field can output. Is part of generated output selection. (default on)
unsigned int bulk_size() const
const std::vector< std::string > & names()
Transport with dispersion implemented using discontinuous Galerkin method.
Field< 3, FieldValue< 3 >::Integer > region_id
void add_admissible_field_names(const Input::Array &in_array)
Registers names of output fields that can be written using this stream.
FieldCommon & flags_add(FieldFlag::Flags::Mask mask)
double distance(const Node &n2) const
void assemble_mass_matrix()
Assembles the mass matrix.
OutputTime * output_stream
int * get_el_4_loc() const
void next_time()
Proceed to the next time according to current estimated time step.
void update_solution() override
Computes the solution in one time instant.
const double JxW(const unsigned int point_no)
Return the product of Jacobian determinant and the quadrature weight at given quadrature point...
const arma::vec::fixed< spacedim > normal_vector(unsigned int point_no)
Returns the normal vector to a side at given quadrature point.
TimeMark::Type type_output()
int dg_variant
DG variant ((non-)symmetric/incomplete.
void prepare_initial_condition()
Assembles the auxiliary linear system to calculate the initial solution as L^2-projection of the pres...
RegionSet get_region_set(const string &set_name) const
const MH_DofHandler * mh_dh
Fields computed from the mesh data.
void set_initial_condition()
Sets the initial condition.
Class FEValues calculates finite element data on the actual cells such as shape function values...
#define FOR_ELEMENT_SIDES(i, j)
bool is_current(const TimeMark::Type &mask) const
vector< vector< arma::vec3 > > ad_coef
Advection coefficients.
static Input::Type::Record input_type
const RegionDB & region_db() const
void set_from_input(const Input::Record in_rec)
Mat * mass_matrix
The mass matrix.
#define AVERAGE(i, k, side_id)
void assemble_stiffness_matrix()
Assembles the stiffness matrix.
const TimeStep & step(int index=-1) const
vector< vector< vector< arma::mat33 > > > dif_coef_edg
Diffusion coefficients on edges.
Discontinuous Galerkin method for equation of transport with dispersion.
vector< Boundary > boundary_
Basic time management functionality for unsteady (and steady) solvers (class Equation).
FieldCommon & units(const UnitSI &units)
Set basic units of the field.
const arma::vec::fixed< spacedim > shape_grad(const unsigned int function_no, const unsigned int point_no)
Return the gradient of the function_no-th shape function at the point_no-th quadrature point...
unsigned int size() const
static TimeMarks & marks()
Specification of transport model interface.
void view(const char *name="") const
void assemble_fluxes_boundary()
Assembles the fluxes on the boundary.
Symmetric Gauss-Legendre quadrature formulae on simplices.
#define WAVERAGE(i, k, side_id)
const unsigned int n_points()
Returns the number of quadrature points.
vector< vector< double > > ret_coef
Retardation coefficient due to sorption.
unsigned int boundary_idx() const
Returns index of the region in the boundary set.
vector< double > sorption_sources
Temporary values of source increments.
TransportDG(Mesh &init_mesh, const Input::Record &in_rec)
Constructor.
vector< double * > output_solution
Array for storing the output solution data.
vector< vector< vector< arma::vec3 > > > ad_coef_edg
Advection coefficients on edges.
Discontinuous Lagrangean finite element on dim dimensional simplex.
Transformed quadrature points.
void output_data()
Postprocesses the solution and writes to output file.
static OutputTime * create_output_stream(const Input::Record &in_rec)
This method delete all object instances of class OutputTime stored in output_streams vector...
vector< unsigned int > subst_idx
List of indices used to call balance methods for a set of quantities.
vector< vector< arma::mat33 > > dif_coef
Diffusion coefficients.
FEObjects * feo
Finite element objects.
static constexpr Mask in_time_term
A field is part of time term of the equation.
FieldCommon & input_default(const string &input_default)
TimeMark::Type equation_fixed_mark_type() const
Raviart-Thomas element of order 0.
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.
FieldCommon & input_selection(const Input::Type::Selection *element_selection)
static auto region_id(Mesh &mesh) -> IndexField
#define START_TIMER(tag)
Starts a timer with specified tag.
FiniteElement< dim, spacedim > * fe
The used finite element.
Provides the numbering of the finite element degrees of freedom on the computational mesh...
Mat * stiffness_matrix
The stiffness matrix.
Field< 3, FieldValue< 3 >::Vector > fracture_sigma
Transition parameter for diffusive transfer on fractures (for each substance).
boost::shared_ptr< Balance > balance_
(new) object for calculation and writing the mass balance to file.
unsigned int dg_order
Polynomial order of finite elements.
void output_vector_gather()
static constexpr Mask in_rhs
A field is part of the right hand side of the equation.
unsigned int n_subst_
Number of transported substances.
Affine mapping between reference and actual cell.
Shape function gradients.
void mark_output_times(const TimeGovernor &tg)
Vec * rhs
Vector of right hand side.
void set_solution(double *sol_array)
BCField< 3, FieldValue< 3 >::Vector > bc_flux
Flux in Neumann or Robin b.c.
static Input::Type::Selection bc_type_selection
DOFHandlerMultiDim * dh()
Discontinuous Galerkin method for equation of transport with dispersion.
const vector< arma::vec::fixed< spacedim > > & point_list()
Return coordinates of all quadrature points in the actual cell system.
void output_data() override
Write computed fields.
vector< Neighbour > vb_neighbours_
double side_flux(const Side &side) const
temporary replacement for DofHandler accessor, flux through given side
const arma::vec::fixed< spacedim > shape_vector(const unsigned int function_no, const unsigned int point_no)
Return the value of the function_no-th shape function at the point_no-th quadrature point...
FieldCommon & description(const string &description)
EqData data_
Field data for model parameters.
bool allocation_done
Indicates whether matrices have been preallocated.
unsigned int cond_idx() const
std::vector< std::vector< double > > gamma
Penalty parameters.
unsigned int max_edge_sides(unsigned int dim) const
Discontinuous Galerkin method for equation of transport with dispersion.
SubstanceList substances_
Transported substances.
ElementFullIter element() const
void calc_fluxes(vector< vector< double > > &bcd_balance, vector< vector< double > > &bcd_plus_balance, vector< vector< double > > &bcd_minus_balance)
Calculates flux through boundary of each region.
arma::vec3 centre() const
void reinit(ElementFullIter &cell, unsigned int sid)
Update cell-dependent data (gradients, Jacobians etc.)
const double shape_value(const unsigned int function_no, const unsigned int point_no)
Return the value of the function_no-th shape function at the point_no-th quadrature point...
BCField< 3, FieldValue< 3 >::EnumVector > bc_type
Type of boundary condition (see also BC_Type)
void reinit(ElementFullIter &cell)
Update cell-dependent data (gradients, Jacobians etc.)
Vec * mass_vec
Mass from previous time instant (necessary when coefficients of mass matrix change in time)...
std::vector< Edge > edges
Vector of MH edges, this should not be part of the geometrical mesh.
FullIter full_iter(Iter it)
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
Abstract linear system class.
Definitions of particular quadrature rules on simplices.
FieldCommon & name(const string &name)
void calc_elem_sources(vector< vector< double > > &mass, vector< vector< double > > &src_balance)
Calculates volume sources for each region.
vector< Vec > output_vec
Vector of solution data.
Calculates finite element data on the actual cell.
#define END_TIMER(tag)
Ends a timer with specified tag.
Discontinuous Galerkin method for equation of transport with dispersion.
virtual void set_velocity_field(const MH_DofHandler &dh)
Updates the velocity field which determines some coefficients of the transport equation.
mixed-hybrid model of linear Darcy flow, possibly unsteady.
unsigned int el_idx() const
unsigned int n_substances() override
Returns number of trnasported substances.
void assemble_volume_integrals()
Assembles the volume integrals into the stiffness matrix.
bool is_valid() const
Returns false if the region has undefined/invalid value.
FieldCommon & flags(FieldFlag::Flags::Mask mask)
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
Base class for FEValues and FESideValues.
Class for representation SI units of Fields.
const Node * node(unsigned int i) const
void calculate_velocity(const ElementFullIter &cell, std::vector< arma::vec3 > &velocity, FEValuesBase< dim, 3 > &fv)
Calculates the velocity field on a given dim dimensional cell.
Distribution * distr() const
Mapping< dim, 3 > * mapping()
static UnitSI & dimensionless()
Returns dimensionless unit.
~TransportDG()
Destructor.
LinSys ** ls
Linear algebra system for the transport equation.
void set_DG_parameters_edge(const Edge &edg, const int s1, const int s2, const int K_size, const std::vector< arma::mat33 > &K1, const std::vector< arma::mat33 > &K2, const std::vector< double > &fluxes, const arma::vec3 &normal_vector, const double alpha1, const double alpha2, double &gamma, double *omega, double &transport_flux)
Sets up some parameters of the DG method for two sides of an edge.
SideIter side(const unsigned int i) const
LinSys ** ls_dt
Linear algebra system for the time derivative (actually it is used only for handling the matrix struc...
Field< 3, FieldValue< 3 >::Vector > dg_penalty
Penalty enforcing inter-element continuity of solution (for each substance).
#define JUMP(i, k, side_id)
void set_DG_parameters_boundary(const SideIter 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.
Definitions of Raviart-Thomas finite elements.
const unsigned int n_global_dofs() const
Getter for the number of all mesh dofs required by the given finite element.
BCField< 3, FieldValue< 3 >::Vector > bc_robin_sigma
Transition coefficient in Robin b.c.
ElementAccessor< 3 > element_accessor()
void zero_time_step() override
Initialize solution in the zero time.
FEObjects(Mesh *mesh_, unsigned int fe_order)
ElementVector element
Vector of elements of the mesh.
unsigned int n_nodes() const
Transformed quadrature weights.
Calculates finite element data on a side.
unsigned int lsize(int proc) const
get local size