Flow123d  JS_before_hm-1623-gd361259
assembly_dg.hh
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file assembly_dg.hh
15  * @brief
16  */
17 
18 #ifndef ASSEMBLY_DG_HH_
19 #define ASSEMBLY_DG_HH_
20 
24 #include "fem/fe_p.hh"
25 #include "fem/fe_values.hh"
27 #include "coupling/balance.hh"
29 
30 
31 
32 /**
33  * Auxiliary container class for Finite element and related objects of given dimension.
34  */
35 template <unsigned int dim, class Model>
36 class MassAssemblyDG : public AssemblyBase<dim>
37 {
38 public:
41 
42  static constexpr const char * name() { return "MassAssemblyDG"; }
43 
44  /// Constructor.
45  MassAssemblyDG(EqFields *eq_fields, EqData *eq_data)
46  : AssemblyBase<dim>(eq_data->dg_order), eq_fields_(eq_fields), eq_data_(eq_data) {
48  this->used_fields_ += eq_fields_->mass_matrix_coef;
49  this->used_fields_ += eq_fields_->retardation_coef;
50  }
51 
52  /// Destructor.
54 
55  /// Initialize auxiliary vectors and other data members
56  void initialize(ElementCacheMap *element_cache_map) {
57  this->element_cache_map_ = element_cache_map;
58 
59  fe_ = std::make_shared< FE_P_disc<dim> >(eq_data_->dg_order);
61  fe_values_.initialize(*this->quad_, *fe_, u);
62  if (dim==1) // print to log only one time
63  DebugOut() << "List of MassAssembly FEValues updates flags: " << this->print_update_flags(u);
64  ndofs_ = fe_->n_dofs();
65  dof_indices_.resize(ndofs_);
66  local_matrix_.resize(4*ndofs_*ndofs_);
67  local_retardation_balance_vector_.resize(ndofs_);
68  local_mass_balance_vector_.resize(ndofs_);
69 
70  }
71 
72 
73  /// Assemble integral over element
74  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
75  {
76  ASSERT_EQ_DBG(cell.dim(), dim).error("Dimension of element mismatch!");
77 
78  ElementAccessor<3> elm = cell.elm();
79  unsigned int k;
80 
81  fe_values_.reinit(elm);
83 
84  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); ++sbi)
85  {
86  // assemble the local mass matrix
87  for (unsigned int i=0; i<ndofs_; i++)
88  {
89  for (unsigned int j=0; j<ndofs_; j++)
90  {
91  local_matrix_[i*ndofs_+j] = 0;
92  k=0;
93  for (auto p : this->bulk_points(element_patch_idx) )
94  {
95  local_matrix_[i*ndofs_+j] += (eq_fields_->mass_matrix_coef(p)+eq_fields_->retardation_coef[sbi](p)) *
97  k++;
98  }
99  }
100  }
101 
102  for (unsigned int i=0; i<ndofs_; i++)
103  {
106  k=0;
107  for (auto p : this->bulk_points(element_patch_idx) )
108  {
109  local_mass_balance_vector_[i] += eq_fields_->mass_matrix_coef(p)*fe_values_.shape_value(i,k)*fe_values_.JxW(k);
110  local_retardation_balance_vector_[i] -= eq_fields_->retardation_coef[sbi](p)*fe_values_.shape_value(i,k)*fe_values_.JxW(k);
111  k++;
112  }
113  }
114 
115  eq_data_->balance_->add_mass_values(eq_data_->subst_idx()[sbi], cell, cell.get_loc_dof_indices(),
117 
118  eq_data_->ls_dt[sbi]->mat_set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]));
119  VecSetValues(eq_data_->ret_vec[sbi], ndofs_, &(dof_indices_[0]), &(local_retardation_balance_vector_[0]), ADD_VALUES);
120  }
121  }
122 
123  /// Implements @p AssemblyBase::begin.
124  void begin() override
125  {
126  eq_data_->balance_->start_mass_assembly( eq_data_->subst_idx() );
127  }
128 
129  /// Implements @p AssemblyBase::end.
130  void end() override
131  {
132  eq_data_->balance_->finish_mass_assembly( eq_data_->subst_idx() );
133  }
134 
135  private:
136  shared_ptr<FiniteElement<dim>> fe_; ///< Finite element for the solution of the advection-diffusion equation.
137 
138  /// Data objects shared with TransportDG
139  EqFields *eq_fields_;
140  EqData *eq_data_;
141 
142  /// Sub field set contains fields used in calculation.
144 
145  unsigned int ndofs_; ///< Number of dofs
146  FEValues<3> fe_values_; ///< FEValues of object (of P disc finite element type)
147 
148  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
149  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
150  vector<PetscScalar> local_retardation_balance_vector_; ///< Auxiliary vector for assemble mass matrix.
152 
153  template < template<IntDim...> class DimAssembly>
154  friend class GenericAssembly;
155 
156 };
157 
158 
159 /**
160  * Auxiliary container class for Finite element and related objects of given dimension.
161  */
162 template <unsigned int dim, class Model>
164 {
165 public:
168 
169  static constexpr const char * name() { return "StiffnessAssemblyDG"; }
170 
171  /// Constructor.
172  StiffnessAssemblyDG(EqFields *eq_fields, EqData *eq_data)
173  : AssemblyBase<dim>(eq_data->dg_order), eq_fields_(eq_fields), eq_data_(eq_data) {
175  this->used_fields_ += eq_fields_->advection_coef;
176  this->used_fields_ += eq_fields_->diffusion_coef;
177  this->used_fields_ += eq_fields_->cross_section;
179  this->used_fields_ += eq_fields_->sources_sigma_out;
181  this->used_fields_ += eq_fields_->bc_type;
182  this->used_fields_ += eq_fields_->bc_robin_sigma;
183  }
184 
185  /// Destructor.
187  for (auto a : averages) if (a != nullptr) delete[] a;
188  for (auto a : waverages) if (a != nullptr) delete[] a;
189  for (auto a : jumps) if (a != nullptr) delete[] a;
190  }
191 
192  /// Initialize auxiliary vectors and other data members
193  void initialize(ElementCacheMap *element_cache_map) {
194  this->element_cache_map_ = element_cache_map;
195 
196  fe_ = std::make_shared< FE_P_disc<dim> >(eq_data_->dg_order);
197  fe_low_ = std::make_shared< FE_P_disc<dim-1> >(eq_data_->dg_order);
200  fe_values_.initialize(*this->quad_, *fe_, u);
201  if (dim>1) {
202  fe_values_vb_.initialize(*this->quad_low_, *fe_low_, u);
203  }
204  fe_values_side_.initialize(*this->quad_low_, *fe_, u_side);
205  if (dim==1) { // print to log only one time
206  DebugOut() << "List of StiffnessAssemblyDG FEValues (cell) updates flags: " << this->print_update_flags(u);
207  DebugOut() << "List of StiffnessAssemblyDG FEValues (side) updates flags: " << this->print_update_flags(u_side);
208  }
209  ndofs_ = fe_->n_dofs();
210  qsize_lower_dim_ = this->quad_low_->size();
211  dof_indices_.resize(ndofs_);
212  side_dof_indices_vb_.resize(2*ndofs_);
213  local_matrix_.resize(4*ndofs_*ndofs_);
214 
215  fe_values_vec_.resize(eq_data_->max_edg_sides);
216  for (unsigned int sid=0; sid<eq_data_->max_edg_sides; sid++)
217  {
218  side_dof_indices_.push_back( vector<LongIdx>(ndofs_) );
219  fe_values_vec_[sid].initialize(*this->quad_low_, *fe_,
221  }
222 
223  // index 0 = element with lower dimension,
224  // index 1 = side of element with higher dimension
225  fv_sb_.resize(2);
226  fv_sb_[0] = &fe_values_vb_;
227  fv_sb_[1] = &fe_values_side_;
228 
229  averages.resize(eq_data_->max_edg_sides);
230  for (unsigned int s=0; s<eq_data_->max_edg_sides; s++)
231  averages[s] = new double[qsize_lower_dim_*fe_->n_dofs()];
232  waverages.resize(2);
233  jumps.resize(2);
234  for (unsigned int s=0; s<2; s++)
235  {
236  waverages[s] = new double[qsize_lower_dim_*fe_->n_dofs()];
237  jumps[s] = new double[qsize_lower_dim_*fe_->n_dofs()];
238  }
239  }
240 
241 
242  /// Assembles the cell (volume) integral into the stiffness matrix.
243  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
244  {
245  ASSERT_EQ_DBG(cell.dim(), dim).error("Dimension of element mismatch!");
246  if (!cell.is_own()) return;
247 
248  ElementAccessor<3> elm = cell.elm();
249 
250  fe_values_.reinit(elm);
252  unsigned int k;
253 
254  // assemble the local stiffness matrix
255  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
256  {
257  for (unsigned int i=0; i<ndofs_; i++)
258  for (unsigned int j=0; j<ndofs_; j++)
259  local_matrix_[i*ndofs_+j] = 0;
260 
261  k=0;
262  for (auto p : this->bulk_points(element_patch_idx) )
263  {
264  for (unsigned int i=0; i<ndofs_; i++)
265  {
266  arma::vec3 Kt_grad_i = eq_fields_->diffusion_coef[sbi](p).t()*fe_values_.shape_grad(i,k);
267  double ad_dot_grad_i = arma::dot(eq_fields_->advection_coef[sbi](p), fe_values_.shape_grad(i,k));
268 
269  for (unsigned int j=0; j<ndofs_; j++)
270  local_matrix_[i*ndofs_+j] += (arma::dot(Kt_grad_i, fe_values_.shape_grad(j,k))
271  -fe_values_.shape_value(j,k)*ad_dot_grad_i
272  +eq_fields_->sources_sigma_out[sbi](p)*fe_values_.shape_value(j,k)*fe_values_.shape_value(i,k))*fe_values_.JxW(k);
273  }
274  k++;
275  }
276  eq_data_->ls[sbi]->mat_set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]));
277  }
278  }
279 
280 
281  /// Assembles the fluxes on the boundary.
282  inline void boundary_side_integral(DHCellSide cell_side)
283  {
284  ASSERT_EQ_DBG(cell_side.dim(), dim).error("Dimension of element mismatch!");
285  if (!cell_side.cell().is_own()) return;
286 
287  Side side = cell_side.side();
288  const DHCellAccessor &cell = cell_side.cell();
289 
291  fe_values_side_.reinit(side);
292  unsigned int k;
293  double gamma_l;
294 
295  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
296  {
297  std::fill(local_matrix_.begin(), local_matrix_.end(), 0);
298 
299  // On Neumann boundaries we have only term from integrating by parts the advective term,
300  // on Dirichlet boundaries we additionally apply the penalty which enforces the prescribed value.
301  double side_flux = 0;
302  k=0;
303  for (auto p : this->boundary_points(cell_side) ) {
304  side_flux += arma::dot(eq_fields_->advection_coef[sbi](p), fe_values_side_.normal_vector(k))*fe_values_side_.JxW(k);
305  k++;
306  }
307  double transport_flux = side_flux/side.measure();
308 
309  auto p_side = *( this->boundary_points(cell_side).begin() );
310  auto p_bdr = p_side.point_bdr( side.cond().element_accessor() );
311  unsigned int bc_type = eq_fields_->bc_type[sbi](p_bdr);
313  {
314  // set up the parameters for DG method
315  k=0; // temporary solution, set dif_coef until set_DG_parameters_boundary will not be removed
316  for (auto p : this->boundary_points(cell_side) ) {
317  eq_data_->dif_coef[sbi][k] = eq_fields_->diffusion_coef[sbi](p);
318  k++;
319  }
320  eq_data_->set_DG_parameters_boundary(side, qsize_lower_dim_, eq_data_->dif_coef[sbi], transport_flux, fe_values_side_.normal_vector(0), eq_fields_->dg_penalty[sbi](p_side), gamma_l);
321  eq_data_->gamma[sbi][side.cond_idx()] = gamma_l;
322  transport_flux += gamma_l;
323  }
324 
325  // fluxes and penalty
326  k=0;
327  for (auto p : this->boundary_points(cell_side) )
328  {
329  double flux_times_JxW;
331  {
332  //sigma_ corresponds to robin_sigma
333  auto p_bdr = p.point_bdr(side.cond().element_accessor());
334  flux_times_JxW = eq_fields_->cross_section(p)*eq_fields_->bc_robin_sigma[sbi](p_bdr)*fe_values_side_.JxW(k);
335  }
337  {
338  auto p_bdr = p.point_bdr(side.cond().element_accessor());
339  flux_times_JxW = (transport_flux + eq_fields_->cross_section(p)*eq_fields_->bc_robin_sigma[sbi](p_bdr))*fe_values_side_.JxW(k);
340  }
341  else if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux < 0)
342  flux_times_JxW = 0;
343  else
344  flux_times_JxW = transport_flux*fe_values_side_.JxW(k);
345 
346  for (unsigned int i=0; i<ndofs_; i++)
347  {
348  for (unsigned int j=0; j<ndofs_; j++)
349  {
350  // flux due to advection and penalty
351  local_matrix_[i*ndofs_+j] += flux_times_JxW*fe_values_side_.shape_value(i,k)*fe_values_side_.shape_value(j,k);
352 
353  // flux due to diffusion (only on dirichlet and inflow boundary)
355  local_matrix_[i*ndofs_+j] -= (arma::dot(eq_fields_->diffusion_coef[sbi](p)*fe_values_side_.shape_grad(j,k),fe_values_side_.normal_vector(k))*fe_values_side_.shape_value(i,k)
356  + arma::dot(eq_fields_->diffusion_coef[sbi](p)*fe_values_side_.shape_grad(i,k),fe_values_side_.normal_vector(k))*fe_values_side_.shape_value(j,k)*eq_data_->dg_variant
357  )*fe_values_side_.JxW(k);
358  }
359  }
360  k++;
361  }
362 
364  }
365  }
366 
367 
368  /// Assembles the fluxes between sides of elements of the same dimension.
370  ASSERT_EQ_DBG(edge_side_range.begin()->element().dim(), dim).error("Dimension of element mismatch!");
371 
372  unsigned int k;
373  double gamma_l, omega[2], transport_flux, delta[2], delta_sum;
374  double aniso1, aniso2;
375  double local_alpha=0.0;
376  int sid=0, s1, s2;
377  for( DHCellSide edge_side : edge_side_range )
378  {
379  auto dh_edge_cell = eq_data_->dh_->cell_accessor_from_element( edge_side.elem_idx() );
380  dh_edge_cell.get_dof_indices(side_dof_indices_[sid]);
381  fe_values_vec_[sid].reinit(edge_side.side());
382  ++sid;
383  }
384  arma::vec3 normal_vector = fe_values_vec_[0].normal_vector(0);
385 
386  // fluxes and penalty
387  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
388  {
389  vector<double> fluxes(edge_side_range.begin()->n_edge_sides());
390  double pflux = 0, nflux = 0; // calculate the total in- and out-flux through the edge
391  sid=0;
392  for( DHCellSide edge_side : edge_side_range )
393  {
394  fluxes[sid] = 0;
395  k=0;
396  for (auto p : this->edge_points(edge_side) ) {
397  fluxes[sid] += arma::dot(eq_fields_->advection_coef[sbi](p), fe_values_vec_[sid].normal_vector(k))*fe_values_vec_[sid].JxW(k);
398  k++;
399  }
400  fluxes[sid] /= edge_side.measure();
401  if (fluxes[sid] > 0)
402  pflux += fluxes[sid];
403  else
404  nflux += fluxes[sid];
405  ++sid;
406  }
407 
408  // precompute averages of shape functions over pairs of sides
409  s1=0;
410  for (DHCellSide edge_side : edge_side_range)
411  {
412  (void)edge_side;
413  for (unsigned int k=0; k<qsize_lower_dim_; k++)
414  {
415  for (unsigned int i=0; i<fe_->n_dofs(); i++)
416  averages[s1][k*fe_->n_dofs()+i] = fe_values_vec_[s1].shape_value(i,k)*0.5;
417  }
418  s1++;
419  }
420 
421 
422 
423  s1=0;
424  for( DHCellSide edge_side1 : edge_side_range )
425  {
426  s2=-1; // need increment at begin of loop (see conditionally 'continue' directions)
427  for( DHCellSide edge_side2 : edge_side_range )
428  {
429  s2++;
430  if (s2<=s1) continue;
431  ASSERT(edge_side1.is_valid()).error("Invalid side of edge.");
432 
433  arma::vec3 nv = fe_values_vec_[s1].normal_vector(0);
434 
435  // set up the parameters for DG method
436  // calculate the flux from edge_side1 to edge_side2
437  if (fluxes[s2] > 0 && fluxes[s1] < 0)
438  transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
439  else if (fluxes[s2] < 0 && fluxes[s1] > 0)
440  transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
441  else
442  transport_flux = 0;
443 
444  gamma_l = 0.5*fabs(transport_flux);
445 
446  delta[0] = 0;
447  delta[1] = 0;
448  for (auto p1 : this->edge_points(edge_side1) )
449  {
450  auto p2 = p1.point_on(edge_side2);
451  delta[0] += dot(eq_fields_->diffusion_coef[sbi](p1)*normal_vector,normal_vector);
452  delta[1] += dot(eq_fields_->diffusion_coef[sbi](p2)*normal_vector,normal_vector);
453  local_alpha = max(eq_fields_->dg_penalty[sbi](p1), eq_fields_->dg_penalty[sbi](p2));
454  }
455  delta[0] /= qsize_lower_dim_;
456  delta[1] /= qsize_lower_dim_;
457 
458  delta_sum = delta[0] + delta[1];
459 
460 // if (delta_sum > numeric_limits<double>::epsilon())
461  if (fabs(delta_sum) > 0)
462  {
463  omega[0] = delta[1]/delta_sum;
464  omega[1] = delta[0]/delta_sum;
465  double h = edge_side1.diameter();
466  aniso1 = eq_data_->elem_anisotropy(edge_side1.element());
467  aniso2 = eq_data_->elem_anisotropy(edge_side2.element());
468  gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
469  }
470  else
471  for (int i=0; i<2; i++) omega[i] = 0;
472  // end of set up the parameters for DG method
473 
474  int sd[2]; bool is_side_own[2];
475  sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
476  sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
477 
478  // precompute jumps and weighted averages of shape functions over the pair of sides (s1,s2)
479  k=0;
480  for (auto p1 : this->edge_points(edge_side1) )
481  {
482  auto p2 = p1.point_on(edge_side2);
483  for (unsigned int i=0; i<fe_->n_dofs(); i++)
484  {
485  for (int n=0; n<2; n++)
486  {
487  jumps[n][k*fe_->n_dofs()+i] = (n==0)*fe_values_vec_[s1].shape_value(i,k) - (n==1)*fe_values_vec_[s2].shape_value(i,k);
488  waverages[n][k*fe_->n_dofs()+i] = arma::dot(eq_fields_->diffusion_coef[sbi]( (n==0 ? p1 : p2) )*fe_values_vec_[sd[n]].shape_grad(i,k),nv)*omega[n];
489  }
490  }
491  k++;
492  }
493 
494  // For selected pair of elements:
495  for (int n=0; n<2; n++)
496  {
497  if (!is_side_own[n]) continue;
498 
499  for (int m=0; m<2; m++)
500  {
501  for (unsigned int i=0; i<fe_values_vec_[sd[n]].n_dofs(); i++)
502  for (unsigned int j=0; j<fe_values_vec_[sd[m]].n_dofs(); j++)
503  local_matrix_[i*fe_values_vec_[sd[m]].n_dofs()+j] = 0;
504 
505  for (k=0; k<this->quad_low_->size(); ++k)
506  {
507  for (unsigned int i=0; i<fe_values_vec_[sd[n]].n_dofs(); i++)
508  {
509  for (unsigned int j=0; j<fe_values_vec_[sd[m]].n_dofs(); j++)
510  {
511  int index = i*fe_values_vec_[sd[m]].n_dofs()+j;
512 
513  local_matrix_[index] += (
514  // flux due to transport (applied on interior edges) (average times jump)
515  transport_flux*jumps[n][k*fe_->n_dofs()+i]*averages[sd[m]][k*fe_->n_dofs()+j]
516 
517  // penalty enforcing continuity across edges (applied on interior and Dirichlet edges) (jump times jump)
518  + gamma_l*jumps[n][k*fe_->n_dofs()+i]*jumps[m][k*fe_->n_dofs()+j]
519 
520  // terms due to diffusion
521  - jumps[n][k*fe_->n_dofs()+i]*waverages[m][k*fe_->n_dofs()+j]
522  - eq_data_->dg_variant*waverages[n][k*fe_->n_dofs()+i]*jumps[m][k*fe_->n_dofs()+j]
523  )*fe_values_vec_[0].JxW(k);
524  }
525  }
526  }
527  eq_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]));
528  }
529  }
530  }
531  s1++;
532  }
533  }
534  }
535 
536 
537  /// Assembles the fluxes between elements of different dimensions.
538  inline void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side) {
539  if (dim == 1) return;
540  ASSERT_EQ_DBG(cell_lower_dim.dim(), dim-1).error("Dimension of element mismatch!");
541 
542  // Note: use data members csection_ and velocity_ for appropriate quantities of lower dim element
543 
544  double comm_flux[2][2];
545  unsigned int n_dofs[2];
546  ElementAccessor<3> elm_lower_dim = cell_lower_dim.elm();
547  unsigned int n_indices = cell_lower_dim.get_dof_indices(dof_indices_);
548  for(unsigned int i=0; i<n_indices; ++i) {
549  side_dof_indices_vb_[i] = dof_indices_[i];
550  }
551  fe_values_vb_.reinit(elm_lower_dim);
552  n_dofs[0] = fv_sb_[0]->n_dofs();
553 
554  DHCellAccessor cell_higher_dim = eq_data_->dh_->cell_accessor_from_element( neighb_side.element().idx() );
555  n_indices = cell_higher_dim.get_dof_indices(dof_indices_);
556  for(unsigned int i=0; i<n_indices; ++i) {
557  side_dof_indices_vb_[i+n_dofs[0]] = dof_indices_[i];
558  }
559  fe_values_side_.reinit(neighb_side.side());
560  n_dofs[1] = fv_sb_[1]->n_dofs();
561 
562  // Testing element if they belong to local partition.
563  bool own_element_id[2];
564  own_element_id[0] = cell_lower_dim.is_own();
565  own_element_id[1] = cell_higher_dim.is_own();
566 
567  unsigned int k;
568  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++) // Optimize: SWAP LOOPS
569  {
570  for (unsigned int i=0; i<n_dofs[0]+n_dofs[1]; i++)
571  for (unsigned int j=0; j<n_dofs[0]+n_dofs[1]; j++)
572  local_matrix_[i*(n_dofs[0]+n_dofs[1])+j] = 0;
573 
574  // set transmission conditions
575  k=0;
576  for (auto p_high : this->coupling_points(neighb_side) )
577  {
578  auto p_low = p_high.lower_dim(cell_lower_dim);
579  // The communication flux has two parts:
580  // - "diffusive" term containing sigma
581  // - "advective" term representing usual upwind
582  //
583  // The calculation differs from the reference manual, since ad_coef and dif_coef have different meaning
584  // than b and A in the manual.
585  // In calculation of sigma there appears one more csection_lower in the denominator.
586  double sigma = eq_fields_->fracture_sigma[sbi](p_low)*arma::dot(eq_fields_->diffusion_coef[sbi](p_low)*fe_values_side_.normal_vector(k),fe_values_side_.normal_vector(k))*
587  2*eq_fields_->cross_section(p_high)*eq_fields_->cross_section(p_high)/(eq_fields_->cross_section(p_low)*eq_fields_->cross_section(p_low));
588 
589  double transport_flux = arma::dot(eq_fields_->advection_coef[sbi](p_high), fe_values_side_.normal_vector(k));
590 
591  comm_flux[0][0] = (sigma-min(0.,transport_flux))*fv_sb_[0]->JxW(k);
592  comm_flux[0][1] = -(sigma-min(0.,transport_flux))*fv_sb_[0]->JxW(k);
593  comm_flux[1][0] = -(sigma+max(0.,transport_flux))*fv_sb_[0]->JxW(k);
594  comm_flux[1][1] = (sigma+max(0.,transport_flux))*fv_sb_[0]->JxW(k);
595 
596  for (int n=0; n<2; n++)
597  {
598  if (!own_element_id[n]) continue;
599 
600  for (unsigned int i=0; i<n_dofs[n]; i++)
601  for (int m=0; m<2; m++)
602  for (unsigned int j=0; j<n_dofs[m]; j++)
603  local_matrix_[(i+n*n_dofs[0])*(n_dofs[0]+n_dofs[1]) + m*n_dofs[0] + j] +=
604  comm_flux[m][n]*fv_sb_[m]->shape_value(j,k)*fv_sb_[n]->shape_value(i,k);
605  }
606  k++;
607  }
608  eq_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]));
609  }
610  }
611 
612 
613 private:
614  shared_ptr<FiniteElement<dim>> fe_; ///< Finite element for the solution of the advection-diffusion equation.
615  shared_ptr<FiniteElement<dim-1>> fe_low_; ///< Finite element for the solution of the advection-diffusion equation (dim-1).
616 
617  /// Data objects shared with TransportDG
618  EqFields *eq_fields_;
619  EqData *eq_data_;
620 
621  /// Sub field set contains fields used in calculation.
623 
624  unsigned int ndofs_; ///< Number of dofs
625  unsigned int qsize_lower_dim_; ///< Size of quadrature of dim-1
626  FEValues<3> fe_values_; ///< FEValues of object (of P disc finite element type)
627  FEValues<3> fe_values_vb_; ///< FEValues of dim-1 object (of P disc finite element type)
628  FEValues<3> fe_values_side_; ///< FEValues of object (of P disc finite element type)
629  vector<FEValues<3>> fe_values_vec_; ///< Vector of FEValues of object (of P disc finite element types)
630  vector<FEValues<3>*> fv_sb_; ///< Auxiliary vector, holds FEValues objects for assemble element-side
631 
632  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
633  vector< vector<LongIdx> > side_dof_indices_; ///< Vector of vectors of side DOF indices
634  vector<LongIdx> side_dof_indices_vb_; ///< Vector of side DOF indices (assemble element-side fluxex)
635  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
636 
637  vector<double*> averages; ///< Auxiliary storage for averages of shape functions.
638  vector<double*> waverages; ///< Auxiliary storage for weighted averages of shape functions.
639  vector<double*> jumps; ///< Auxiliary storage for jumps of shape functions.
640 
641  template < template<IntDim...> class DimAssembly>
642  friend class GenericAssembly;
643 
644 };
645 
646 
647 /**
648  * Auxiliary container class for Finite element and related objects of given dimension.
649  */
650 template <unsigned int dim, class Model>
651 class SourcesAssemblyDG : public AssemblyBase<dim>
652 {
653 public:
656 
657  static constexpr const char * name() { return "SourcesAssemblyDG"; }
658 
659  /// Constructor.
660  SourcesAssemblyDG(EqFields *eq_fields, EqData *eq_data)
661  : AssemblyBase<dim>(eq_data->dg_order), eq_fields_(eq_fields), eq_data_(eq_data) {
663  this->used_fields_ += eq_fields_->sources_density_out;
664  this->used_fields_ += eq_fields_->sources_conc_out;
665  this->used_fields_ += eq_fields_->sources_sigma_out;
666  }
667 
668  /// Destructor.
670 
671  /// Initialize auxiliary vectors and other data members
672  void initialize(ElementCacheMap *element_cache_map) {
673  this->element_cache_map_ = element_cache_map;
674 
675  fe_ = std::make_shared< FE_P_disc<dim> >(eq_data_->dg_order);
677  fe_values_.initialize(*this->quad_, *fe_, u);
678  if (dim==1) // print to log only one time
679  DebugOut() << "List of SourcesAssemblyDG FEValues updates flags: " << this->print_update_flags(u);
680  ndofs_ = fe_->n_dofs();
681  dof_indices_.resize(ndofs_);
682  local_rhs_.resize(ndofs_);
683  local_source_balance_vector_.resize(ndofs_);
684  local_source_balance_rhs_.resize(ndofs_);
685  }
686 
687 
688  /// Assemble integral over element
689  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
690  {
691  ASSERT_EQ_DBG(cell.dim(), dim).error("Dimension of element mismatch!");
692 
693  ElementAccessor<3> elm = cell.elm();
694  unsigned int k;
695  double source;
696 
697  fe_values_.reinit(elm);
699 
700  // assemble the local stiffness matrix
701  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
702  {
703  fill_n( &(local_rhs_[0]), ndofs_, 0 );
704  local_source_balance_vector_.assign(ndofs_, 0);
705  local_source_balance_rhs_.assign(ndofs_, 0);
706 
707  k=0;
708  for (auto p : this->bulk_points(element_patch_idx) )
709  {
710  source = (eq_fields_->sources_density_out[sbi](p) + eq_fields_->sources_conc_out[sbi](p)*eq_fields_->sources_sigma_out[sbi](p))*fe_values_.JxW(k);
711 
712  for (unsigned int i=0; i<ndofs_; i++)
713  local_rhs_[i] += source*fe_values_.shape_value(i,k);
714  k++;
715  }
716  eq_data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
717 
718  for (unsigned int i=0; i<ndofs_; i++)
719  {
720  k=0;
721  for (auto p : this->bulk_points(element_patch_idx) )
722  {
723  local_source_balance_vector_[i] -= eq_fields_->sources_sigma_out[sbi](p)*fe_values_.shape_value(i,k)*fe_values_.JxW(k);
724  k++;
725  }
726 
727  local_source_balance_rhs_[i] += local_rhs_[i];
728  }
729  eq_data_->balance_->add_source_values(eq_data_->subst_idx()[sbi], elm.region().bulk_idx(),
730  cell.get_loc_dof_indices(),
731  local_source_balance_vector_, local_source_balance_rhs_);
732  }
733  }
734 
735  /// Implements @p AssemblyBase::begin.
736  void begin() override
737  {
738  eq_data_->balance_->start_source_assembly( eq_data_->subst_idx() );
739  }
740 
741  /// Implements @p AssemblyBase::end.
742  void end() override
743  {
744  eq_data_->balance_->finish_source_assembly( eq_data_->subst_idx() );
745  }
746 
747 
748  private:
749  shared_ptr<FiniteElement<dim>> fe_; ///< Finite element for the solution of the advection-diffusion equation.
750 
751  /// Data objects shared with TransportDG
752  EqFields *eq_fields_;
753  EqData *eq_data_;
754 
755  /// Sub field set contains fields used in calculation.
757 
758  unsigned int ndofs_; ///< Number of dofs
759  FEValues<3> fe_values_; ///< FEValues of object (of P disc finite element type)
760 
761  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
762  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
763  vector<PetscScalar> local_source_balance_vector_; ///< Auxiliary vector for set_sources method.
764  vector<PetscScalar> local_source_balance_rhs_; ///< Auxiliary vector for set_sources method.
765 
766  template < template<IntDim...> class DimAssembly>
767  friend class GenericAssembly;
768 
769 };
770 
771 
772 /**
773  * Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions..
774  */
775 template <unsigned int dim, class Model>
777 {
778 public:
781 
782  static constexpr const char * name() { return "BdrConditionAssemblyDG"; }
783 
784  /// Constructor.
785  BdrConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data)
786  : AssemblyBase<dim>(eq_data->dg_order), eq_fields_(eq_fields), eq_data_(eq_data) {
788  this->used_fields_ += eq_fields_->advection_coef;
789  this->used_fields_ += eq_fields_->diffusion_coef;
790  this->used_fields_ += eq_fields_->cross_section;
791  this->used_fields_ += eq_fields_->bc_type;
792  this->used_fields_ += eq_fields_->bc_dirichlet_value;
793  this->used_fields_ += eq_fields_->bc_robin_sigma;
794  this->used_fields_ += eq_fields_->bc_flux;
795  }
796 
797  /// Destructor.
799 
800  /// Initialize auxiliary vectors and other data members
801  void initialize(ElementCacheMap *element_cache_map) {
802  this->element_cache_map_ = element_cache_map;
803 
804  fe_ = std::make_shared< FE_P_disc<dim> >(eq_data_->dg_order);
806  fe_values_side_.initialize(*this->quad_low_, *fe_, u);
807  if (dim==1) // print to log only one time
808  DebugOut() << "List of BdrConditionAssemblyDG FEValues updates flags: " << this->print_update_flags(u);
809  ndofs_ = fe_->n_dofs();
810  dof_indices_.resize(ndofs_);
811  local_rhs_.resize(ndofs_);
812  local_flux_balance_vector_.resize(ndofs_);
813  }
814 
815 
816  /// Implements @p AssemblyBase::boundary_side_integral.
817  inline void boundary_side_integral(DHCellSide cell_side)
818  {
819  unsigned int k;
820 
821  const unsigned int cond_idx = cell_side.side().cond_idx();
822 
823  ElementAccessor<3> bc_elm = cell_side.cond().element_accessor();
824 
825  fe_values_side_.reinit(cell_side.side());
826 
827  const DHCellAccessor &cell = cell_side.cell();
829 
830  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
831  {
832  fill_n(&(local_rhs_[0]), ndofs_, 0);
833  local_flux_balance_vector_.assign(ndofs_, 0);
834  local_flux_balance_rhs_ = 0;
835 
836  double side_flux = 0;
837  k=0;
838  for (auto p : this->boundary_points(cell_side) ) {
839  side_flux += arma::dot(eq_fields_->advection_coef[sbi](p), fe_values_side_.normal_vector(k))*fe_values_side_.JxW(k);
840  k++;
841  }
842  double transport_flux = side_flux/cell_side.measure();
843 
844  auto p_side = *( this->boundary_points(cell_side)).begin();
845  auto p_bdr = p_side.point_bdr(cell_side.cond().element_accessor() );
846  unsigned int bc_type = eq_fields_->bc_type[sbi](p_bdr);
847  if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux < 0)
848  {
849  k=0;
850  for (auto p : this->boundary_points(cell_side) )
851  {
852  auto p_bdr = p.point_bdr(bc_elm);
853  double bc_term = -transport_flux*eq_fields_->bc_dirichlet_value[sbi](p_bdr)*fe_values_side_.JxW(k);
854  for (unsigned int i=0; i<ndofs_; i++)
855  local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k);
856  k++;
857  }
858  for (unsigned int i=0; i<ndofs_; i++)
859  local_flux_balance_rhs_ -= local_rhs_[i];
860  }
861  else if (bc_type == AdvectionDiffusionModel::abc_dirichlet)
862  {
863  k=0;
864  for (auto p : this->boundary_points(cell_side) )
865  {
866  auto p_bdr = p.point_bdr(bc_elm);
867  double bc_term = eq_data_->gamma[sbi][cond_idx]*eq_fields_->bc_dirichlet_value[sbi](p_bdr)*fe_values_side_.JxW(k);
868  arma::vec3 bc_grad = -eq_fields_->bc_dirichlet_value[sbi](p_bdr)*fe_values_side_.JxW(k)*eq_data_->dg_variant*(arma::trans(eq_fields_->diffusion_coef[sbi](p))*fe_values_side_.normal_vector(k));
869  for (unsigned int i=0; i<ndofs_; i++)
870  local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k)
871  + arma::dot(bc_grad,fe_values_side_.shape_grad(i,k));
872  k++;
873  }
874  k=0;
875  for (auto p : this->boundary_points(cell_side) )
876  {
877  for (unsigned int i=0; i<ndofs_; i++)
878  {
879  local_flux_balance_vector_[i] += (arma::dot(eq_fields_->advection_coef[sbi](p), fe_values_side_.normal_vector(k))*fe_values_side_.shape_value(i,k)
880  - arma::dot(eq_fields_->diffusion_coef[sbi](p)*fe_values_side_.shape_grad(i,k),fe_values_side_.normal_vector(k))
881  + eq_data_->gamma[sbi][cond_idx]*fe_values_side_.shape_value(i,k))*fe_values_side_.JxW(k);
882  }
883  k++;
884  }
885  if (eq_data_->time_->step().index() > 0)
886  for (unsigned int i=0; i<ndofs_; i++)
887  local_flux_balance_rhs_ -= local_rhs_[i];
888  }
889  else if (bc_type == AdvectionDiffusionModel::abc_total_flux)
890  {
891  k=0;
892  for (auto p : this->boundary_points(cell_side) )
893  {
894  auto p_bdr = p.point_bdr(bc_elm);
895  double bc_term = eq_fields_->cross_section(p) * (eq_fields_->bc_robin_sigma[sbi](p_bdr)*eq_fields_->bc_dirichlet_value[sbi](p_bdr) +
896  eq_fields_->bc_flux[sbi](p_bdr)) * fe_values_side_.JxW(k);
897  for (unsigned int i=0; i<ndofs_; i++)
898  local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k);
899  k++;
900  }
901 
902  for (unsigned int i=0; i<ndofs_; i++)
903  {
904  k=0;
905  for (auto p : this->boundary_points(cell_side) ) {
906  auto p_bdr = p.point_bdr(bc_elm);
907  local_flux_balance_vector_[i] += eq_fields_->cross_section(p) * eq_fields_->bc_robin_sigma[sbi](p_bdr) *
908  fe_values_side_.JxW(k) * fe_values_side_.shape_value(i,k);
909  k++;
910  }
911  local_flux_balance_rhs_ -= local_rhs_[i];
912  }
913  }
915  {
916  k=0;
917  for (auto p : this->boundary_points(cell_side) )
918  {
919  auto p_bdr = p.point_bdr(bc_elm);
920  double bc_term = eq_fields_->cross_section(p) * (eq_fields_->bc_robin_sigma[sbi](p_bdr)*eq_fields_->bc_dirichlet_value[sbi](p_bdr) +
921  eq_fields_->bc_flux[sbi](p_bdr)) * fe_values_side_.JxW(k);
922  for (unsigned int i=0; i<ndofs_; i++)
923  local_rhs_[i] += bc_term*fe_values_side_.shape_value(i,k);
924  k++;
925  }
926 
927  for (unsigned int i=0; i<ndofs_; i++)
928  {
929  k=0;
930  for (auto p : this->boundary_points(cell_side) ) {
931  auto p_bdr = p.point_bdr(bc_elm);
932  local_flux_balance_vector_[i] += eq_fields_->cross_section(p)*(arma::dot(eq_fields_->advection_coef[sbi](p), fe_values_side_.normal_vector(k)) +
933  eq_fields_->bc_robin_sigma[sbi](p_bdr))*fe_values_side_.JxW(k)*fe_values_side_.shape_value(i,k);
934  k++;
935  }
936  local_flux_balance_rhs_ -= local_rhs_[i];
937  }
938  }
939  else if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux >= 0)
940  {
941  k=0;
942  for (auto p : this->boundary_points(cell_side) )
943  {
944  for (unsigned int i=0; i<ndofs_; i++)
945  local_flux_balance_vector_[i] += arma::dot(eq_fields_->advection_coef[sbi](p), fe_values_side_.normal_vector(k))*fe_values_side_.JxW(k)*fe_values_side_.shape_value(i,k);
946  k++;
947  }
948  }
949  eq_data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
950 
951  eq_data_->balance_->add_flux_values(eq_data_->subst_idx()[sbi], cell_side,
952  cell.get_loc_dof_indices(),
953  local_flux_balance_vector_, local_flux_balance_rhs_);
954  }
955  }
956 
957  /// Implements @p AssemblyBase::begin.
958  void begin() override
959  {
960  eq_data_->balance_->start_flux_assembly( eq_data_->subst_idx() );
961  }
962 
963  /// Implements @p AssemblyBase::end.
964  void end() override
965  {
966  eq_data_->balance_->finish_flux_assembly( eq_data_->subst_idx() );
967  }
968 
969 
970  private:
971  shared_ptr<FiniteElement<dim>> fe_; ///< Finite element for the solution of the advection-diffusion equation.
972 
973  /// Data objects shared with TransportDG
974  EqFields *eq_fields_;
975  EqData *eq_data_;
976 
977  /// Sub field set contains fields used in calculation.
979 
980  unsigned int ndofs_; ///< Number of dofs
981  FEValues<3> fe_values_side_; ///< FEValues of object (of P disc finite element type)
982 
983  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
984  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
985  vector<PetscScalar> local_flux_balance_vector_; ///< Auxiliary vector for set_boundary_conditions method.
986  PetscScalar local_flux_balance_rhs_; ///< Auxiliary variable for set_boundary_conditions method.
987 
988  template < template<IntDim...> class DimAssembly>
989  friend class GenericAssembly;
990 
991 };
992 
993 
994 /**
995  * Auxiliary container class sets the initial condition.
996  */
997 template <unsigned int dim, class Model>
999 {
1000 public:
1003 
1004  static constexpr const char * name() { return "InitConditionAssemblyDG"; }
1005 
1006  /// Constructor.
1007  InitConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data)
1008  : AssemblyBase<dim>(eq_data->dg_order), eq_fields_(eq_fields), eq_data_(eq_data) {
1010  this->used_fields_ += eq_fields_->init_condition;
1011  }
1012 
1013  /// Destructor.
1015 
1016  /// Initialize auxiliary vectors and other data members
1017  void initialize(ElementCacheMap *element_cache_map) {
1018  this->element_cache_map_ = element_cache_map;
1019 
1020  fe_ = std::make_shared< FE_P_disc<dim> >(eq_data_->dg_order);
1022  fe_values_.initialize(*this->quad_, *fe_, u);
1023  if (dim==1) // print to log only one time
1024  DebugOut() << "List of InitConditionAssemblyDG FEValues updates flags: " << this->print_update_flags(u);
1025  ndofs_ = fe_->n_dofs();
1026  dof_indices_.resize(ndofs_);
1027  local_matrix_.resize(4*ndofs_*ndofs_);
1028  local_rhs_.resize(ndofs_);
1029  }
1030 
1031 
1032  /// Assemble integral over element
1033  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
1034  {
1035  ASSERT_EQ_DBG(cell.dim(), dim).error("Dimension of element mismatch!");
1036 
1037  unsigned int k;
1038  ElementAccessor<3> elem = cell.elm();
1040  fe_values_.reinit(elem);
1041 
1042  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
1043  {
1044  for (unsigned int i=0; i<ndofs_; i++)
1045  {
1046  local_rhs_[i] = 0;
1047  for (unsigned int j=0; j<ndofs_; j++)
1048  local_matrix_[i*ndofs_+j] = 0;
1049  }
1050 
1051  k=0;
1052  for (auto p : this->bulk_points(element_patch_idx) )
1053  {
1054  double rhs_term = eq_fields_->init_condition[sbi](p)*fe_values_.JxW(k);
1055 
1056  for (unsigned int i=0; i<ndofs_; i++)
1057  {
1058  for (unsigned int j=0; j<ndofs_; j++)
1060 
1061  local_rhs_[i] += fe_values_.shape_value(i,k)*rhs_term;
1062  }
1063  k++;
1064  }
1065  eq_data_->ls[sbi]->set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]), &(local_rhs_[0]));
1066  }
1067  }
1068 
1069 
1070  private:
1071  shared_ptr<FiniteElement<dim>> fe_; ///< Finite element for the solution of the advection-diffusion equation.
1072 
1073  /// Data objects shared with TransportDG
1074  EqFields *eq_fields_;
1075  EqData *eq_data_;
1076 
1077  /// Sub field set contains fields used in calculation.
1079 
1080  unsigned int ndofs_; ///< Number of dofs
1081  FEValues<3> fe_values_; ///< FEValues of object (of P disc finite element type)
1082 
1083  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
1084  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
1085  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
1086 
1087  template < template<IntDim...> class DimAssembly>
1088  friend class GenericAssembly;
1089 
1090 };
1091 
1092 
1093 
1094 #endif /* ASSEMBLY_DG_HH_ */
1095 
TransportDG< Model >::EqFields EqFields
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:145
Shape function values.
Definition: update_flags.hh:87
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:756
UpdateFlags
Enum type UpdateFlags indicates which quantities are to be recomputed on each finite element cell...
Definition: update_flags.hh:67
MultiField< 3, FieldValue< 3 >::Scalar > dg_penalty
Penalty enforcing inter-element continuity of solution (for each substance).
EqData * eq_data_
Definition: assembly_dg.hh:140
shared_ptr< FiniteElement< dim > > fe_
Finite element for the solution of the advection-diffusion equation.
Definition: assembly_dg.hh:136
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:159
static constexpr const char * name()
Definition: assembly_dg.hh:782
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
Definition: assembly_dg.hh:635
FEValues< 3 > fe_values_
FEValues of object (of P disc finite element type)
Definition: assembly_dg.hh:626
Transformed quadrature weight for cell sides.
#define ASSERT_EQ_DBG(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:332
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
Definition: assembly_dg.hh:689
Quadrature * quad_low_
Quadrature used in assembling methods (dim-1).
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assembles the cell (volume) integral into the stiffness matrix.
Definition: assembly_dg.hh:243
double elem_anisotropy(ElementAccessor< 3 > e) const
Compute and return anisotropy of given element.
std::vector< std::vector< double > > gamma
Penalty parameters.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:632
int active_integrals_
Holds mask of active integrals.
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:801
unsigned int dim() const
Return dimension of element appropriate to the side.
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:139
Range< EdgePoint > edge_points(const DHCellSide &cell_side) const
Return EdgePoint range of appropriate dimension.
unsigned int dg_order
Polynomial order of finite elements.
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:780
unsigned int get_dof_indices(std::vector< LongIdx > &indices) const
Fill vector of the global indices of dofs associated to the cell.
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:980
FEValues< 3 > fe_values_
FEValues of object (of P disc finite element type)
Definition: assembly_dg.hh:146
~InitConditionAssemblyDG()
Destructor.
shared_ptr< FiniteElement< dim > > fe_
Finite element for the solution of the advection-diffusion equation.
Definition: assembly_dg.hh:971
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:166
virtual void rhs_set_values(int nrow, int *rows, double *vals)=0
vector< vector< LongIdx > > side_dof_indices_
Vector of vectors of side DOF indices.
Definition: assembly_dg.hh:633
unsigned int dim() const
Return dimension of element appropriate to cell.
FieldSet used_fields_
Sub field set contains fields used in calculation.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
FEValues< 3 > fe_values_vb_
FEValues of dim-1 object (of P disc finite element type)
Definition: assembly_dg.hh:627
SourcesAssemblyDG(EqFields *eq_fields, EqData *eq_data)
Constructor.
Definition: assembly_dg.hh:660
arma::vec::fixed< spacedim > shape_grad(const unsigned int function_no, const unsigned int point_no) const
Return the gradient of the function_no-th shape function at the point_no-th quadrature point...
Definition: fe_values.hh:164
Directing class of FieldValueCache.
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
Cell accessor allow iterate over DOF handler cells.
MassAssemblyDG(EqFields *eq_fields, EqData *eq_data)
Constructor.
Definition: assembly_dg.hh:45
Class FEValues calculates finite element data on the actual cells such as shape function values...
int dg_variant
DG variant ((non-)symmetric/incomplete.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:761
vector< PetscScalar > local_source_balance_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:764
LocDofVec get_loc_dof_indices() const
Returns the local indices of dofs associated to the cell on the local process.
double measure() const
~SourcesAssemblyDG()
Destructor.
Definition: assembly_dg.hh:669
EqFields * eq_fields_
Data objects shared with TransportDG.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
shared_ptr< FiniteElement< dim > > fe_
Finite element for the solution of the advection-diffusion equation.
const TimeStep & step(int index=-1) const
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:672
std::shared_ptr< Balance > balance_
IterConvert< ObjectIn, ObjectOut > begin()
Iterator to begin item of range.
static constexpr const char * name()
Definition: assembly_dg.hh:657
bool is_own() const
Return true if accessor represents own element (false for ghost element)
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:193
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:618
FEValues< 3 > fe_values_side_
FEValues of object (of P disc finite element type)
Definition: assembly_dg.hh:628
Side side() const
Return Side of given cell and side_idx.
void reinit(const ElementAccessor< spacedim > &cell)
Update cell-dependent data (gradients, Jacobians etc.)
Definition: fe_values.cc:541
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:130
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:736
vector< PetscScalar > local_mass_balance_vector_
Same as previous.
Definition: assembly_dg.hh:151
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:124
InitConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data)
Constructor.
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:622
Discontinuous Lagrangean finite element on dim dimensional simplex.
Definition: fe_p.hh:108
Transformed quadrature points.
const ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
unsigned int max_edg_sides
Maximal number of edge sides (evaluate from dim 1,2,3)
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:758
vector< double * > jumps
Auxiliary storage for jumps of shape functions.
Definition: assembly_dg.hh:639
vector< vector< arma::mat33 > > dif_coef
Diffusion coefficients.
FEValues< 3 > fe_values_
FEValues of object (of P disc finite element type)
FEValues< 3 > fe_values_side_
FEValues of object (of P disc finite element type)
Definition: assembly_dg.hh:981
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:742
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:779
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
Definition: assembly_dg.hh:74
void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side)
Assembles the fluxes between elements of different dimensions.
Definition: assembly_dg.hh:538
void edge_integral(RangeConvert< DHEdgeSide, DHCellSide > edge_side_range)
Assembles the fluxes between sides of elements of the same dimension.
Definition: assembly_dg.hh:369
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:655
vector< double * > waverages
Auxiliary storage for weighted averages of shape functions.
Definition: assembly_dg.hh:638
std::vector< Vec > ret_vec
Auxiliary vectors for calculation of sources in balance due to retardation (e.g. sorption).
vector< FEValues< 3 > * > fv_sb_
Auxiliary vector, holds FEValues objects for assemble element-side.
Definition: assembly_dg.hh:630
Range< BulkPoint > bulk_points(unsigned int element_patch_idx) const
Return BulkPoint range of appropriate dimension.
Definitions of basic Lagrangean finite elements with polynomial shape functions.
FEValues< 3 > fe_values_
FEValues of object (of P disc finite element type)
Definition: assembly_dg.hh:759
LinSys ** ls
Linear algebra system for the transport equation.
ElementAccessor< 3 > element() const
void boundary_side_integral(DHCellSide cell_side)
Assembles the fluxes on the boundary.
Definition: assembly_dg.hh:282
Boundary cond() const
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:762
void initialize(Quadrature &_quadrature, FiniteElement< DIM > &_fe, UpdateFlags _flags)
Initialize structures and calculates cell-independent data.
Definition: fe_values.cc:137
static constexpr const char * name()
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
Definition: assembly_dg.hh:149
void boundary_side_integral(DHCellSide cell_side)
Implements AssemblyBase::boundary_side_integral.
Definition: assembly_dg.hh:817
static constexpr const char * name()
Definition: assembly_dg.hh:42
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:56
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:624
Shape function gradients.
Definition: update_flags.hh:95
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:983
unsigned int IntDim
A dimension index type.
Definition: mixed.hh:19
StiffnessAssemblyDG(EqFields *eq_fields, EqData *eq_data)
Constructor.
Definition: assembly_dg.hh:172
void set_DG_parameters_boundary(Side 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.
double measure() const
Calculate metrics of the side.
Definition: accessors.cc:27
unsigned int qsize_lower_dim_
Size of quadrature of dim-1.
Definition: assembly_dg.hh:625
Region region() const
Definition: accessors.hh:165
Normal vectors.
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:143
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:148
Discontinuous Galerkin method for equation of transport with dispersion.
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:978
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:167
PetscScalar local_flux_balance_rhs_
Auxiliary variable for set_boundary_conditions method.
Definition: assembly_dg.hh:986
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
void set_values(int nrow, int *rows, int ncol, int *cols, PetscScalar *mat_vals, PetscScalar *rhs_vals)
Set values in the system matrix and values in the right-hand side vector on corresponding rows...
Definition: linsys.hh:386
unsigned int cond_idx() const
Returns global index of the prescribed boundary condition.
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:974
vector< LongIdx > side_dof_indices_vb_
Vector of side DOF indices (assemble element-side fluxex)
Definition: assembly_dg.hh:634
shared_ptr< FiniteElement< dim > > fe_
Finite element for the solution of the advection-diffusion equation.
Definition: assembly_dg.hh:614
~BdrConditionAssemblyDG()
Destructor.
Definition: assembly_dg.hh:798
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:752
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:39
TransportDG< Model >::EqData EqData
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:40
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:964
vector< FEValues< 3 > > fe_values_vec_
Vector of FEValues of object (of P disc finite element types)
Definition: assembly_dg.hh:629
unsigned int ndofs_
Number of dofs.
Generic class of assemblation.
MultiField< 3, FieldValue< 3 >::Scalar > fracture_sigma
Transition parameter for diffusive transfer on fractures (for each substance).
std::shared_ptr< DOFHandlerMultiDim > dh_
Object for distribution of dofs.
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
Definition: region.hh:91
Definitions of particular quadrature rules on simplices.
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:984
shared_ptr< FiniteElement< dim > > fe_
Finite element for the solution of the advection-diffusion equation.
Definition: assembly_dg.hh:749
shared_ptr< FiniteElement< dim-1 > > fe_low_
Finite element for the solution of the advection-diffusion equation (dim-1).
Definition: assembly_dg.hh:615
BdrConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data)
Constructor.
Definition: assembly_dg.hh:785
static constexpr const char * name()
Definition: assembly_dg.hh:169
unsigned int index() const
TimeGovernor * time_
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:654
Range< CouplingPoint > coupling_points(const DHCellSide &cell_side) const
Return CouplingPoint range of appropriate dimension.
virtual void mat_set_values(int nrow, int *rows, int ncol, int *cols, double *vals)=0
vector< PetscScalar > local_flux_balance_vector_
Auxiliary vector for set_boundary_conditions method.
Definition: assembly_dg.hh:985
Abstract class for the description of a general finite element on a reference simplex in dim dimensio...
double JxW(const unsigned int point_no)
Return the product of Jacobian determinant and the quadrature weight at given quadrature point...
Definition: fe_values.hh:223
unsigned int dim() const
Definition: accessors.hh:157
Boundary cond() const
double shape_value(const unsigned int function_no, const unsigned int point_no) const
Return the value of the function_no-th shape function at the point_no-th quadrature point...
Definition: fe_values.hh:149
Range< BoundaryPoint > boundary_points(const DHCellSide &cell_side) const
Return BoundaryPoint range of appropriate dimension.
unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:87
~StiffnessAssemblyDG()
Destructor.
Definition: assembly_dg.hh:186
vector< PetscScalar > local_source_balance_vector_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:763
vector< PetscScalar > local_retardation_balance_vector_
Auxiliary vector for assemble mass matrix.
Definition: assembly_dg.hh:150
#define DebugOut()
Macro defining &#39;debug&#39; record of log.
Definition: logger.hh:276
unsigned int idx() const
Return local idx of element in boundary / bulk part of element vector.
Definition: accessors.hh:181
~MassAssemblyDG()
Destructor.
Definition: assembly_dg.hh:53
LinSys ** ls_dt
Linear algebra system for the time derivative (actually it is used only for handling the matrix struc...
Quadrature * quad_
Quadrature used in assembling methods.
Side accessor allows to iterate over sides of DOF handler cell.
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:958
ElementAccessor< 3 > element_accessor()
std::string print_update_flags(UpdateFlags u) const
Print update flags to string format.
ElementCacheMap * element_cache_map_
ElementCacheMap shared with GenericAssembly object.
Transformed quadrature weights.
vector< double * > averages
Auxiliary storage for averages of shape functions.
Definition: assembly_dg.hh:637