18 #ifndef ASSEMBLY_DG_HH_ 19 #define ASSEMBLY_DG_HH_ 61 template <
unsigned int dim,
class Model>
69 : fe_(make_shared<
FE_P_disc<dim> >(data->dg_order)), fe_low_(make_shared<
FE_P_disc<dim-1> >(data->dg_order)),
71 quad_(new
QGauss(dim, 2*data->dg_order)),
72 quad_low_(new
QGauss(dim-1, 2*data->dg_order)),
75 fv_rt_vb_(nullptr), fe_values_vb_(nullptr),
81 fe_values_vb_ =
new FEValues<dim-1,3>(*quad_low_, *fe_low_,
85 qsize_ = quad_->size();
86 qsize_lower_dim_ = quad_low_->size();
87 dof_indices_.resize(ndofs_);
88 loc_dof_indices_.resize(ndofs_);
89 side_dof_indices_vb_.resize(2*ndofs_);
98 if (fv_rt_vb_!=
nullptr)
delete fv_rt_vb_;
99 if (fe_values_vb_!=
nullptr)
delete fe_values_vb_;
101 for (
unsigned int i=0; i<data_->ad_coef_edg.size(); i++)
103 delete fe_values_vec_[i];
109 local_matrix_.resize(4*ndofs_*ndofs_);
110 local_retardation_balance_vector_.resize(ndofs_);
111 local_mass_balance_vector_.resize(ndofs_);
112 local_rhs_.resize(ndofs_);
113 local_source_balance_vector_.resize(ndofs_);
114 local_source_balance_rhs_.resize(ndofs_);
115 local_flux_balance_vector_.resize(ndofs_);
116 velocity_.resize(qsize_);
117 side_velocity_vec_.resize(data_->ad_coef_edg.size());
121 sigma_.resize(qsize_lower_dim_);
122 csection_.resize(qsize_lower_dim_);
123 csection_higher_.resize(qsize_lower_dim_);
124 dg_penalty_.resize(data_->ad_coef_edg.size());
125 bc_values_.resize(qsize_lower_dim_);
126 bc_fluxes_.resize(qsize_lower_dim_);
127 bc_ref_values_.resize(qsize_lower_dim_);
130 mm_coef_.resize(qsize_);
131 ret_coef_.resize(model_.n_substances());
132 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
134 ret_coef_[sbi].resize(qsize_);
137 for (
unsigned int sid=0; sid<data_->ad_coef_edg.size(); sid++)
140 fe_values_vec_.push_back(
new FESideValues<dim,3>(*quad_low_, *fe_,
147 fv_sb_[0] = fe_values_vb_;
148 fv_sb_[1] = &fe_values_side_;
157 fe_values_.reinit(elm);
160 model_.compute_mass_matrix_coefficient(fe_values_.point_list(), elm, mm_coef_);
161 model_.compute_retardation_coefficient(fe_values_.point_list(), elm, ret_coef_);
163 for (
unsigned int sbi=0; sbi<model_.n_substances(); ++sbi)
166 for (
unsigned int i=0; i<ndofs_; i++)
168 for (
unsigned int j=0; j<ndofs_; j++)
170 local_matrix_[i*ndofs_+j] = 0;
171 for (
unsigned int k=0; k<qsize_; k++)
172 local_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);
176 for (
unsigned int i=0; i<ndofs_; i++)
178 local_mass_balance_vector_[i] = 0;
179 local_retardation_balance_vector_[i] = 0;
180 for (
unsigned int k=0; k<qsize_; k++)
182 local_mass_balance_vector_[i] += mm_coef_[k]*fe_values_.shape_value(i,k)*fe_values_.JxW(k);
183 local_retardation_balance_vector_[i] -= ret_coef_[sbi][k]*fe_values_.shape_value(i,k)*fe_values_.JxW(k);
187 model_.balance()->add_mass_matrix_values(model_.get_subst_idx()[sbi], elm.
region().
bulk_idx(), dof_indices_, local_mass_balance_vector_);
188 data_->ls_dt[sbi]->mat_set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]));
189 VecSetValues(data_->ret_vec[sbi], ndofs_, &(dof_indices_[0]), &(local_retardation_balance_vector_[0]), ADD_VALUES);
197 if (!cell.
is_own())
return;
201 fe_values_.reinit(elm);
205 calculate_velocity(elm, velocity_, fv_rt_.point_list());
206 model_.compute_advection_diffusion_coefficients(fe_values_.point_list(), velocity_, elm, data_->ad_coef, data_->dif_coef);
207 model_.compute_sources_sigma(fe_values_.point_list(), elm, sources_sigma_);
210 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
212 for (
unsigned int i=0; i<ndofs_; i++)
213 for (
unsigned int j=0; j<ndofs_; j++)
214 local_matrix_[i*ndofs_+j] = 0;
216 for (
unsigned int k=0; k<qsize_; k++)
218 for (
unsigned int i=0; i<ndofs_; i++)
220 arma::vec3 Kt_grad_i = data_->dif_coef[sbi][k].t()*fe_values_.shape_grad(i,k);
221 double ad_dot_grad_i = arma::dot(data_->ad_coef[sbi][k], fe_values_.shape_grad(i,k));
223 for (
unsigned int j=0; j<ndofs_; j++)
224 local_matrix_[i*ndofs_+j] += (arma::dot(Kt_grad_i, fe_values_.shape_grad(j,k))
225 -fe_values_.shape_value(j,k)*ad_dot_grad_i
226 +sources_sigma_[sbi][k]*fe_values_.shape_value(j,k)*fe_values_.shape_value(i,k))*fe_values_.JxW(k);
229 data_->ls[sbi]->mat_set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]));
237 if (!cell.
is_own())
return;
241 Side side = cell_side.side();
244 if (side.
dim() != dim-1)
continue;
246 if (side.
cond() == NULL)
continue;
250 fe_values_side_.reinit(elm_acc, side.
side_idx());
251 fsv_rt_.reinit(elm_acc, side.
side_idx());
253 calculate_velocity(elm_acc, velocity_, fsv_rt_.point_list());
254 model_.compute_advection_diffusion_coefficients(fe_values_side_.point_list(), velocity_, elm_acc, data_->ad_coef, data_->dif_coef);
257 data_->cross_section.value_list(fe_values_side_.point_list(), elm_acc, csection_);
259 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
261 std::fill(local_matrix_.begin(), local_matrix_.end(), 0);
265 double side_flux = 0;
266 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
267 side_flux += arma::dot(data_->ad_coef[sbi][k], fe_values_side_.normal_vector(k))*fe_values_side_.JxW(k);
268 double transport_flux = side_flux/side.
measure();
274 data_->set_DG_parameters_boundary(side, qsize_lower_dim_, data_->dif_coef[sbi], transport_flux, fe_values_side_.normal_vector(0), data_->dg_penalty[sbi].value(elm_acc.centre(), elm_acc), gamma_l);
275 data_->gamma[sbi][side.
cond_idx()] = gamma_l;
276 transport_flux += gamma_l;
280 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
282 double flux_times_JxW;
286 model_.get_flux_bc_sigma(sbi, fe_values_side_.point_list(), side.
cond()->
element_accessor(), sigma_);
287 flux_times_JxW = csection_[k]*sigma_[k]*fe_values_side_.JxW(k);
291 model_.get_flux_bc_sigma(sbi, fe_values_side_.point_list(), side.
cond()->
element_accessor(), sigma_);
292 flux_times_JxW = (transport_flux + csection_[k]*sigma_[k])*fe_values_side_.JxW(k);
297 flux_times_JxW = transport_flux*fe_values_side_.JxW(k);
299 for (
unsigned int i=0; i<ndofs_; i++)
301 for (
unsigned int j=0; j<ndofs_; j++)
304 local_matrix_[i*ndofs_+j] += flux_times_JxW*fe_values_side_.shape_value(i,k)*fe_values_side_.shape_value(j,k);
308 local_matrix_[i*ndofs_+j] -= (arma::dot(data_->dif_coef[sbi][k]*fe_values_side_.shape_grad(j,k),fe_values_side_.normal_vector(k))*fe_values_side_.shape_value(i,k)
309 + arma::dot(data_->dif_coef[sbi][k]*fe_values_side_.shape_grad(i,k),fe_values_side_.normal_vector(k))*fe_values_side_.shape_value(j,k)*data_->dg_variant
310 )*fe_values_side_.JxW(k);
315 data_->ls[sbi]->mat_set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]));
329 if (cell_side.n_edge_sides() < 2)
continue;
330 bool unique_edge = (cell_side.edge_sides().begin()->element().idx() != cell.
elm_idx());
331 if ( unique_edge )
continue;
335 auto dh_edge_cell = data_->dh_->cell_accessor_from_element( edge_side.elem_idx() );
337 dh_edge_cell.get_dof_indices(side_dof_indices_[sid]);
338 fe_values_vec_[sid]->reinit(edg_elm, edge_side.side_idx());
339 fsv_rt_.reinit(edg_elm, edge_side.side_idx());
340 calculate_velocity(edg_elm, side_velocity_vec_[sid], fsv_rt_.point_list());
341 model_.compute_advection_diffusion_coefficients(fe_values_vec_[sid]->point_list(), side_velocity_vec_[sid], edg_elm, data_->ad_coef_edg[sid], data_->dif_coef_edg[sid]);
342 dg_penalty_[sid].resize(model_.n_substances());
343 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
344 dg_penalty_[sid][sbi] = data_->dg_penalty[sbi].value(edg_elm.
centre(), edg_elm);
347 arma::vec3 normal_vector = fe_values_vec_[0]->normal_vector(0);
350 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
353 double pflux = 0, nflux = 0;
358 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
359 fluxes[sid] += arma::dot(data_->ad_coef_edg[sid][sbi][k], fe_values_vec_[sid]->normal_vector(k))*fe_values_vec_[sid]->JxW(k);
360 fluxes[sid] /= edge_side.measure();
362 pflux += fluxes[sid];
364 nflux += fluxes[sid];
375 if (s2<=s1)
continue;
376 ASSERT(edge_side1.is_valid()).error(
"Invalid side of edge.");
378 arma::vec3 nv = fe_values_vec_[s1]->normal_vector(0);
382 if (fluxes[s2] > 0 && fluxes[s1] < 0)
383 transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
384 else if (fluxes[s2] < 0 && fluxes[s1] > 0)
385 transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
389 gamma_l = 0.5*fabs(transport_flux);
393 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
395 delta[0] += dot(data_->dif_coef_edg[s1][sbi][k]*normal_vector,normal_vector);
396 delta[1] += dot(data_->dif_coef_edg[s2][sbi][k]*normal_vector,normal_vector);
398 delta[0] /= qsize_lower_dim_;
399 delta[1] /= qsize_lower_dim_;
401 delta_sum = delta[0] + delta[1];
404 if (fabs(delta_sum) > 0)
406 omega[0] = delta[1]/delta_sum;
407 omega[1] = delta[0]/delta_sum;
408 double local_alpha = max(dg_penalty_[s1][sbi], dg_penalty_[s2][sbi]);
409 double h = edge_side1.diameter();
410 aniso1 = data_->elem_anisotropy(edge_side1.element());
411 aniso2 = data_->elem_anisotropy(edge_side2.element());
412 gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
415 for (
int i=0; i<2; i++) omega[i] = 0;
418 int sd[2];
bool is_side_own[2];
419 sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
420 sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
422 #define AVERAGE(i,k,side_id) (fe_values_vec_[sd[side_id]]->shape_value(i,k)*0.5) 423 #define WAVERAGE(i,k,side_id) (arma::dot(data_->dif_coef_edg[sd[side_id]][sbi][k]*fe_values_vec_[sd[side_id]]->shape_grad(i,k),nv)*omega[side_id]) 424 #define JUMP(i,k,side_id) ((side_id==0?1:-1)*fe_values_vec_[sd[side_id]]->shape_value(i,k)) 427 for (
int n=0; n<2; n++)
429 if (!is_side_own[n])
continue;
431 for (
int m=0; m<2; m++)
433 for (
unsigned int i=0; i<fe_values_vec_[sd[n]]->n_dofs(); i++)
434 for (
unsigned int j=0; j<fe_values_vec_[sd[m]]->n_dofs(); j++)
435 local_matrix_[i*fe_values_vec_[sd[m]]->n_dofs()+j] = 0;
437 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
439 double flux_times_JxW = transport_flux*fe_values_vec_[0]->JxW(k);
440 double gamma_times_JxW = gamma_l*fe_values_vec_[0]->JxW(k);
442 for (
unsigned int i=0; i<fe_values_vec_[sd[n]]->n_dofs(); i++)
444 double flux_JxW_jump_i = flux_times_JxW*
JUMP(i,k,n);
445 double gamma_JxW_jump_i = gamma_times_JxW*
JUMP(i,k,n);
446 double JxW_jump_i = fe_values_vec_[0]->JxW(k)*
JUMP(i,k,n);
447 double JxW_var_wavg_i = fe_values_vec_[0]->JxW(k)*
WAVERAGE(i,k,n)*data_->dg_variant;
449 for (
unsigned int j=0; j<fe_values_vec_[sd[m]]->n_dofs(); j++)
451 int index = i*fe_values_vec_[sd[m]]->n_dofs()+j;
454 local_matrix_[index] += flux_JxW_jump_i*
AVERAGE(j,k,m);
457 local_matrix_[index] += gamma_JxW_jump_i*
JUMP(j,k,m);
460 local_matrix_[index] -=
WAVERAGE(j,k,m)*JxW_jump_i;
461 local_matrix_[index] -=
JUMP(j,k,m)*JxW_var_wavg_i;
465 data_->ls[sbi]->mat_set_values(fe_values_vec_[sd[n]]->n_dofs(), &(side_dof_indices_[sd[n]][0]), fe_values_vec_[sd[m]]->n_dofs(), &(side_dof_indices_[sd[m]][0]), &(local_matrix_[0]));
483 if (dim == 1)
return;
484 ASSERT_EQ_DBG(cell_lower_dim.
dim(), dim-1).error(
"Dimension of element mismatch!");
491 if (cell_lower_dim.
dim() != dim-1)
continue;
495 for(
unsigned int i=0; i<n_indices; ++i) {
496 side_dof_indices_vb_[i] = dof_indices_[i];
498 fe_values_vb_->reinit(elm_lower_dim);
499 n_dofs[0] = fv_sb_[0]->n_dofs();
501 DHCellAccessor cell_higher_dim = data_->dh_->cell_accessor_from_element( neighb_side.element().idx() );
504 for(
unsigned int i=0; i<n_indices; ++i) {
505 side_dof_indices_vb_[i+n_dofs[0]] = dof_indices_[i];
507 fe_values_side_.reinit(elm_higher_dim, neighb_side.side_idx());
508 n_dofs[1] = fv_sb_[1]->n_dofs();
511 bool own_element_id[2];
512 own_element_id[0] = cell_lower_dim.
is_own();
513 own_element_id[1] = cell_higher_dim.
is_own();
515 fsv_rt_.reinit(elm_higher_dim, neighb_side.side_idx());
516 fv_rt_vb_->reinit(elm_lower_dim);
517 calculate_velocity(elm_higher_dim, velocity_higher_, fsv_rt_.point_list());
518 calculate_velocity(elm_lower_dim, velocity_, fv_rt_vb_->point_list());
519 model_.compute_advection_diffusion_coefficients(fe_values_vb_->point_list(), velocity_, elm_lower_dim, data_->ad_coef_edg[0], data_->dif_coef_edg[0]);
520 model_.compute_advection_diffusion_coefficients(fe_values_vb_->point_list(), velocity_higher_, elm_higher_dim, data_->ad_coef_edg[1], data_->dif_coef_edg[1]);
521 data_->cross_section.value_list(fe_values_vb_->point_list(), elm_lower_dim, csection_);
522 data_->cross_section.value_list(fe_values_vb_->point_list(), elm_higher_dim, csection_higher_);
524 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
526 for (
unsigned int i=0; i<n_dofs[0]+n_dofs[1]; i++)
527 for (
unsigned int j=0; j<n_dofs[0]+n_dofs[1]; j++)
528 local_matrix_[i*(n_dofs[0]+n_dofs[1])+j] = 0;
531 data_->fracture_sigma[sbi].value_list(fe_values_vb_->point_list(), elm_lower_dim, sigma_);
534 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
543 double sigma = sigma_[k]*arma::dot(data_->dif_coef_edg[0][sbi][k]*fe_values_side_.normal_vector(k),fe_values_side_.normal_vector(k))*
544 2*csection_higher_[k]*csection_higher_[k]/(csection_[k]*csection_[k]);
546 double transport_flux = arma::dot(data_->ad_coef_edg[1][sbi][k], fe_values_side_.normal_vector(k));
548 comm_flux[0][0] = (sigma-min(0.,transport_flux))*fv_sb_[0]->JxW(k);
549 comm_flux[0][1] = -(sigma-min(0.,transport_flux))*fv_sb_[0]->JxW(k);
550 comm_flux[1][0] = -(sigma+max(0.,transport_flux))*fv_sb_[0]->JxW(k);
551 comm_flux[1][1] = (sigma+max(0.,transport_flux))*fv_sb_[0]->JxW(k);
553 for (
int n=0; n<2; n++)
555 if (!own_element_id[n])
continue;
557 for (
unsigned int i=0; i<n_dofs[n]; i++)
558 for (
int m=0; m<2; m++)
559 for (
unsigned int j=0; j<n_dofs[m]; j++)
560 local_matrix_[(i+n*n_dofs[0])*(n_dofs[0]+n_dofs[1]) + m*n_dofs[0] + j] +=
561 comm_flux[m][n]*fv_sb_[m]->shape_value(j,k)*fv_sb_[n]->shape_value(i,k);
564 data_->ls[sbi]->mat_set_values(n_dofs[0]+n_dofs[1], &(side_dof_indices_vb_[0]), n_dofs[0]+n_dofs[1], &(side_dof_indices_vb_[0]), &(local_matrix_[0]));
578 fe_values_.reinit(elm);
581 model_.compute_source_coefficients(fe_values_.point_list(), elm, sources_conc_, sources_density_, sources_sigma_);
584 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
586 fill_n( &(local_rhs_[0]), ndofs_, 0 );
587 local_source_balance_vector_.assign(ndofs_, 0);
588 local_source_balance_rhs_.assign(ndofs_, 0);
591 for (
unsigned int k=0; k<qsize_; k++)
593 source = (sources_density_[sbi][k] + sources_conc_[sbi][k]*sources_sigma_[sbi][k])*fe_values_.JxW(k);
595 for (
unsigned int i=0; i<ndofs_; i++)
596 local_rhs_[i] += source*fe_values_.shape_value(i,k);
598 data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
600 for (
unsigned int i=0; i<ndofs_; i++)
602 for (
unsigned int k=0; k<qsize_; k++)
603 local_source_balance_vector_[i] -= sources_sigma_[sbi][k]*fe_values_.shape_value(i,k)*fe_values_.JxW(k);
605 local_source_balance_rhs_[i] += local_rhs_[i];
609 model_.balance()->add_source_values(model_.get_subst_idx()[sbi], elm.
region().
bulk_idx(), loc_dof_indices_,
610 local_source_balance_vector_, local_source_balance_rhs_);
619 for (
unsigned int si=0; si<cell.
elm()->
n_sides(); si++)
622 if (edg->
n_sides > 1)
continue;
624 if (edg->
side(0)->
cond() == NULL)
continue;
632 model_.get_bc_type(ele_acc, bc_type);
634 fe_values_side_.reinit(elm, side.
side_idx());
635 fsv_rt_.reinit(elm, side.
side_idx());
636 calculate_velocity(elm, velocity_, fsv_rt_.point_list());
638 model_.compute_advection_diffusion_coefficients(fe_values_side_.point_list(), velocity_, side.
element(), data_->ad_coef, data_->dif_coef);
639 data_->cross_section.value_list(fe_values_side_.point_list(), side.
element(), csection_);
644 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
646 fill_n(&(local_rhs_[0]), ndofs_, 0);
647 local_flux_balance_vector_.assign(ndofs_, 0);
648 local_flux_balance_rhs_ = 0;
652 data_->bc_dirichlet_value[sbi].value_list(fe_values_side_.point_list(), ele_acc, bc_values_);
654 double side_flux = 0;
655 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
656 side_flux += arma::dot(data_->ad_coef[sbi][k], fe_values_side_.normal_vector(k))*fe_values_side_.JxW(k);
657 double transport_flux = side_flux/side.
measure();
661 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
663 double bc_term = -transport_flux*bc_values_[k]*fe_values_side_.JxW(k);
664 for (
unsigned int i=0; i<ndofs_; i++)
665 local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k);
667 for (
unsigned int i=0; i<ndofs_; i++)
668 local_flux_balance_rhs_ -= local_rhs_[i];
672 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
674 double bc_term = data_->gamma[sbi][side.
cond_idx()]*bc_values_[k]*fe_values_side_.JxW(k);
675 arma::vec3 bc_grad = -bc_values_[k]*fe_values_side_.JxW(k)*data_->dg_variant*(arma::trans(data_->dif_coef[sbi][k])*fe_values_side_.normal_vector(k));
676 for (
unsigned int i=0; i<ndofs_; i++)
677 local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k)
678 + arma::dot(bc_grad,fe_values_side_.shape_grad(i,k));
680 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
682 for (
unsigned int i=0; i<ndofs_; i++)
684 local_flux_balance_vector_[i] += (arma::dot(data_->ad_coef[sbi][k], fe_values_side_.normal_vector(k))*fe_values_side_.shape_value(i,k)
685 - arma::dot(data_->dif_coef[sbi][k]*fe_values_side_.shape_grad(i,k),fe_values_side_.normal_vector(k))
686 + data_->gamma[sbi][side.
cond_idx()]*fe_values_side_.shape_value(i,k))*fe_values_side_.JxW(k);
689 if (model_.time().tlevel() > 0)
690 for (
unsigned int i=0; i<ndofs_; i++)
691 local_flux_balance_rhs_ -= local_rhs_[i];
695 model_.get_flux_bc_data(sbi, fe_values_side_.point_list(), ele_acc, bc_fluxes_, sigma_, bc_ref_values_);
696 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
698 double bc_term = csection_[k]*(sigma_[k]*bc_ref_values_[k]+bc_fluxes_[k])*fe_values_side_.JxW(k);
699 for (
unsigned int i=0; i<ndofs_; i++)
700 local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k);
703 for (
unsigned int i=0; i<ndofs_; i++)
705 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
706 local_flux_balance_vector_[i] += csection_[k]*sigma_[k]*fe_values_side_.JxW(k)*fe_values_side_.shape_value(i,k);
707 local_flux_balance_rhs_ -= local_rhs_[i];
712 model_.get_flux_bc_data(sbi, fe_values_side_.point_list(), ele_acc, bc_fluxes_, sigma_, bc_ref_values_);
713 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
715 double bc_term = csection_[k]*(sigma_[k]*bc_ref_values_[k]+bc_fluxes_[k])*fe_values_side_.JxW(k);
716 for (
unsigned int i=0; i<ndofs_; i++)
717 local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k);
720 for (
unsigned int i=0; i<ndofs_; i++)
722 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
723 local_flux_balance_vector_[i] += csection_[k]*(arma::dot(data_->ad_coef[sbi][k], fe_values_side_.normal_vector(k)) + sigma_[k])*fe_values_side_.JxW(k)*fe_values_side_.shape_value(i,k);
724 local_flux_balance_rhs_ -= local_rhs_[i];
729 for (
unsigned int k=0; k<qsize_lower_dim_; k++)
731 for (
unsigned int i=0; i<ndofs_; i++)
732 local_flux_balance_vector_[i] += arma::dot(data_->ad_coef[sbi][k], fe_values_side_.normal_vector(k))*fe_values_side_.JxW(k)*fe_values_side_.shape_value(i,k);
735 data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
737 model_.balance()->add_flux_matrix_values(model_.get_subst_idx()[sbi], side, dof_indices_, local_flux_balance_vector_);
738 model_.balance()->add_flux_vec_value(model_.get_subst_idx()[sbi], side, local_flux_balance_rhs_);
754 fe_values_.reinit(elem);
755 model_.compute_init_cond(fe_values_.point_list(), elem, init_values_);
757 for (
unsigned int sbi=0; sbi<model_.n_substances(); sbi++)
759 for (
unsigned int i=0; i<ndofs_; i++)
762 for (
unsigned int j=0; j<ndofs_; j++)
763 local_matrix_[i*ndofs_+j] = 0;
766 for (
unsigned int k=0; k<qsize_; k++)
768 double rhs_term = init_values_[sbi][k]*fe_values_.JxW(k);
770 for (
unsigned int i=0; i<ndofs_; i++)
772 for (
unsigned int j=0; j<ndofs_; j++)
773 local_matrix_[i*ndofs_+j] += fe_values_.shape_value(i,k)*fe_values_.shape_value(j,k)*fe_values_.JxW(k);
775 local_rhs_[i] += fe_values_.shape_value(i,k)*rhs_term;
778 data_->ls[sbi]->set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]), &(local_rhs_[0]));
792 const std::vector<arma::vec::fixed<3>> &point_list)
794 velocity.resize(point_list.size());
795 model_.velocity_field_ptr()->value_list(point_list, cell, velocity);
799 shared_ptr<FiniteElement<dim>>
fe_;
869 double comm_flux[2][2];
vector< vector< double > > ret_coef_
Retardation coefficient due to sorption.
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
void set_boundary_conditions(DHCellAccessor cell) override
unsigned int n_sides() const
Returns number of sides aligned with the edge.
Range< DHCellSide > side_range() const
Returns range of cell sides.
Transformed quadrature weight for cell sides.
#define ASSERT_EQ_DBG(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
unsigned int elm_idx() const
Return serial idx to element of loc_ele_idx_.
shared_ptr< FiniteElement< dim-1 > > fe_low_
Finite element for the solution of the advection-diffusion equation (dim-1).
unsigned int * boundary_idx_
unsigned int side_idx() const
Returns local index of the side on the element.
Transport with dispersion implemented using discontinuous Galerkin method.
FESideValues< dim, 3 > fsv_rt_
FESideValues of object (of RT0 finite element type)
unsigned int ndofs_
Number of dofs.
vector< vector< double > > sources_sigma_
Auxiliary vectors for assemble volume integrals and set_sources method.
unsigned int get_dof_indices(std::vector< LongIdx > &indices) const
Fill vector of the global indices of dofs associated to the cell.
PetscScalar local_flux_balance_rhs_
Auxiliary variable for set_boundary_conditions method.
Edge edge() const
Returns pointer to the edge connected to the side.
#define WAVERAGE(i, k, side_id)
vector< LongIdx > dof_indices_
Vector of global DOF indices.
vector< vector< arma::vec3 > > side_velocity_vec_
Vector of velocities results.
vector< LongIdx > loc_dof_indices_
Vector of local DOF indices.
unsigned int dim() const
Return dimension of element appropriate to cell.
vector< PetscScalar > local_retardation_balance_vector_
Auxiliary vector for assemble mass matrix.
unsigned int n_dofs() const
Returns the number of shape functions.
#define AVERAGE(i, k, side_id)
Cell accessor allow iterate over DOF handler cells.
Class FEValues calculates finite element data on the actual cells such as shape function values...
vector< double > bc_fluxes_
Same as previous.
vector< PetscScalar > local_source_balance_vector_
Auxiliary vector for set_sources method.
LocDofVec get_loc_dof_indices() const
Returns the local indices of dofs associated to the cell on the local process.
SideIter side(const unsigned int loc_index)
virtual void assemble_volume_integrals(DHCellAccessor cell)=0
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
virtual void assemble_fluxes_element_element(DHCellAccessor cell)=0
vector< LongIdx > side_dof_indices_vb_
Vector of side DOF indices (assemble element-side fluxex)
bool is_own() const
Return true if accessor represents own element (false for ghost element)
ElementAccessor< 3 > element() const
Returns iterator to the element of the side.
FEValues< dim, 3 > fv_rt_
FEValues of object (of RT0 finite element type)
virtual void set_boundary_conditions(DHCellAccessor cell)=0
virtual void assemble_fluxes_element_side(DHCellAccessor cell_lower_dim)=0
virtual void prepare_initial_condition(DHCellAccessor cell)=0
vector< double > bc_ref_values_
Same as previous.
Base class for quadrature rules on simplices in arbitrary dimensions.
void initialize() override
Initialize auxiliary vectors and other data members.
Symmetric Gauss-Legendre quadrature formulae on simplices.
void set_sources(DHCellAccessor cell) override
Assembles the right hand side vector due to volume sources.
arma::vec::fixed< spacedim > centre() const
Computes the barycenter.
Discontinuous Lagrangean finite element on dim dimensional simplex.
Transformed quadrature points.
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
FiniteElement< dim-1 > * fe_rt_low_
Finite element for the water velocity field (dim-1).
vector< FEValuesSpaceBase< 3 > * > fv_sb_
Auxiliary vector, holds FEValues objects for assemble element-side.
unsigned int dim() const
Returns dimension of the side, that is dimension of the element minus one.
vector< PetscScalar > local_flux_balance_vector_
Auxiliary vector for set_boundary_conditions method.
vector< vector< LongIdx > > side_dof_indices_
Vector of vectors of side DOF indices.
virtual void assemble_fluxes_boundary(DHCellAccessor cell)=0
vector< vector< double > > sources_density_
Auxiliary vectors for set_sources method.
RangeConvert< DHEdgeSide, DHCellSide > edge_sides() const
Returns range of all sides looped over common Edge.
void prepare_initial_condition(DHCellAccessor cell) override
Assembles the auxiliary linear system to calculate the initial solution as L^2-projection of the pres...
vector< vector< double > > dg_penalty_
Auxiliary vectors for assemble element-element fluxes.
Raviart-Thomas element of order 0.
Definitions of basic Lagrangean finite elements with polynomial shape functions.
unsigned int n_sides() const
RangeConvert< DHNeighbSide, DHCellSide > neighb_sides() const
Returns range of neighbour cell of lower dimension corresponding to cell of higher dimension...
virtual void initialize()=0
vector< PetscScalar > local_mass_balance_vector_
Same as previous.
FiniteElement< dim > * fe_rt_
Finite element for the water velocity field.
void assemble_fluxes_element_element(DHCellAccessor cell) override
Assembles the fluxes between elements of the same dimension.
Quadrature * quad_low_
Quadrature used in assembling methods (dim-1).
vector< double > csection_higher_
Auxiliary vector for assemble element-side fluxes.
Shape function gradients.
unsigned int qsize_
Size of quadrature of actual dim.
TransportDG< Model > & model_
Reference to model (we must use common ancestor of concentration and heat model)
vector< arma::vec3 > velocity_higher_
Velocity results of higher dim element (element-side computation).
void assemble_volume_integrals(DHCellAccessor cell) override
Assembles the volume integrals into the stiffness matrix.
double measure() const
Calculate metrics of the side.
std::vector< std::vector< double > > init_values_
Auxiliary vectors for prepare initial condition.
FEValues< dim-1, 3 > * fv_rt_vb_
FEValues of dim-1 object (of RT0 finite element type)
Quadrature * quad_
Quadrature used in assembling methods.
Discontinuous Galerkin method for equation of transport with dispersion.
vector< double > csection_
Auxiliary vector for assemble boundary fluxes, element-side fluxes and set boundary conditions...
#define JUMP(i, k, side_id)
vector< double > mm_coef_
Mass matrix coefficients.
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
unsigned int cond_idx() const
Returns global index of the prescribed boundary condition.
shared_ptr< FiniteElement< dim > > fe_
Finite element for the solution of the advection-diffusion equation.
unsigned int qsize_lower_dim_
Size of quadrature of dim-1.
FEValues< dim-1, 3 > * fe_values_vb_
FEValues of dim-1 object (of P disc finite element type)
FEValues< dim, 3 > fe_values_
FEValues of object (of P disc finite element type)
virtual ~AssemblyDGBase()
vector< arma::vec3 > velocity_
Auxiliary results.
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
Definitions of particular quadrature rules on simplices.
Calculates finite element data on the actual cell.
FESideValues< dim, 3 > fe_values_side_
FESideValues of object (of P disc finite element type)
AssemblyDG(std::shared_ptr< EqDataDG > data, TransportDG< Model > &model)
Constructor.
vector< FESideValues< dim, 3 > * > fe_values_vec_
Vector of FESideValues of object (of P disc finite element types)
TransportDG< Model >::EqData EqDataDG
vector< vector< double > > sources_conc_
Auxiliary vectors for set_sources method.
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
void assemble_fluxes_element_side(DHCellAccessor cell_lower_dim) override
Assembles the fluxes between elements of different dimensions.
std::shared_ptr< EqDataDG > data_
Data object shared with TransportDG.
void assemble_fluxes_boundary(DHCellAccessor cell) override
Assembles the fluxes on the boundary.
vector< double > bc_values_
Auxiliary vector for set boundary conditions method.
virtual void set_sources(DHCellAccessor cell)=0
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
void calculate_velocity(const ElementAccessor< 3 > &cell, vector< arma::vec3 > &velocity, const std::vector< arma::vec::fixed< 3 >> &point_list)
Calculates the velocity field on a given cell.
SideIter side(const unsigned int i) const
Gets side iterator of the i -th side.
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
Definitions of Raviart-Thomas finite elements.
vector< double > sigma_
Auxiliary vector for assemble boundary fluxes (robin sigma), element-side fluxes (frac sigma) and set...
Side accessor allows to iterate over sides of DOF handler cell.
vector< PetscScalar > local_source_balance_rhs_
Auxiliary vector for set_sources method.
ElementAccessor< 3 > element_accessor()
virtual void assemble_mass_matrix(DHCellAccessor cell)=0
void assemble_mass_matrix(DHCellAccessor cell) override
Assemble integral over element.
Transformed quadrature weights.