Flow123d  DF_patch_fe_mechanics-ccea6e4
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/patch_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 AssemblyBasePatch<dim>
37 {
38 public:
41 
42  static constexpr const char * name() { return "MassAssemblyDG"; }
43 
44  /// Constructor.
45  MassAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
46  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
47  JxW_( this->bulk_values().JxW() ),
48  ref_scalar_( this->bulk_values().ref_scalar() ),
49  conc_shape_( this->bulk_values().scalar_shape() ) {
51  this->used_fields_ += eq_fields_->mass_matrix_coef;
52  this->used_fields_ += eq_fields_->retardation_coef;
53  }
54 
55  /// Destructor.
57 
58  /// Initialize auxiliary vectors and other data members
59  void initialize(ElementCacheMap *element_cache_map) {
60  this->element_cache_map_ = element_cache_map;
61 
62  this->fe_values_->template initialize<dim>(*this->quad_);
63  ndofs_ = this->n_dofs();
64  dof_indices_.resize(ndofs_);
65  local_matrix_.resize(4*ndofs_*ndofs_);
66  local_retardation_balance_vector_.resize(ndofs_);
68 
69  }
70 
71 
72  /// Assemble integral over element
73  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
74  {
75  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
76 
78 
79  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); ++sbi)
80  {
81  // assemble the local mass matrix
82  for (unsigned int i=0; i<ndofs_; i++)
83  {
84  for (unsigned int j=0; j<ndofs_; j++)
85  {
86  local_matrix_[i*ndofs_+j] = 0;
87  for (auto p : this->bulk_points(element_patch_idx) )
88  {
89  local_matrix_[i*ndofs_+j] += (eq_fields_->mass_matrix_coef(p)+eq_fields_->retardation_coef[sbi](p)) *
90  conc_shape_.shape(j)(p)*conc_shape_.shape(i)(p)*JxW_(p);
91  }
92  }
93  }
94 
95  for (unsigned int i=0; i<ndofs_; i++)
96  {
99  for (auto p : this->bulk_points(element_patch_idx) )
100  {
101  local_mass_balance_vector_[i] += eq_fields_->mass_matrix_coef(p)*conc_shape_.shape(i)(p)*JxW_(p);
102  local_retardation_balance_vector_[i] -= eq_fields_->retardation_coef[sbi](p)*conc_shape_.shape(i)(p)*JxW_(p);
103  }
104  }
105 
106  eq_data_->balance_->add_mass_values(eq_data_->subst_idx()[sbi], cell, cell.get_loc_dof_indices(),
108 
110  VecSetValues(eq_data_->ret_vec[sbi], ndofs_, &(dof_indices_[0]), &(local_retardation_balance_vector_[0]), ADD_VALUES);
111  }
112  }
113 
114  /// Implements @p AssemblyBase::begin.
115  void begin() override
116  {
117  eq_data_->balance_->start_mass_assembly( eq_data_->subst_idx() );
118  }
119 
120  /// Implements @p AssemblyBase::end.
121  void end() override
122  {
123  eq_data_->balance_->finish_mass_assembly( eq_data_->subst_idx() );
124  }
125 
126  private:
127  /// Data objects shared with TransportDG
130 
131  /// Sub field set contains fields used in calculation.
133 
134  unsigned int ndofs_; ///< Number of dofs
135  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
136  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
137  vector<PetscScalar> local_retardation_balance_vector_; ///< Auxiliary vector for assemble mass matrix.
139 
143 
144  template < template<IntDim...> class DimAssembly>
145  friend class GenericAssembly;
146 
147 };
148 
149 
150 // return the ratio of longest and shortest edge
152 {
153  double h_max = 0, h_min = numeric_limits<double>::infinity();
154  for (unsigned int i=0; i<e->n_nodes(); i++)
155  for (unsigned int j=i+1; j<e->n_nodes(); j++)
156  {
157  double dist = arma::norm(*e.node(i) - *e.node(j));
158  h_max = max(h_max, dist);
159  h_min = min(h_min, dist);
160  }
161  return h_max/h_min;
162 }
163 /**
164  * @brief Computes average normal diffusivity over a set of points
165  *
166  * @param diff_coef Diffusion tensor.
167  * @param pts Points.
168  * @param nv Normal vector.
169  * @return double
170  */
172 {
173  double delta = 0;
174  unsigned int n = 0;
175  for (auto p : pts )
176  {
177  delta += dot(diff_coef(p)*nv, nv);
178  n++;
179  }
180  return n == 0 ? 0 : (delta/n);
181 }
182 
183 
184 /**
185  * @brief Computes the penalty parameter of the DG method on a given boundary edge.
186  *
187  * Assumption is that the edge consists of only 1 side.
188  * @param side The boundary side.
189  * @param diff_delta Average normal dispersivity K*n.n computed by diffusion_delta()
190  * @param ad_vector Advection vector.
191  * @param alpha Penalty parameter that influences the continuity
192  * of the solution (large value=more continuity).
193  */
195  const double &diff_delta,
196  const double flux,
197  const double alpha)
198 {
199  return 0.5*fabs(flux) + alpha/side.diameter()*diff_delta*elem_anisotropy(side.element());
200 }
201 
202 
203 /**
204  * @brief Computes advective flux.
205  *
206  * @param advection_coef Advection vector.
207  * @param pts Quadrature points.
208  * @param JxW JxW accessor.
209  * @param normal normalW accessor.
210  * @return double
211  */
212 template <class PointType>
214 {
215  double side_flux = 0;
216  for (auto p : pts) {
217  side_flux += arma::dot(advection_coef(p), normal(p))*JxW(p);
218  }
219  return side_flux;
220 }
221 
222 
223 /**
224  * Auxiliary container class for Finite element and related objects of given dimension.
225  */
226 template <unsigned int dim, class Model>
228 {
229 public:
232 
233  static constexpr const char * name() { return "StiffnessAssemblyDG"; }
234 
235  /// Constructor.
236  StiffnessAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
237  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
238  JxW_( this->bulk_values().JxW() ),
239  JxW_side_( this->side_values().JxW() ),
240  normal_( this->side_values().normal_vector() ),
241  ref_scalar_( this->bulk_values().ref_scalar() ),
242  ref_scalar_side_( this->side_values().ref_scalar() ),
243  ref_scalar_grad_( this->bulk_values().ref_scalar_grad() ),
244  ref_scalar_grad_side_( this->side_values().ref_scalar_grad() ),
245  conc_shape_( this->bulk_values().scalar_shape() ),
246  conc_shape_side_( this->side_values().scalar_shape() ),
247  conc_grad_( this->bulk_values().grad_scalar_shape() ),
248  conc_grad_sidw_( this->side_values().grad_scalar_shape() ),
249  conc_join_shape_( FeQJoin<Scalar>( this->join_values().scalar_join_shape() ) ) {
251  this->used_fields_ += eq_fields_->advection_coef;
252  this->used_fields_ += eq_fields_->diffusion_coef;
253  this->used_fields_ += eq_fields_->cross_section;
255  this->used_fields_ += eq_fields_->sources_sigma_out;
257  this->used_fields_ += eq_fields_->bc_type;
258  this->used_fields_ += eq_fields_->bc_robin_sigma;
259  }
260 
261  /// Destructor.
263  for (auto a : averages) if (a != nullptr) delete[] a;
264  for (auto a : waverages) if (a != nullptr) delete[] a;
265  for (auto a : jumps) if (a != nullptr) delete[] a;
266  }
267 
268  /// Initialize auxiliary vectors and other data members
269  void initialize(ElementCacheMap *element_cache_map) {
270  this->element_cache_map_ = element_cache_map;
271 
272  this->fe_values_->template initialize<dim>(*this->quad_);
273  this->fe_values_->template initialize<dim>(*this->quad_low_);
274  ndofs_ = this->n_dofs();
275  qsize_lower_dim_ = this->quad_low_->size();
276  dof_indices_.resize(ndofs_);
277  side_dof_indices_vb_.resize(2*ndofs_);
278  local_matrix_.resize(4*ndofs_*ndofs_);
279 
280  for (unsigned int sid=0; sid<eq_data_->max_edg_sides; sid++)
281  {
283  }
284 
286  for (unsigned int s=0; s<eq_data_->max_edg_sides; s++)
287  averages[s] = new double[qsize_lower_dim_*ndofs_];
288  waverages.resize(2);
289  jumps.resize(2);
290  for (unsigned int s=0; s<2; s++)
291  {
292  waverages[s] = new double[qsize_lower_dim_*ndofs_];
293  jumps[s] = new double[qsize_lower_dim_*ndofs_];
294  }
295  }
296 
297 
298  /// Assembles the cell (volume) integral into the stiffness matrix.
299  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
300  {
301  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
302  if (!cell.is_own()) return;
303 
305 
306  // assemble the local stiffness matrix
307  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
308  {
309  for (unsigned int i=0; i<ndofs_; i++)
310  for (unsigned int j=0; j<ndofs_; j++)
311  local_matrix_[i*ndofs_+j] = 0;
312 
313  for (auto p : this->bulk_points(element_patch_idx) )
314  {
315  for (unsigned int i=0; i<ndofs_; i++)
316  {
317  arma::vec3 Kt_grad_i = eq_fields_->diffusion_coef[sbi](p).t()*conc_grad_.shape(i)(p);
318  double ad_dot_grad_i = arma::dot(eq_fields_->advection_coef[sbi](p), conc_grad_.shape(i)(p));
319 
320  for (unsigned int j=0; j<ndofs_; j++)
321  local_matrix_[i*ndofs_+j] += (arma::dot(Kt_grad_i, conc_grad_.shape(j)(p))
322  -conc_shape_.shape(j)(p)*ad_dot_grad_i
323  +eq_fields_->sources_sigma_out[sbi](p)*conc_shape_.shape(j)(p)*conc_shape_.shape(i)(p))*JxW_(p);
324  }
325  }
327  }
328  }
329 
330 
331  /// Assembles the fluxes on the boundary.
332  inline void boundary_side_integral(DHCellSide cell_side)
333  {
334  ASSERT_EQ(cell_side.dim(), dim).error("Dimension of element mismatch!");
335  if (!cell_side.cell().is_own()) return;
336 
337  Side side = cell_side.side();
338  const DHCellAccessor &cell = cell_side.cell();
339 
341  unsigned int k;
342  double gamma_l;
343 
344  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
345  {
346  std::fill(local_matrix_.begin(), local_matrix_.end(), 0);
347 
348  double side_flux = advective_flux(eq_fields_->advection_coef[sbi], this->boundary_points(cell_side), JxW_side_, normal_);
349  double transport_flux = side_flux/side.measure();
350 
351  // On Neumann boundaries we have only term from integrating by parts the advective term,
352  // on Dirichlet boundaries we additionally apply the penalty which enforces the prescribed value.
353  auto p_side = *( this->boundary_points(cell_side).begin() );
354  auto p_bdr = p_side.point_bdr( side.cond().element_accessor() );
355  unsigned int bc_type = eq_fields_->bc_type[sbi](p_bdr);
357  {
358  // set up the parameters for DG method
359  auto p = *( this->boundary_points(cell_side).begin() );
360  gamma_l = DG_penalty_boundary(side,
361  diffusion_delta(eq_fields_->diffusion_coef[sbi], this->boundary_points(cell_side), normal_(p)),
362  transport_flux,
363  eq_fields_->dg_penalty[sbi](p_side));
364  transport_flux += gamma_l;
365  }
366 
367  // fluxes and penalty
368  k=0;
369  for (auto p : this->boundary_points(cell_side) )
370  {
371  double flux_times_JxW;
373  {
374  //sigma_ corresponds to robin_sigma
375  auto p_bdr = p.point_bdr(side.cond().element_accessor());
376  flux_times_JxW = eq_fields_->cross_section(p)*eq_fields_->bc_robin_sigma[sbi](p_bdr)*JxW_side_(p);
377  }
379  {
380  auto p_bdr = p.point_bdr(side.cond().element_accessor());
381  flux_times_JxW = (transport_flux + eq_fields_->cross_section(p)*eq_fields_->bc_robin_sigma[sbi](p_bdr))*JxW_side_(p);
382  }
383  else if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux < 0)
384  flux_times_JxW = 0;
385  else
386  flux_times_JxW = transport_flux*JxW_side_(p);
387 
388  for (unsigned int i=0; i<ndofs_; i++)
389  {
390  for (unsigned int j=0; j<ndofs_; j++)
391  {
392  // flux due to advection and penalty
393  local_matrix_[i*ndofs_+j] += flux_times_JxW*conc_shape_side_.shape(i)(p)*conc_shape_side_.shape(j)(p);
394 
395  // flux due to diffusion (only on dirichlet and inflow boundary)
397  local_matrix_[i*ndofs_+j] -= (arma::dot(eq_fields_->diffusion_coef[sbi](p)*conc_grad_sidw_.shape(j)(p),normal_(p))*conc_shape_side_.shape(i)(p)
398  + arma::dot(eq_fields_->diffusion_coef[sbi](p)*conc_grad_sidw_.shape(i)(p),normal_(p))*conc_shape_side_.shape(j)(p)*eq_data_->dg_variant
399  )*JxW_side_(p);
400  }
401  }
402  k++;
403  }
404 
406  }
407  }
408 
409 
410  /// Assembles the fluxes between sides of elements of the same dimension.
412  ASSERT_EQ(edge_side_range.begin()->element().dim(), dim).error("Dimension of element mismatch!");
413 
414  unsigned int k;
415  double gamma_l, omega[2], transport_flux, delta[2], delta_sum;
416  double aniso1, aniso2;
417  double local_alpha=0.0;
418  int sid=0, s1, s2;
419  for( DHCellSide edge_side : edge_side_range )
420  {
421  auto dh_edge_cell = eq_data_->dh_->cell_accessor_from_element( edge_side.elem_idx() );
422  dh_edge_cell.get_dof_indices(side_dof_indices_[sid]);
423  ++sid;
424  }
425  auto zero_edge_side = *edge_side_range.begin();
426  auto p = *( this->edge_points(zero_edge_side).begin() );
427  arma::vec3 normal_vector = normal_(p);
428 
429  // fluxes and penalty
430  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
431  {
432  vector<double> fluxes(edge_side_range.begin()->n_edge_sides());
433  double pflux = 0, nflux = 0; // calculate the total in- and out-flux through the edge
434  sid=0;
435  for( DHCellSide edge_side : edge_side_range )
436  {
437  fluxes[sid] = advective_flux(eq_fields_->advection_coef[sbi], this->edge_points(edge_side), JxW_side_, normal_) / edge_side.measure();
438  if (fluxes[sid] > 0)
439  pflux += fluxes[sid];
440  else
441  nflux += fluxes[sid];
442  ++sid;
443  }
444 
445  // precompute averages of shape functions over pairs of sides
446  s1=0;
447  for (DHCellSide edge_side : edge_side_range)
448  {
449  k=0;
450  for (auto p : this->edge_points(edge_side) )
451  {
452  for (unsigned int i=0; i<ndofs_; i++)
453  averages[s1][k*ndofs_+i] = conc_shape_side_.shape(i)(p)*0.5;
454  k++;
455  }
456  s1++;
457  }
458 
459 
460 
461  s1=0;
462  for( DHCellSide edge_side1 : edge_side_range )
463  {
464  s2=-1; // need increment at begin of loop (see conditionally 'continue' directions)
465  for( DHCellSide edge_side2 : edge_side_range )
466  {
467  s2++;
468  if (s2<=s1) continue;
469  ASSERT(edge_side1.is_valid()).error("Invalid side of edge.");
470 
471  auto p = *( this->edge_points(edge_side1).begin() );
472  arma::vec3 nv = normal_(p);
473 
474  // set up the parameters for DG method
475  // calculate the flux from edge_side1 to edge_side2
476  if (fluxes[s2] > 0 && fluxes[s1] < 0)
477  transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
478  else if (fluxes[s2] < 0 && fluxes[s1] > 0)
479  transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
480  else
481  transport_flux = 0;
482 
483  gamma_l = 0.5*fabs(transport_flux);
484 
485  delta[0] = 0;
486  delta[1] = 0;
487  for (auto p1 : this->edge_points(edge_side1) )
488  {
489  auto p2 = p1.point_on(edge_side2);
490  delta[0] += dot(eq_fields_->diffusion_coef[sbi](p1)*normal_vector,normal_vector);
491  delta[1] += dot(eq_fields_->diffusion_coef[sbi](p2)*normal_vector,normal_vector);
492  local_alpha = max(eq_fields_->dg_penalty[sbi](p1), eq_fields_->dg_penalty[sbi](p2));
493  }
494  delta[0] /= qsize_lower_dim_;
495  delta[1] /= qsize_lower_dim_;
496 
497  delta_sum = delta[0] + delta[1];
498 
499 // if (delta_sum > numeric_limits<double>::epsilon())
500  if (fabs(delta_sum) > 0)
501  {
502  omega[0] = delta[1]/delta_sum;
503  omega[1] = delta[0]/delta_sum;
504  double h = edge_side1.diameter();
505  aniso1 = elem_anisotropy(edge_side1.element());
506  aniso2 = elem_anisotropy(edge_side2.element());
507  gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
508  }
509  else
510  for (int i=0; i<2; i++) omega[i] = 0;
511  // end of set up the parameters for DG method
512 
513  int sd[2]; bool is_side_own[2];
514  sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
515  sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
516 
517  // precompute jumps and weighted averages of shape functions over the pair of sides (s1,s2)
518  k=0;
519  for (auto p1 : this->edge_points(edge_side1) )
520  {
521  auto p2 = p1.point_on(edge_side2);
522  for (unsigned int i=0; i<ndofs_; i++)
523  {
524  jumps[0][k*ndofs_+i] = conc_shape_side_.shape(i)(p1);
525  jumps[1][k*ndofs_+i] = - conc_shape_side_.shape(i)(p2);
526  waverages[0][k*ndofs_+i] = arma::dot(eq_fields_->diffusion_coef[sbi](p1)*conc_grad_sidw_.shape(i)(p1),nv)*omega[0];
527  waverages[1][k*ndofs_+i] = arma::dot(eq_fields_->diffusion_coef[sbi](p2)*conc_grad_sidw_.shape(i)(p2),nv)*omega[1];
528  }
529  k++;
530  }
531 
532  // For selected pair of elements:
533  for (int n=0; n<2; n++)
534  {
535  if (!is_side_own[n]) continue;
536 
537  for (int m=0; m<2; m++)
538  {
539  for (unsigned int i=0; i<ndofs_; i++)
540  for (unsigned int j=0; j<ndofs_; j++)
541  local_matrix_[i*ndofs_+j] = 0;
542 
543  k=0;
544  for (auto p1 : this->edge_points(zero_edge_side) )
545  //for (k=0; k<this->quad_low_->size(); ++k)
546  {
547  for (unsigned int i=0; i<ndofs_; i++)
548  {
549  for (unsigned int j=0; j<ndofs_; j++)
550  {
551  int index = i*ndofs_+j;
552 
553  local_matrix_[index] += (
554  // flux due to transport (applied on interior edges) (average times jump)
555  transport_flux*jumps[n][k*ndofs_+i]*averages[sd[m]][k*ndofs_+j]
556 
557  // penalty enforcing continuity across edges (applied on interior and Dirichlet edges) (jump times jump)
558  + gamma_l*jumps[n][k*ndofs_+i]*jumps[m][k*ndofs_+j]
559 
560  // terms due to diffusion
561  - jumps[n][k*ndofs_+i]*waverages[m][k*ndofs_+j]
562  - eq_data_->dg_variant*waverages[n][k*ndofs_+i]*jumps[m][k*ndofs_+j]
564  }
565  }
566  k++;
567  }
568  eq_data_->ls[sbi]->mat_set_values(ndofs_, &(side_dof_indices_[sd[n]][0]), ndofs_, &(side_dof_indices_[sd[m]][0]), &(local_matrix_[0]));
569  }
570  }
571  }
572  s1++;
573  }
574  }
575  }
576 
577 
578  /// Assembles the fluxes between elements of different dimensions.
579  inline void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side) {
580  if (dim == 1) return;
581  ASSERT_EQ(cell_lower_dim.dim(), dim-1).error("Dimension of element mismatch!");
582 
583  // Note: use data members csection_ and velocity_ for appropriate quantities of lower dim element
584 
585  unsigned int n_dofs[2];
586  unsigned int n_indices = cell_lower_dim.get_dof_indices(dof_indices_);
587  for(unsigned int i=0; i<n_indices; ++i) {
589  }
591 
592  DHCellAccessor cell_higher_dim = eq_data_->dh_->cell_accessor_from_element( neighb_side.element().idx() );
593  n_indices = cell_higher_dim.get_dof_indices(dof_indices_);
594  for(unsigned int i=0; i<n_indices; ++i) {
596  }
598 
599  // Testing element if they belong to local partition.
600  bool own_element_id[2];
601  own_element_id[0] = cell_lower_dim.is_own();
602  own_element_id[1] = cell_higher_dim.is_own();
603 
604  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++) // Optimize: SWAP LOOPS
605  {
606  for (unsigned int i=0; i<n_dofs[0]+n_dofs[1]; i++)
607  for (unsigned int j=0; j<n_dofs[0]+n_dofs[1]; j++)
608  local_matrix_[i*(n_dofs[0]+n_dofs[1])+j] = 0;
609 
610  // set transmission conditions
611  for (auto p_high : this->coupling_points(neighb_side) )
612  {
613  auto p_low = p_high.lower_dim(cell_lower_dim);
614  // The communication flux has two parts:
615  // - "diffusive" term containing sigma
616  // - "advective" term representing usual upwind
617  //
618  // The calculation differs from the reference manual, since ad_coef and dif_coef have different meaning
619  // than b and A in the manual.
620  // In calculation of sigma there appears one more csection_lower in the denominator.
621  double sigma = eq_fields_->fracture_sigma[sbi](p_low)*arma::dot(eq_fields_->diffusion_coef[sbi](p_low)*normal_(p_high),normal_(p_high))*
622  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));
623 
624  double transport_flux = arma::dot(eq_fields_->advection_coef[sbi](p_high), normal_(p_high));
625 
626  for (uint i=0; i<conc_join_shape_.n_dofs_both(); ++i) {
627  uint is_high_i = conc_join_shape_.is_high_dim(i);
628  if (!own_element_id[is_high_i]) continue;
629  double diff_shape_i = conc_join_shape_.shape(i)(p_high) - conc_join_shape_.shape(i)(p_low);
630  for (uint j=0; j<conc_join_shape_.n_dofs_both(); ++j) {
631  local_matrix_[i * (n_dofs[0]+n_dofs[1]) + j] += (
632  sigma * diff_shape_i * (conc_join_shape_.shape(j)(p_high) - conc_join_shape_.shape(j)(p_low))
633  + diff_shape_i * ( max(0.,transport_flux) * conc_join_shape_.shape(j)(p_high) + min(0.,transport_flux) * conc_join_shape_.shape(j)(p_low))
635  }
636  }
637  }
639  }
640  }
641 
642 
643 private:
644  /// Data objects shared with TransportDG
647 
648  /// Sub field set contains fields used in calculation.
650 
651  unsigned int ndofs_; ///< Number of dofs
652  unsigned int qsize_lower_dim_; ///< Size of quadrature of dim-1
653 
654  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
655  vector< vector<LongIdx> > side_dof_indices_; ///< Vector of vectors of side DOF indices
656  vector<LongIdx> side_dof_indices_vb_; ///< Vector of side DOF indices (assemble element-side fluxex)
657  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
658 
659  vector<double*> averages; ///< Auxiliary storage for averages of shape functions.
660  vector<double*> waverages; ///< Auxiliary storage for weighted averages of shape functions.
661  vector<double*> jumps; ///< Auxiliary storage for jumps of shape functions.
662 
675 
676  template < template<IntDim...> class DimAssembly>
677  friend class GenericAssembly;
678 
679 };
680 
681 
682 /**
683  * Auxiliary container class for Finite element and related objects of given dimension.
684  */
685 template <unsigned int dim, class Model>
687 {
688 public:
691 
692  static constexpr const char * name() { return "SourcesAssemblyDG"; }
693 
694  /// Constructor.
695  SourcesAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
696  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
697  JxW_( this->bulk_values().JxW() ),
698  ref_scalar_( this->bulk_values().ref_scalar() ),
699  conc_shape_( this->bulk_values().scalar_shape() ) {
701  this->used_fields_ += eq_fields_->sources_density_out;
702  this->used_fields_ += eq_fields_->sources_conc_out;
703  this->used_fields_ += eq_fields_->sources_sigma_out;
704  }
705 
706  /// Destructor.
708 
709  /// Initialize auxiliary vectors and other data members
710  void initialize(ElementCacheMap *element_cache_map) {
711  this->element_cache_map_ = element_cache_map;
712 
713  this->fe_values_->template initialize<dim>(*this->quad_);
714  ndofs_ = this->n_dofs();
715  dof_indices_.resize(ndofs_);
716  local_rhs_.resize(ndofs_);
719  }
720 
721 
722  /// Assemble integral over element
723  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
724  {
725  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
726 
727  ElementAccessor<3> elm = cell.elm();
728  double source;
729 
731 
732  // assemble the local stiffness matrix
733  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
734  {
735  fill_n( &(local_rhs_[0]), ndofs_, 0 );
738 
739  for (auto p : this->bulk_points(element_patch_idx) )
740  {
741  source = (eq_fields_->sources_density_out[sbi](p) + eq_fields_->sources_conc_out[sbi](p)*eq_fields_->sources_sigma_out[sbi](p))*JxW_(p);
742 
743  for (unsigned int i=0; i<ndofs_; i++)
744  local_rhs_[i] += source*conc_shape_.shape(i)(p);
745  }
746  eq_data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
747 
748  for (unsigned int i=0; i<ndofs_; i++)
749  {
750  for (auto p : this->bulk_points(element_patch_idx) )
751  {
752  local_source_balance_vector_[i] -= eq_fields_->sources_sigma_out[sbi](p)*conc_shape_.shape(i)(p)*JxW_(p);
753  }
754 
756  }
757  eq_data_->balance_->add_source_values(eq_data_->subst_idx()[sbi], elm.region().bulk_idx(),
758  cell.get_loc_dof_indices(),
760  }
761  }
762 
763  /// Implements @p AssemblyBase::begin.
764  void begin() override
765  {
766  eq_data_->balance_->start_source_assembly( eq_data_->subst_idx() );
767  }
768 
769  /// Implements @p AssemblyBase::end.
770  void end() override
771  {
772  eq_data_->balance_->finish_source_assembly( eq_data_->subst_idx() );
773  }
774 
775 
776  private:
777  /// Data objects shared with TransportDG
780 
781  /// Sub field set contains fields used in calculation.
783 
784  unsigned int ndofs_; ///< Number of dofs
785 
786  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
787  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
788  vector<PetscScalar> local_source_balance_vector_; ///< Auxiliary vector for set_sources method.
789  vector<PetscScalar> local_source_balance_rhs_; ///< Auxiliary vector for set_sources method.
790 
794 
795  template < template<IntDim...> class DimAssembly>
796  friend class GenericAssembly;
797 
798 };
799 
800 
801 /**
802  * Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions..
803  */
804 template <unsigned int dim, class Model>
806 {
807 public:
810 
811  static constexpr const char * name() { return "BdrConditionAssemblyDG"; }
812 
813  /// Constructor.
814  BdrConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
815  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
816  JxW_( this->side_values().JxW() ),
817  normal_( this->side_values().normal_vector() ),
818  ref_scalar_side_( this->side_values().ref_scalar() ),
819  ref_scalar_grad_side_( this->side_values().ref_scalar_grad() ),
820  conc_shape_( this->side_values().scalar_shape() ),
821  conc_grad_( this->side_values().grad_scalar_shape() ) {
823  this->used_fields_ += eq_fields_->advection_coef;
824  this->used_fields_ += eq_fields_->diffusion_coef;
825  this->used_fields_ += eq_fields_->cross_section;
826  this->used_fields_ += eq_fields_->bc_type;
827  this->used_fields_ += eq_fields_->bc_dirichlet_value;
828  this->used_fields_ += eq_fields_->bc_robin_sigma;
829  this->used_fields_ += eq_fields_->bc_flux;
830  }
831 
832  /// Destructor.
834 
835  /// Initialize auxiliary vectors and other data members
836  void initialize(ElementCacheMap *element_cache_map) {
837  this->element_cache_map_ = element_cache_map;
838 
839  this->fe_values_->template initialize<dim>(*this->quad_low_);
840  ndofs_ = this->n_dofs();
841  dof_indices_.resize(ndofs_);
842  local_rhs_.resize(ndofs_);
844  }
845 
846 
847  /// Implements @p AssemblyBase::boundary_side_integral.
848  inline void boundary_side_integral(DHCellSide cell_side)
849  {
850 
851  ElementAccessor<3> bc_elm = cell_side.cond().element_accessor();
852 
853  const DHCellAccessor &cell = cell_side.cell();
855 
856  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
857  {
858  fill_n(&(local_rhs_[0]), ndofs_, 0);
861 
862  double side_flux = advective_flux(eq_fields_->advection_coef[sbi], this->boundary_points(cell_side), JxW_, normal_);
863  double transport_flux = side_flux/cell_side.measure();
864 
865  auto p_side = *( this->boundary_points(cell_side)).begin();
866  auto p_bdr = p_side.point_bdr(cell_side.cond().element_accessor() );
867  unsigned int bc_type = eq_fields_->bc_type[sbi](p_bdr);
868  if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux < 0)
869  {
870  for (auto p : this->boundary_points(cell_side) )
871  {
872  auto p_bdr = p.point_bdr(bc_elm);
873  double bc_term = -transport_flux*eq_fields_->bc_dirichlet_value[sbi](p_bdr)*JxW_(p);
874  for (unsigned int i=0; i<ndofs_; i++)
875  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p);
876  }
877  for (unsigned int i=0; i<ndofs_; i++)
879  }
880  else if (bc_type == AdvectionDiffusionModel::abc_dirichlet)
881  {
882  double side_flux = advective_flux(eq_fields_->advection_coef[sbi], this->boundary_points(cell_side), JxW_, normal_);
883  double transport_flux = side_flux/cell_side.measure();
884 
885  auto p = *( this->boundary_points(cell_side).begin() );
886  double gamma_l = DG_penalty_boundary(cell_side.side(),
887  diffusion_delta(eq_fields_->diffusion_coef[sbi], this->boundary_points(cell_side), normal_(p)),
888  transport_flux,
889  eq_fields_->dg_penalty[sbi](p_bdr));
890 
891  for (auto p : this->boundary_points(cell_side) )
892  {
893  auto p_bdr = p.point_bdr(bc_elm);
894  double bc_term = gamma_l*eq_fields_->bc_dirichlet_value[sbi](p_bdr)*JxW_(p);
895  arma::vec3 bc_grad = -eq_fields_->bc_dirichlet_value[sbi](p_bdr)*JxW_(p)*eq_data_->dg_variant*(arma::trans(eq_fields_->diffusion_coef[sbi](p))*normal_(p));
896  for (unsigned int i=0; i<ndofs_; i++)
897  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p)
898  + arma::dot(bc_grad,conc_grad_.shape(i)(p));
899  }
900  for (auto p : this->boundary_points(cell_side) )
901  {
902  for (unsigned int i=0; i<ndofs_; i++)
903  {
904  local_flux_balance_vector_[i] += (arma::dot(eq_fields_->advection_coef[sbi](p), normal_(p))*conc_shape_.shape(i)(p)
905  - arma::dot(eq_fields_->diffusion_coef[sbi](p)*conc_grad_.shape(i)(p),normal_(p))
906  + gamma_l*conc_shape_.shape(i)(p))*JxW_(p);
907  }
908  }
909  if (eq_data_->time_->step().index() > 0)
910  for (unsigned int i=0; i<ndofs_; i++)
912  }
913  else if (bc_type == AdvectionDiffusionModel::abc_total_flux)
914  {
915  for (auto p : this->boundary_points(cell_side) )
916  {
917  auto p_bdr = p.point_bdr(bc_elm);
918  double bc_term = eq_fields_->cross_section(p) * (eq_fields_->bc_robin_sigma[sbi](p_bdr)*eq_fields_->bc_dirichlet_value[sbi](p_bdr) +
919  eq_fields_->bc_flux[sbi](p_bdr)) * JxW_(p);
920  for (unsigned int i=0; i<ndofs_; i++)
921  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p);
922  }
923 
924  for (unsigned int i=0; i<ndofs_; i++)
925  {
926  for (auto p : this->boundary_points(cell_side) ) {
927  auto p_bdr = p.point_bdr(bc_elm);
928  local_flux_balance_vector_[i] += eq_fields_->cross_section(p) * eq_fields_->bc_robin_sigma[sbi](p_bdr) *
929  JxW_(p) * conc_shape_.shape(i)(p);
930  }
932  }
933  }
935  {
936  for (auto p : this->boundary_points(cell_side) )
937  {
938  auto p_bdr = p.point_bdr(bc_elm);
939  double bc_term = eq_fields_->cross_section(p) * (eq_fields_->bc_robin_sigma[sbi](p_bdr)*eq_fields_->bc_dirichlet_value[sbi](p_bdr) +
940  eq_fields_->bc_flux[sbi](p_bdr)) * JxW_(p);
941  for (unsigned int i=0; i<ndofs_; i++)
942  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p);
943  }
944 
945  for (unsigned int i=0; i<ndofs_; i++)
946  {
947  for (auto p : this->boundary_points(cell_side) ) {
948  auto p_bdr = p.point_bdr(bc_elm);
949  local_flux_balance_vector_[i] += eq_fields_->cross_section(p)*(arma::dot(eq_fields_->advection_coef[sbi](p), normal_(p)) +
950  eq_fields_->bc_robin_sigma[sbi](p_bdr))*JxW_(p)*conc_shape_.shape(i)(p);
951  }
953  }
954  }
955  else if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux >= 0)
956  {
957  for (auto p : this->boundary_points(cell_side) )
958  {
959  for (unsigned int i=0; i<ndofs_; i++)
960  local_flux_balance_vector_[i] += arma::dot(eq_fields_->advection_coef[sbi](p), normal_(p))*JxW_(p)*conc_shape_.shape(i)(p);
961  }
962  }
963  eq_data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
964 
965  eq_data_->balance_->add_flux_values(eq_data_->subst_idx()[sbi], cell_side,
966  cell.get_loc_dof_indices(),
968  }
969  }
970 
971  /// Implements @p AssemblyBase::begin.
972  void begin() override
973  {
974  eq_data_->balance_->start_flux_assembly( eq_data_->subst_idx() );
975  }
976 
977  /// Implements @p AssemblyBase::end.
978  void end() override
979  {
980  eq_data_->balance_->finish_flux_assembly( eq_data_->subst_idx() );
981  }
982 
983 
984  private:
985  /// Data objects shared with TransportDG
988 
989  unsigned int ndofs_; ///< Number of dofs
990 
991  /// Sub field set contains fields used in calculation.
993 
994  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
995  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
996  vector<PetscScalar> local_flux_balance_vector_; ///< Auxiliary vector for set_boundary_conditions method.
997  PetscScalar local_flux_balance_rhs_; ///< Auxiliary variable for set_boundary_conditions method.
998 
1005 
1006  template < template<IntDim...> class DimAssembly>
1007  friend class GenericAssembly;
1008 
1009 };
1010 
1011 
1012 /**
1013  * Auxiliary container class sets the initial condition.
1014  */
1015 template <unsigned int dim, class Model>
1017 {
1018 public:
1021 
1022  static constexpr const char * name() { return "InitProjectionAssemblyDG"; }
1023 
1024  /// Constructor.
1025  InitProjectionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
1026  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
1027  JxW_( this->bulk_values().JxW() ),
1028  ref_scalar_( this->bulk_values().ref_scalar() ),
1029  init_shape_( this->bulk_values().scalar_shape() ) {
1031  this->used_fields_ += eq_fields_->init_condition;
1032  }
1033 
1034  /// Destructor.
1036 
1037  /// Initialize auxiliary vectors and other data members
1038  void initialize(ElementCacheMap *element_cache_map) {
1039  this->element_cache_map_ = element_cache_map;
1040 
1041  this->fe_values_->template initialize<dim>(*this->quad_);
1042  ndofs_ = this->n_dofs();
1043  dof_indices_.resize(ndofs_);
1044  local_matrix_.resize(4*ndofs_*ndofs_);
1045  local_rhs_.resize(ndofs_);
1046  }
1047 
1048 
1049  /// Assemble integral over element
1050  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
1051  {
1052  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
1053 
1055 
1056  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
1057  {
1058  for (unsigned int i=0; i<ndofs_; i++)
1059  {
1060  local_rhs_[i] = 0;
1061  for (unsigned int j=0; j<ndofs_; j++)
1062  local_matrix_[i*ndofs_+j] = 0;
1063  }
1064 
1065  for (auto p : this->bulk_points(element_patch_idx) )
1066  {
1067  double rhs_term = eq_fields_->init_condition[sbi](p)*JxW_(p);
1068 
1069  for (unsigned int i=0; i<ndofs_; i++)
1070  {
1071  for (unsigned int j=0; j<ndofs_; j++)
1072  local_matrix_[i*ndofs_+j] += init_shape_.shape(i)(p)*init_shape_.shape(j)(p)*JxW_(p);
1073 
1074  local_rhs_[i] += init_shape_.shape(i)(p)*rhs_term;
1075  }
1076  }
1077  eq_data_->ls[sbi]->set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]), &(local_rhs_[0]));
1078  }
1079  }
1080 
1081 
1082  private:
1083  /// Data objects shared with TransportDG
1086 
1087  /// Sub field set contains fields used in calculation.
1089 
1090  unsigned int ndofs_; ///< Number of dofs
1091  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
1092  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
1093  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
1094 
1098 
1099  template < template<IntDim...> class DimAssembly>
1100  friend class GenericAssembly;
1101 
1102 };
1103 
1104 
1105 /**
1106  * Auxiliary container class sets the initial condition.
1107  */
1108 template <unsigned int dim, class Model>
1110 {
1111 public:
1114 
1115  static constexpr const char * name() { return "InitConditionAssemblyDG"; }
1116 
1117  /// Constructor.
1119  : AssemblyBase<dim>(), eq_fields_(eq_fields), eq_data_(eq_data) {
1121  this->used_fields_ += eq_fields_->init_condition;
1122 
1123  this->quad_ = new Quadrature(dim, RefElement<dim>::n_nodes);
1124  for(unsigned int i = 0; i<RefElement<dim>::n_nodes; i++)
1125  {
1126  this->quad_->weight(i) = 1.0;
1127  this->quad_->set(i) = RefElement<dim>::node_coords(i);
1128  }
1129  }
1130 
1131  /// Destructor.
1133 
1134  /// Initialize auxiliary vectors and other data members
1135  void initialize(ElementCacheMap *element_cache_map) {
1136  this->element_cache_map_ = element_cache_map;
1137  }
1138 
1139 
1140  /// Assemble integral over element
1141  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
1142  {
1143  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
1144 
1145  unsigned int k;
1146 
1147  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
1148  {
1149  k=0;
1150  for (auto p : this->bulk_points(element_patch_idx) )
1151  {
1152  double val = eq_fields_->init_condition[sbi](p);
1153 
1154  eq_data_->output_vec[sbi].set(cell.get_loc_dof_indices()[k], val);
1155  k++;
1156  }
1157  }
1158  }
1159 
1160 
1161  private:
1162  /// Data objects shared with TransportDG
1165 
1166  /// Sub field set contains fields used in calculation.
1168 
1169  template < template<IntDim...> class DimAssembly>
1170  friend class GenericAssembly;
1171 
1172 };
1173 
1174 #endif /* ASSEMBLY_DG_HH_ */
1175 
double advective_flux(Field< 3, FieldValue< 3 >::VectorFixed > &advection_coef, Range< PointType > pts, FeQ< Scalar > &JxW, ElQ< Vector > normal)
Computes advective flux.
Definition: assembly_dg.hh:213
double elem_anisotropy(ElementAccessor< 3 > e)
Definition: assembly_dg.hh:151
double DG_penalty_boundary(Side side, const double &diff_delta, const double flux, const double alpha)
Computes the penalty parameter of the DG method on a given boundary edge.
Definition: assembly_dg.hh:194
double diffusion_delta(Field< 3, FieldValue< 3 >::TensorFixed > &diff_coef, Range< BoundaryPoint > pts, const arma::vec3 &nv)
Computes average normal diffusivity over a set of points.
Definition: assembly_dg.hh:171
#define ASSERT(expr)
Definition: asserts.hh:351
#define ASSERT_EQ(a, b)
Definition of comparative assert macro (EQual) only for debug mode.
Definition: asserts.hh:333
JoinValues< dim > join_values()
Return JoinValues object.
PatchFEValues< 3 > * fe_values_
Common FEValues object over all dimensions.
BulkValues< dim > bulk_values()
Return BulkValues object.
unsigned int n_dofs()
Return BulkValues object.
SideValues< dim > side_values()
Return SideValues object.
Range< BulkPoint > bulk_points(unsigned int element_patch_idx) const
Return BulkPoint range of appropriate dimension.
Range< EdgePoint > edge_points(const DHCellSide &cell_side) const
Return EdgePoint range of appropriate dimension.
Quadrature * quad_
Quadrature used in assembling methods.
Quadrature * quad_low_
Quadrature used in assembling methods (dim-1).
Range< CouplingPoint > coupling_points(const DHCellSide &cell_side) const
Return CouplingPoint range of appropriate dimension.
int active_integrals_
Holds mask of active integrals.
Range< BoundaryPoint > boundary_points(const DHCellSide &cell_side) const
Return BoundaryPoint range of appropriate dimension.
ElementCacheMap * element_cache_map_
ElementCacheMap shared with GenericAssembly object.
static constexpr const char * name()
Definition: assembly_dg.hh:811
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:992
vector< PetscScalar > local_flux_balance_vector_
Auxiliary vector for set_boundary_conditions method.
Definition: assembly_dg.hh:996
void boundary_side_integral(DHCellSide cell_side)
Implements AssemblyBase::boundary_side_integral.
Definition: assembly_dg.hh:848
BdrConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:814
FeQArray< Scalar > ref_scalar_side_
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:809
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:808
FeQArray< Scalar > conc_shape_
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:972
~BdrConditionAssemblyDG()
Destructor.
Definition: assembly_dg.hh:833
PetscScalar local_flux_balance_rhs_
Auxiliary variable for set_boundary_conditions method.
Definition: assembly_dg.hh:997
FeQArray< Vector > ref_scalar_grad_side_
FeQArray< Vector > conc_grad_
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:836
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:994
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:986
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:978
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:995
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:989
ElementAccessor< 3 > element_accessor()
Cell accessor allow iterate over DOF handler cells.
bool is_own() const
Return true if accessor represents own element (false for ghost element)
LocDofVec get_loc_dof_indices() const
Returns the local indices of dofs associated to the cell on the local process.
unsigned int get_dof_indices(std::vector< LongIdx > &indices) const
Fill vector of the global indices of dofs associated to the cell.
unsigned int dim() const
Return dimension of element appropriate to cell.
ElementAccessor< 3 > elm() const
Return ElementAccessor to element of loc_ele_idx_.
Side accessor allows to iterate over sides of DOF handler cell.
Side side() const
Return Side of given cell and side_idx.
Boundary cond() const
const DHCellAccessor & cell() const
Return DHCellAccessor appropriate to the side.
unsigned int dim() const
Return dimension of element appropriate to the side.
double measure() const
ElementAccessor< 3 > element() const
NodeAccessor< 3 > node(unsigned int ni) const
Definition: accessors.hh:230
Region region() const
Definition: accessors.hh:198
unsigned int idx() const
We need this method after replacing Region by RegionIdx, and movinf RegionDB instance into particular...
Definition: accessors.hh:215
Directing class of FieldValueCache.
unsigned int n_nodes() const
Definition: elements.h:125
FeQ< ValueType > shape(unsigned int i_shape_fn_idx) const
bool is_high_dim(unsigned int i_join_idx) const
unsigned int n_dofs_both() const
unsigned int n_dofs_low() const
unsigned int n_dofs_high() const
FeQ< ValueType > shape(unsigned int i_join_idx) const
Container for various descendants of FieldCommonBase.
Definition: field_set.hh:159
Class template representing a field with values dependent on: point, element, and region.
Definition: field.hh:92
Generic class of assemblation.
FieldSet used_fields_
Sub field set contains fields used in calculation.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
static constexpr const char * name()
~InitConditionAssemblyDG()
Destructor.
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
InitConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data)
Constructor.
EqFields * eq_fields_
Data objects shared with TransportDG.
TransportDG< Model >::EqData EqData
TransportDG< Model >::EqFields EqFields
EqFields * eq_fields_
Data objects shared with TransportDG.
FeQArray< Scalar > init_shape_
FeQArray< Scalar > ref_scalar_
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
vector< LongIdx > dof_indices_
Vector of global DOF indices.
TransportDG< Model >::EqData EqData
FieldSet used_fields_
Sub field set contains fields used in calculation.
unsigned int ndofs_
Number of dofs.
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
InitProjectionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
static constexpr const char * name()
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
~InitProjectionAssemblyDG()
Destructor.
TransportDG< Model >::EqFields EqFields
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
virtual void rhs_set_values(int nrow, int *rows, double *vals)=0
virtual void mat_set_values(int nrow, int *rows, int ncol, int *cols, double *vals)=0
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
static constexpr double almost_zero
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:135
vector< PetscScalar > local_mass_balance_vector_
Same as previous.
Definition: assembly_dg.hh:138
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:39
MassAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:45
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:132
FeQArray< Scalar > ref_scalar_
Definition: assembly_dg.hh:141
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
Definition: assembly_dg.hh:136
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:121
~MassAssemblyDG()
Destructor.
Definition: assembly_dg.hh:56
EqData * eq_data_
Definition: assembly_dg.hh:129
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:115
static constexpr const char * name()
Definition: assembly_dg.hh:42
FeQArray< Scalar > conc_shape_
Definition: assembly_dg.hh:142
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:59
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:134
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
Definition: assembly_dg.hh:73
FeQ< Scalar > JxW_
Definition: assembly_dg.hh:140
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:40
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:128
vector< PetscScalar > local_retardation_balance_vector_
Auxiliary vector for assemble mass matrix.
Definition: assembly_dg.hh:137
Base class for quadrature rules on simplices in arbitrary dimensions.
Definition: quadrature.hh:48
unsigned int size() const
Returns number of quadrature points.
Definition: quadrature.hh:86
Armor::Array< double >::ArrayMatSet set(uint i)
Definition: quadrature.hh:93
double weight(unsigned int i) const
Returns the ith weight.
Definition: quadrature.hh:103
IterConvert< ObjectIn, ObjectOut > begin()
Iterator to begin item of range.
Range helper class.
static LocalPoint node_coords(unsigned int nid)
Definition: ref_element.hh:634
unsigned int bulk_idx() const
Returns index of the region in the bulk set.
Definition: region.hh:90
double measure() const
Calculate metrics of the side.
Definition: accessors.cc:27
Boundary cond() const
ElementAccessor< 3 > element() const
Returns iterator to the element of the side.
double diameter() const
Calculate the side diameter.
Definition: accessors.cc:132
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:787
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:690
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:689
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
Definition: assembly_dg.hh:723
~SourcesAssemblyDG()
Destructor.
Definition: assembly_dg.hh:707
SourcesAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:695
vector< PetscScalar > local_source_balance_vector_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:788
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:770
static constexpr const char * name()
Definition: assembly_dg.hh:692
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:778
vector< PetscScalar > local_source_balance_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:789
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:710
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:782
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:784
FeQArray< Scalar > conc_shape_
Definition: assembly_dg.hh:793
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:786
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:764
FeQArray< Scalar > ref_scalar_
Definition: assembly_dg.hh:792
FeQ< Scalar > JxW_
Definition: assembly_dg.hh:791
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:231
FeQArray< Vector > conc_grad_sidw_
Definition: assembly_dg.hh:673
FeQArray< Scalar > ref_scalar_
Definition: assembly_dg.hh:666
void edge_integral(RangeConvert< DHEdgeSide, DHCellSide > edge_side_range)
Assembles the fluxes between sides of elements of the same dimension.
Definition: assembly_dg.hh:411
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:649
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:651
vector< vector< LongIdx > > side_dof_indices_
Vector of vectors of side DOF indices.
Definition: assembly_dg.hh:655
FeQArray< Vector > conc_grad_
Definition: assembly_dg.hh:672
StiffnessAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:236
FeQ< Scalar > JxW_
Definition: assembly_dg.hh:663
void boundary_side_integral(DHCellSide cell_side)
Assembles the fluxes on the boundary.
Definition: assembly_dg.hh:332
vector< double * > jumps
Auxiliary storage for jumps of shape functions.
Definition: assembly_dg.hh:661
vector< double * > waverages
Auxiliary storage for weighted averages of shape functions.
Definition: assembly_dg.hh:660
void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side)
Assembles the fluxes between elements of different dimensions.
Definition: assembly_dg.hh:579
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:269
vector< LongIdx > side_dof_indices_vb_
Vector of side DOF indices (assemble element-side fluxex)
Definition: assembly_dg.hh:656
FeQArray< Scalar > conc_shape_
Definition: assembly_dg.hh:670
FeQArray< Vector > ref_scalar_grad_
Definition: assembly_dg.hh:668
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assembles the cell (volume) integral into the stiffness matrix.
Definition: assembly_dg.hh:299
FeQArray< Vector > ref_scalar_grad_side_
Definition: assembly_dg.hh:669
FeQArray< Scalar > conc_shape_side_
Definition: assembly_dg.hh:671
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:230
vector< double * > averages
Auxiliary storage for averages of shape functions.
Definition: assembly_dg.hh:659
FeQArray< Scalar > ref_scalar_side_
Definition: assembly_dg.hh:667
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
Definition: assembly_dg.hh:657
~StiffnessAssemblyDG()
Destructor.
Definition: assembly_dg.hh:262
static constexpr const char * name()
Definition: assembly_dg.hh:233
ElQ< Vector > normal_
Definition: assembly_dg.hh:665
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:654
FeQ< Scalar > JxW_side_
Definition: assembly_dg.hh:664
FeQJoin< Scalar > conc_join_shape_
Definition: assembly_dg.hh:674
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:645
unsigned int qsize_lower_dim_
Size of quadrature of dim-1.
Definition: assembly_dg.hh:652
const TimeStep & step(int index=-1) const
unsigned int index() const
std::shared_ptr< DOFHandlerMultiDim > dh_
Object for distribution of dofs.
std::vector< VectorMPI > output_vec
Vector of solution data.
LinSys ** ls_dt
Linear algebra system for the time derivative (actually it is used only for handling the matrix struc...
int dg_variant
DG variant ((non-)symmetric/incomplete.
TimeGovernor * time_
std::shared_ptr< Balance > balance_
LinSys ** ls
Linear algebra system for the transport equation.
std::vector< Vec > ret_vec
Auxiliary vectors for calculation of sources in balance due to retardation (e.g. sorption).
unsigned int max_edg_sides
Maximal number of edge sides (evaluate from dim 1,2,3)
MultiField< 3, FieldValue< 3 >::Scalar > dg_penalty
Penalty enforcing inter-element continuity of solution (for each substance).
MultiField< 3, FieldValue< 3 >::Scalar > fracture_sigma
Transition parameter for diffusive transfer on fractures (for each substance).
Definitions of basic Lagrangean finite elements with polynomial shape functions.
@ coupling
@ boundary
@ bulk
@ edge
unsigned int uint
unsigned int IntDim
A dimension index type.
Definition: mixed.hh:19
Class FEValues calculates finite element data on the actual cells such as shape function values,...
double Scalar
Definitions of particular quadrature rules on simplices.
Discontinuous Galerkin method for equation of transport with dispersion.