Flow123d  DF_patch_fe_mechanics-5faa023
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"
26 #include "fem/op_factory.hh"
27 #include "fem/patch_op_impl.hh"
29 #include "coupling/balance.hh"
30 #include "fem/element_cache_map.hh"
31 
32 
33 
34 /**
35  * Auxiliary container class for Finite element and related objects of given dimension.
36  */
37 template <unsigned int dim, class Model>
38 class MassAssemblyDG : public AssemblyBasePatch<dim>
39 {
40 public:
43 
44  static constexpr const char * name() { return "MassAssemblyDG"; }
45 
46  /// Constructor.
47  MassAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
48  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
49  JxW_( this->bulk_values().JxW() ),
50  conc_shape_( this->bulk_values().scalar_shape() ) {
52  this->used_fields_ += eq_fields_->mass_matrix_coef;
53  this->used_fields_ += eq_fields_->retardation_coef;
54  }
55 
56  /// Destructor.
58 
59  /// Initialize auxiliary vectors and other data members
60  void initialize(ElementCacheMap *element_cache_map) {
61  this->element_cache_map_ = element_cache_map;
62 
63  this->fe_values_->template initialize<dim>(*this->quad_);
64  ndofs_ = this->n_dofs();
65  dof_indices_.resize(ndofs_);
66  local_matrix_.resize(4*ndofs_*ndofs_);
67  local_retardation_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(cell.dim(), dim).error("Dimension of element mismatch!");
77 
79 
80  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); ++sbi)
81  {
82  // assemble the local mass matrix
83  for (unsigned int i=0; i<ndofs_; i++)
84  {
85  for (unsigned int j=0; j<ndofs_; j++)
86  {
87  local_matrix_[i*ndofs_+j] = 0;
88  for (auto p : this->bulk_points(element_patch_idx) )
89  {
90  local_matrix_[i*ndofs_+j] += (eq_fields_->mass_matrix_coef(p)+eq_fields_->retardation_coef[sbi](p)) *
91  conc_shape_.shape(j)(p)*conc_shape_.shape(i)(p)*JxW_(p);
92  }
93  }
94  }
95 
96  for (unsigned int i=0; i<ndofs_; i++)
97  {
100  for (auto p : this->bulk_points(element_patch_idx) )
101  {
102  local_mass_balance_vector_[i] += eq_fields_->mass_matrix_coef(p)*conc_shape_.shape(i)(p)*JxW_(p);
103  local_retardation_balance_vector_[i] -= eq_fields_->retardation_coef[sbi](p)*conc_shape_.shape(i)(p)*JxW_(p);
104  }
105  }
106 
107  eq_data_->balance_->add_mass_values(eq_data_->subst_idx()[sbi], cell, cell.get_loc_dof_indices(),
109 
111  VecSetValues(eq_data_->ret_vec[sbi], ndofs_, &(dof_indices_[0]), &(local_retardation_balance_vector_[0]), ADD_VALUES);
112  }
113  }
114 
115  /// Implements @p AssemblyBase::begin.
116  void begin() override
117  {
118  eq_data_->balance_->start_mass_assembly( eq_data_->subst_idx() );
119  }
120 
121  /// Implements @p AssemblyBase::end.
122  void end() override
123  {
124  eq_data_->balance_->finish_mass_assembly( eq_data_->subst_idx() );
125  }
126 
127  private:
128  /// Data objects shared with TransportDG
131 
132  /// Sub field set contains fields used in calculation.
134 
135  unsigned int ndofs_; ///< Number of dofs
136  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
137  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
138  vector<PetscScalar> local_retardation_balance_vector_; ///< Auxiliary vector for assemble mass matrix.
140 
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  conc_shape_( this->bulk_values().scalar_shape() ),
242  conc_shape_side_( this->side_values().scalar_shape() ),
243  conc_grad_( this->bulk_values().grad_scalar_shape() ),
244  conc_grad_sidw_( this->side_values().grad_scalar_shape() ),
245  conc_join_shape_( FeQJoin<Scalar>( this->join_values().scalar_join_shape() ) ) {
247  this->used_fields_ += eq_fields_->advection_coef;
248  this->used_fields_ += eq_fields_->diffusion_coef;
249  this->used_fields_ += eq_fields_->cross_section;
251  this->used_fields_ += eq_fields_->sources_sigma_out;
253  this->used_fields_ += eq_fields_->bc_type;
254  this->used_fields_ += eq_fields_->bc_robin_sigma;
255  }
256 
257  /// Destructor.
259  for (auto a : averages) if (a != nullptr) delete[] a;
260  for (auto a : waverages) if (a != nullptr) delete[] a;
261  for (auto a : jumps) if (a != nullptr) delete[] a;
262  }
263 
264  /// Initialize auxiliary vectors and other data members
265  void initialize(ElementCacheMap *element_cache_map) {
266  this->element_cache_map_ = element_cache_map;
267 
268  this->fe_values_->template initialize<dim>(*this->quad_);
269  this->fe_values_->template initialize<dim>(*this->quad_low_);
270  ndofs_ = this->n_dofs();
271  qsize_lower_dim_ = this->quad_low_->size();
272  dof_indices_.resize(ndofs_);
273  side_dof_indices_vb_.resize(2*ndofs_);
274  local_matrix_.resize(4*ndofs_*ndofs_);
275 
276  for (unsigned int sid=0; sid<eq_data_->max_edg_sides; sid++)
277  {
279  }
280 
282  for (unsigned int s=0; s<eq_data_->max_edg_sides; s++)
283  averages[s] = new double[qsize_lower_dim_*ndofs_];
284  waverages.resize(2);
285  jumps.resize(2);
286  for (unsigned int s=0; s<2; s++)
287  {
288  waverages[s] = new double[qsize_lower_dim_*ndofs_];
289  jumps[s] = new double[qsize_lower_dim_*ndofs_];
290  }
291  }
292 
293 
294  /// Assembles the cell (volume) integral into the stiffness matrix.
295  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
296  {
297  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
298  if (!cell.is_own()) return;
299 
301 
302  // assemble the local stiffness matrix
303  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
304  {
305  for (unsigned int i=0; i<ndofs_; i++)
306  for (unsigned int j=0; j<ndofs_; j++)
307  local_matrix_[i*ndofs_+j] = 0;
308 
309  for (auto p : this->bulk_points(element_patch_idx) )
310  {
311  for (unsigned int i=0; i<ndofs_; i++)
312  {
313  arma::vec3 Kt_grad_i = eq_fields_->diffusion_coef[sbi](p).t()*conc_grad_.shape(i)(p);
314  double ad_dot_grad_i = arma::dot(eq_fields_->advection_coef[sbi](p), conc_grad_.shape(i)(p));
315 
316  for (unsigned int j=0; j<ndofs_; j++)
317  local_matrix_[i*ndofs_+j] += (arma::dot(Kt_grad_i, conc_grad_.shape(j)(p))
318  -conc_shape_.shape(j)(p)*ad_dot_grad_i
319  +eq_fields_->sources_sigma_out[sbi](p)*conc_shape_.shape(j)(p)*conc_shape_.shape(i)(p))*JxW_(p);
320  }
321  }
323  }
324  }
325 
326 
327  /// Assembles the fluxes on the boundary.
328  inline void boundary_side_integral(DHCellSide cell_side)
329  {
330  ASSERT_EQ(cell_side.dim(), dim).error("Dimension of element mismatch!");
331  if (!cell_side.cell().is_own()) return;
332 
333  Side side = cell_side.side();
334  const DHCellAccessor &cell = cell_side.cell();
335 
337  unsigned int k;
338  double gamma_l;
339 
340  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
341  {
342  std::fill(local_matrix_.begin(), local_matrix_.end(), 0);
343 
344  double side_flux = advective_flux(eq_fields_->advection_coef[sbi], this->boundary_points(cell_side), JxW_side_, normal_);
345  double transport_flux = side_flux/side.measure();
346 
347  // On Neumann boundaries we have only term from integrating by parts the advective term,
348  // on Dirichlet boundaries we additionally apply the penalty which enforces the prescribed value.
349  auto p_side = *( this->boundary_points(cell_side).begin() );
350  auto p_bdr = p_side.point_bdr( side.cond().element_accessor() );
351  unsigned int bc_type = eq_fields_->bc_type[sbi](p_bdr);
353  {
354  // set up the parameters for DG method
355  auto p = *( this->boundary_points(cell_side).begin() );
356  gamma_l = DG_penalty_boundary(side,
357  diffusion_delta(eq_fields_->diffusion_coef[sbi], this->boundary_points(cell_side), normal_(p)),
358  transport_flux,
359  eq_fields_->dg_penalty[sbi](p_side));
360  transport_flux += gamma_l;
361  }
362 
363  // fluxes and penalty
364  k=0;
365  for (auto p : this->boundary_points(cell_side) )
366  {
367  double flux_times_JxW;
369  {
370  //sigma_ corresponds to robin_sigma
371  auto p_bdr = p.point_bdr(side.cond().element_accessor());
372  flux_times_JxW = eq_fields_->cross_section(p)*eq_fields_->bc_robin_sigma[sbi](p_bdr)*JxW_side_(p);
373  }
375  {
376  auto p_bdr = p.point_bdr(side.cond().element_accessor());
377  flux_times_JxW = (transport_flux + eq_fields_->cross_section(p)*eq_fields_->bc_robin_sigma[sbi](p_bdr))*JxW_side_(p);
378  }
379  else if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux < 0)
380  flux_times_JxW = 0;
381  else
382  flux_times_JxW = transport_flux*JxW_side_(p);
383 
384  for (unsigned int i=0; i<ndofs_; i++)
385  {
386  for (unsigned int j=0; j<ndofs_; j++)
387  {
388  // flux due to advection and penalty
389  local_matrix_[i*ndofs_+j] += flux_times_JxW*conc_shape_side_.shape(i)(p)*conc_shape_side_.shape(j)(p);
390 
391  // flux due to diffusion (only on dirichlet and inflow boundary)
393  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)
394  + 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
395  )*JxW_side_(p);
396  }
397  }
398  k++;
399  }
400 
402  }
403  }
404 
405 
406  /// Assembles the fluxes between sides of elements of the same dimension.
408  ASSERT_EQ(edge_side_range.begin()->element().dim(), dim).error("Dimension of element mismatch!");
409 
410  unsigned int k;
411  double gamma_l, omega[2], transport_flux, delta[2], delta_sum;
412  double aniso1, aniso2;
413  double local_alpha=0.0;
414  int sid=0, s1, s2;
415  for( DHCellSide edge_side : edge_side_range )
416  {
417  auto dh_edge_cell = eq_data_->dh_->cell_accessor_from_element( edge_side.elem_idx() );
418  dh_edge_cell.get_dof_indices(side_dof_indices_[sid]);
419  ++sid;
420  }
421  auto zero_edge_side = *edge_side_range.begin();
422  auto p = *( this->edge_points(zero_edge_side).begin() );
423  arma::vec3 normal_vector = normal_(p);
424 
425  // fluxes and penalty
426  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
427  {
428  vector<double> fluxes(edge_side_range.begin()->n_edge_sides());
429  double pflux = 0, nflux = 0; // calculate the total in- and out-flux through the edge
430  sid=0;
431  for( DHCellSide edge_side : edge_side_range )
432  {
433  fluxes[sid] = advective_flux(eq_fields_->advection_coef[sbi], this->edge_points(edge_side), JxW_side_, normal_) / edge_side.measure();
434  if (fluxes[sid] > 0)
435  pflux += fluxes[sid];
436  else
437  nflux += fluxes[sid];
438  ++sid;
439  }
440 
441  // precompute averages of shape functions over pairs of sides
442  s1=0;
443  for (DHCellSide edge_side : edge_side_range)
444  {
445  k=0;
446  for (auto p : this->edge_points(edge_side) )
447  {
448  for (unsigned int i=0; i<ndofs_; i++)
449  averages[s1][k*ndofs_+i] = conc_shape_side_.shape(i)(p)*0.5;
450  k++;
451  }
452  s1++;
453  }
454 
455 
456 
457  s1=0;
458  for( DHCellSide edge_side1 : edge_side_range )
459  {
460  s2=-1; // need increment at begin of loop (see conditionally 'continue' directions)
461  for( DHCellSide edge_side2 : edge_side_range )
462  {
463  s2++;
464  if (s2<=s1) continue;
465  ASSERT(edge_side1.is_valid()).error("Invalid side of edge.");
466 
467  auto p = *( this->edge_points(edge_side1).begin() );
468  arma::vec3 nv = normal_(p);
469 
470  // set up the parameters for DG method
471  // calculate the flux from edge_side1 to edge_side2
472  if (fluxes[s2] > 0 && fluxes[s1] < 0)
473  transport_flux = fluxes[s1]*fabs(fluxes[s2]/pflux);
474  else if (fluxes[s2] < 0 && fluxes[s1] > 0)
475  transport_flux = fluxes[s1]*fabs(fluxes[s2]/nflux);
476  else
477  transport_flux = 0;
478 
479  gamma_l = 0.5*fabs(transport_flux);
480 
481  delta[0] = 0;
482  delta[1] = 0;
483  for (auto p1 : this->edge_points(edge_side1) )
484  {
485  auto p2 = p1.point_on(edge_side2);
486  delta[0] += dot(eq_fields_->diffusion_coef[sbi](p1)*normal_vector,normal_vector);
487  delta[1] += dot(eq_fields_->diffusion_coef[sbi](p2)*normal_vector,normal_vector);
488  local_alpha = max(eq_fields_->dg_penalty[sbi](p1), eq_fields_->dg_penalty[sbi](p2));
489  }
490  delta[0] /= qsize_lower_dim_;
491  delta[1] /= qsize_lower_dim_;
492 
493  delta_sum = delta[0] + delta[1];
494 
495 // if (delta_sum > numeric_limits<double>::epsilon())
496  if (fabs(delta_sum) > 0)
497  {
498  omega[0] = delta[1]/delta_sum;
499  omega[1] = delta[0]/delta_sum;
500  double h = edge_side1.diameter();
501  aniso1 = elem_anisotropy(edge_side1.element());
502  aniso2 = elem_anisotropy(edge_side2.element());
503  gamma_l += local_alpha/h*aniso1*aniso2*(delta[0]*delta[1]/delta_sum);
504  }
505  else
506  for (int i=0; i<2; i++) omega[i] = 0;
507  // end of set up the parameters for DG method
508 
509  int sd[2]; bool is_side_own[2];
510  sd[0] = s1; is_side_own[0] = edge_side1.cell().is_own();
511  sd[1] = s2; is_side_own[1] = edge_side2.cell().is_own();
512 
513  // precompute jumps and weighted averages of shape functions over the pair of sides (s1,s2)
514  k=0;
515  for (auto p1 : this->edge_points(edge_side1) )
516  {
517  auto p2 = p1.point_on(edge_side2);
518  for (unsigned int i=0; i<ndofs_; i++)
519  {
520  jumps[0][k*ndofs_+i] = conc_shape_side_.shape(i)(p1);
521  jumps[1][k*ndofs_+i] = - conc_shape_side_.shape(i)(p2);
522  waverages[0][k*ndofs_+i] = arma::dot(eq_fields_->diffusion_coef[sbi](p1)*conc_grad_sidw_.shape(i)(p1),nv)*omega[0];
523  waverages[1][k*ndofs_+i] = arma::dot(eq_fields_->diffusion_coef[sbi](p2)*conc_grad_sidw_.shape(i)(p2),nv)*omega[1];
524  }
525  k++;
526  }
527 
528  // For selected pair of elements:
529  for (int n=0; n<2; n++)
530  {
531  if (!is_side_own[n]) continue;
532 
533  for (int m=0; m<2; m++)
534  {
535  for (unsigned int i=0; i<ndofs_; i++)
536  for (unsigned int j=0; j<ndofs_; j++)
537  local_matrix_[i*ndofs_+j] = 0;
538 
539  k=0;
540  for (auto p1 : this->edge_points(zero_edge_side) )
541  //for (k=0; k<this->quad_low_->size(); ++k)
542  {
543  for (unsigned int i=0; i<ndofs_; i++)
544  {
545  for (unsigned int j=0; j<ndofs_; j++)
546  {
547  int index = i*ndofs_+j;
548 
549  local_matrix_[index] += (
550  // flux due to transport (applied on interior edges) (average times jump)
551  transport_flux*jumps[n][k*ndofs_+i]*averages[sd[m]][k*ndofs_+j]
552 
553  // penalty enforcing continuity across edges (applied on interior and Dirichlet edges) (jump times jump)
554  + gamma_l*jumps[n][k*ndofs_+i]*jumps[m][k*ndofs_+j]
555 
556  // terms due to diffusion
557  - jumps[n][k*ndofs_+i]*waverages[m][k*ndofs_+j]
558  - eq_data_->dg_variant*waverages[n][k*ndofs_+i]*jumps[m][k*ndofs_+j]
560  }
561  }
562  k++;
563  }
564  eq_data_->ls[sbi]->mat_set_values(ndofs_, &(side_dof_indices_[sd[n]][0]), ndofs_, &(side_dof_indices_[sd[m]][0]), &(local_matrix_[0]));
565  }
566  }
567  }
568  s1++;
569  }
570  }
571  }
572 
573 
574  /// Assembles the fluxes between elements of different dimensions.
575  inline void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side) {
576  if (dim == 1) return;
577  ASSERT_EQ(cell_lower_dim.dim(), dim-1).error("Dimension of element mismatch!");
578 
579  // Note: use data members csection_ and velocity_ for appropriate quantities of lower dim element
580 
581  unsigned int n_dofs[2];
582  unsigned int n_indices = cell_lower_dim.get_dof_indices(dof_indices_);
583  for(unsigned int i=0; i<n_indices; ++i) {
585  }
587 
588  DHCellAccessor cell_higher_dim = eq_data_->dh_->cell_accessor_from_element( neighb_side.element().idx() );
589  n_indices = cell_higher_dim.get_dof_indices(dof_indices_);
590  for(unsigned int i=0; i<n_indices; ++i) {
592  }
594 
595  // Testing element if they belong to local partition.
596  bool own_element_id[2];
597  own_element_id[0] = cell_lower_dim.is_own();
598  own_element_id[1] = cell_higher_dim.is_own();
599 
600  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++) // Optimize: SWAP LOOPS
601  {
602  for (unsigned int i=0; i<n_dofs[0]+n_dofs[1]; i++)
603  for (unsigned int j=0; j<n_dofs[0]+n_dofs[1]; j++)
604  local_matrix_[i*(n_dofs[0]+n_dofs[1])+j] = 0;
605 
606  // set transmission conditions
607  for (auto p_high : this->coupling_points(neighb_side) )
608  {
609  auto p_low = p_high.lower_dim(cell_lower_dim);
610  // The communication flux has two parts:
611  // - "diffusive" term containing sigma
612  // - "advective" term representing usual upwind
613  //
614  // The calculation differs from the reference manual, since ad_coef and dif_coef have different meaning
615  // than b and A in the manual.
616  // In calculation of sigma there appears one more csection_lower in the denominator.
617  double sigma = eq_fields_->fracture_sigma[sbi](p_low)*arma::dot(eq_fields_->diffusion_coef[sbi](p_low)*normal_(p_high),normal_(p_high))*
618  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));
619 
620  double transport_flux = arma::dot(eq_fields_->advection_coef[sbi](p_high), normal_(p_high));
621 
622  for (uint i=0; i<conc_join_shape_.n_dofs_both(); ++i) {
623  uint is_high_i = conc_join_shape_.is_high_dim(i);
624  if (!own_element_id[is_high_i]) continue;
625  double diff_shape_i = conc_join_shape_.shape(i)(p_high) - conc_join_shape_.shape(i)(p_low);
626  for (uint j=0; j<conc_join_shape_.n_dofs_both(); ++j) {
627  local_matrix_[i * (n_dofs[0]+n_dofs[1]) + j] += (
628  sigma * diff_shape_i * (conc_join_shape_.shape(j)(p_high) - conc_join_shape_.shape(j)(p_low))
629  + 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))
631  }
632  }
633  }
635  }
636  }
637 
638 
639 private:
640  /// Data objects shared with TransportDG
643 
644  /// Sub field set contains fields used in calculation.
646 
647  unsigned int ndofs_; ///< Number of dofs
648  unsigned int qsize_lower_dim_; ///< Size of quadrature of dim-1
649 
650  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
651  vector< vector<LongIdx> > side_dof_indices_; ///< Vector of vectors of side DOF indices
652  vector<LongIdx> side_dof_indices_vb_; ///< Vector of side DOF indices (assemble element-side fluxex)
653  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
654 
655  vector<double*> averages; ///< Auxiliary storage for averages of shape functions.
656  vector<double*> waverages; ///< Auxiliary storage for weighted averages of shape functions.
657  vector<double*> jumps; ///< Auxiliary storage for jumps of shape functions.
658 
667 
668  template < template<IntDim...> class DimAssembly>
669  friend class GenericAssembly;
670 
671 };
672 
673 
674 /**
675  * Auxiliary container class for Finite element and related objects of given dimension.
676  */
677 template <unsigned int dim, class Model>
679 {
680 public:
683 
684  static constexpr const char * name() { return "SourcesAssemblyDG"; }
685 
686  /// Constructor.
687  SourcesAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
688  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
689  JxW_( this->bulk_values().JxW() ),
690  conc_shape_( this->bulk_values().scalar_shape() ) {
692  this->used_fields_ += eq_fields_->sources_density_out;
693  this->used_fields_ += eq_fields_->sources_conc_out;
694  this->used_fields_ += eq_fields_->sources_sigma_out;
695  }
696 
697  /// Destructor.
699 
700  /// Initialize auxiliary vectors and other data members
701  void initialize(ElementCacheMap *element_cache_map) {
702  this->element_cache_map_ = element_cache_map;
703 
704  this->fe_values_->template initialize<dim>(*this->quad_);
705  ndofs_ = this->n_dofs();
706  dof_indices_.resize(ndofs_);
707  local_rhs_.resize(ndofs_);
710  }
711 
712 
713  /// Assemble integral over element
714  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
715  {
716  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
717 
718  ElementAccessor<3> elm = cell.elm();
719  double source;
720 
722 
723  // assemble the local stiffness matrix
724  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
725  {
726  fill_n( &(local_rhs_[0]), ndofs_, 0 );
729 
730  for (auto p : this->bulk_points(element_patch_idx) )
731  {
732  source = (eq_fields_->sources_density_out[sbi](p) + eq_fields_->sources_conc_out[sbi](p)*eq_fields_->sources_sigma_out[sbi](p))*JxW_(p);
733 
734  for (unsigned int i=0; i<ndofs_; i++)
735  local_rhs_[i] += source*conc_shape_.shape(i)(p);
736  }
737  eq_data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
738 
739  for (unsigned int i=0; i<ndofs_; i++)
740  {
741  for (auto p : this->bulk_points(element_patch_idx) )
742  {
743  local_source_balance_vector_[i] -= eq_fields_->sources_sigma_out[sbi](p)*conc_shape_.shape(i)(p)*JxW_(p);
744  }
745 
747  }
748  eq_data_->balance_->add_source_values(eq_data_->subst_idx()[sbi], elm.region().bulk_idx(),
749  cell.get_loc_dof_indices(),
751  }
752  }
753 
754  /// Implements @p AssemblyBase::begin.
755  void begin() override
756  {
757  eq_data_->balance_->start_source_assembly( eq_data_->subst_idx() );
758  }
759 
760  /// Implements @p AssemblyBase::end.
761  void end() override
762  {
763  eq_data_->balance_->finish_source_assembly( eq_data_->subst_idx() );
764  }
765 
766 
767  private:
768  /// Data objects shared with TransportDG
771 
772  /// Sub field set contains fields used in calculation.
774 
775  unsigned int ndofs_; ///< Number of dofs
776 
777  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
778  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
779  vector<PetscScalar> local_source_balance_vector_; ///< Auxiliary vector for set_sources method.
780  vector<PetscScalar> local_source_balance_rhs_; ///< Auxiliary vector for set_sources method.
781 
784 
785  template < template<IntDim...> class DimAssembly>
786  friend class GenericAssembly;
787 
788 };
789 
790 
791 /**
792  * Assembles the r.h.s. components corresponding to the Dirichlet boundary conditions..
793  */
794 template <unsigned int dim, class Model>
796 {
797 public:
800 
801  static constexpr const char * name() { return "BdrConditionAssemblyDG"; }
802 
803  /// Constructor.
804  BdrConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
805  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
806  JxW_( this->side_values().JxW() ),
807  normal_( this->side_values().normal_vector() ),
808  conc_shape_( this->side_values().scalar_shape() ),
809  conc_grad_( this->side_values().grad_scalar_shape() ) {
811  this->used_fields_ += eq_fields_->advection_coef;
812  this->used_fields_ += eq_fields_->diffusion_coef;
813  this->used_fields_ += eq_fields_->cross_section;
814  this->used_fields_ += eq_fields_->bc_type;
815  this->used_fields_ += eq_fields_->bc_dirichlet_value;
816  this->used_fields_ += eq_fields_->bc_robin_sigma;
817  this->used_fields_ += eq_fields_->bc_flux;
818  }
819 
820  /// Destructor.
822 
823  /// Initialize auxiliary vectors and other data members
824  void initialize(ElementCacheMap *element_cache_map) {
825  this->element_cache_map_ = element_cache_map;
826 
827  this->fe_values_->template initialize<dim>(*this->quad_low_);
828  ndofs_ = this->n_dofs();
829  dof_indices_.resize(ndofs_);
830  local_rhs_.resize(ndofs_);
832  }
833 
834 
835  /// Implements @p AssemblyBase::boundary_side_integral.
836  inline void boundary_side_integral(DHCellSide cell_side)
837  {
838 
839  ElementAccessor<3> bc_elm = cell_side.cond().element_accessor();
840 
841  const DHCellAccessor &cell = cell_side.cell();
843 
844  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
845  {
846  fill_n(&(local_rhs_[0]), ndofs_, 0);
849 
850  double side_flux = advective_flux(eq_fields_->advection_coef[sbi], this->boundary_points(cell_side), JxW_, normal_);
851  double transport_flux = side_flux/cell_side.measure();
852 
853  auto p_side = *( this->boundary_points(cell_side)).begin();
854  auto p_bdr = p_side.point_bdr(cell_side.cond().element_accessor() );
855  unsigned int bc_type = eq_fields_->bc_type[sbi](p_bdr);
856  if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux < 0)
857  {
858  for (auto p : this->boundary_points(cell_side) )
859  {
860  auto p_bdr = p.point_bdr(bc_elm);
861  double bc_term = -transport_flux*eq_fields_->bc_dirichlet_value[sbi](p_bdr)*JxW_(p);
862  for (unsigned int i=0; i<ndofs_; i++)
863  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p);
864  }
865  for (unsigned int i=0; i<ndofs_; i++)
867  }
868  else if (bc_type == AdvectionDiffusionModel::abc_dirichlet)
869  {
870  double side_flux = advective_flux(eq_fields_->advection_coef[sbi], this->boundary_points(cell_side), JxW_, normal_);
871  double transport_flux = side_flux/cell_side.measure();
872 
873  auto p = *( this->boundary_points(cell_side).begin() );
874  double gamma_l = DG_penalty_boundary(cell_side.side(),
875  diffusion_delta(eq_fields_->diffusion_coef[sbi], this->boundary_points(cell_side), normal_(p)),
876  transport_flux,
877  eq_fields_->dg_penalty[sbi](p_bdr));
878 
879  for (auto p : this->boundary_points(cell_side) )
880  {
881  auto p_bdr = p.point_bdr(bc_elm);
882  double bc_term = gamma_l*eq_fields_->bc_dirichlet_value[sbi](p_bdr)*JxW_(p);
883  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));
884  for (unsigned int i=0; i<ndofs_; i++)
885  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p)
886  + arma::dot(bc_grad,conc_grad_.shape(i)(p));
887  }
888  for (auto p : this->boundary_points(cell_side) )
889  {
890  for (unsigned int i=0; i<ndofs_; i++)
891  {
892  local_flux_balance_vector_[i] += (arma::dot(eq_fields_->advection_coef[sbi](p), normal_(p))*conc_shape_.shape(i)(p)
893  - arma::dot(eq_fields_->diffusion_coef[sbi](p)*conc_grad_.shape(i)(p),normal_(p))
894  + gamma_l*conc_shape_.shape(i)(p))*JxW_(p);
895  }
896  }
897  if (eq_data_->time_->step().index() > 0)
898  for (unsigned int i=0; i<ndofs_; i++)
900  }
901  else if (bc_type == AdvectionDiffusionModel::abc_total_flux)
902  {
903  for (auto p : this->boundary_points(cell_side) )
904  {
905  auto p_bdr = p.point_bdr(bc_elm);
906  double bc_term = eq_fields_->cross_section(p) * (eq_fields_->bc_robin_sigma[sbi](p_bdr)*eq_fields_->bc_dirichlet_value[sbi](p_bdr) +
907  eq_fields_->bc_flux[sbi](p_bdr)) * JxW_(p);
908  for (unsigned int i=0; i<ndofs_; i++)
909  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p);
910  }
911 
912  for (unsigned int i=0; i<ndofs_; i++)
913  {
914  for (auto p : this->boundary_points(cell_side) ) {
915  auto p_bdr = p.point_bdr(bc_elm);
916  local_flux_balance_vector_[i] += eq_fields_->cross_section(p) * eq_fields_->bc_robin_sigma[sbi](p_bdr) *
917  JxW_(p) * conc_shape_.shape(i)(p);
918  }
920  }
921  }
923  {
924  for (auto p : this->boundary_points(cell_side) )
925  {
926  auto p_bdr = p.point_bdr(bc_elm);
927  double bc_term = eq_fields_->cross_section(p) * (eq_fields_->bc_robin_sigma[sbi](p_bdr)*eq_fields_->bc_dirichlet_value[sbi](p_bdr) +
928  eq_fields_->bc_flux[sbi](p_bdr)) * JxW_(p);
929  for (unsigned int i=0; i<ndofs_; i++)
930  local_rhs_[i] += bc_term*conc_shape_.shape(i)(p);
931  }
932 
933  for (unsigned int i=0; i<ndofs_; i++)
934  {
935  for (auto p : this->boundary_points(cell_side) ) {
936  auto p_bdr = p.point_bdr(bc_elm);
937  local_flux_balance_vector_[i] += eq_fields_->cross_section(p)*(arma::dot(eq_fields_->advection_coef[sbi](p), normal_(p)) +
938  eq_fields_->bc_robin_sigma[sbi](p_bdr))*JxW_(p)*conc_shape_.shape(i)(p);
939  }
941  }
942  }
943  else if (bc_type == AdvectionDiffusionModel::abc_inflow && side_flux >= 0)
944  {
945  for (auto p : this->boundary_points(cell_side) )
946  {
947  for (unsigned int i=0; i<ndofs_; i++)
948  local_flux_balance_vector_[i] += arma::dot(eq_fields_->advection_coef[sbi](p), normal_(p))*JxW_(p)*conc_shape_.shape(i)(p);
949  }
950  }
951  eq_data_->ls[sbi]->rhs_set_values(ndofs_, &(dof_indices_[0]), &(local_rhs_[0]));
952 
953  eq_data_->balance_->add_flux_values(eq_data_->subst_idx()[sbi], cell_side,
954  cell.get_loc_dof_indices(),
956  }
957  }
958 
959  /// Implements @p AssemblyBase::begin.
960  void begin() override
961  {
962  eq_data_->balance_->start_flux_assembly( eq_data_->subst_idx() );
963  }
964 
965  /// Implements @p AssemblyBase::end.
966  void end() override
967  {
968  eq_data_->balance_->finish_flux_assembly( eq_data_->subst_idx() );
969  }
970 
971 
972  private:
973  /// Data objects shared with TransportDG
976 
977  unsigned int ndofs_; ///< Number of dofs
978 
979  /// Sub field set contains fields used in calculation.
981 
982  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
983  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
984  vector<PetscScalar> local_flux_balance_vector_; ///< Auxiliary vector for set_boundary_conditions method.
985  PetscScalar local_flux_balance_rhs_; ///< Auxiliary variable for set_boundary_conditions method.
986 
991 
992  template < template<IntDim...> class DimAssembly>
993  friend class GenericAssembly;
994 
995 };
996 
997 
998 /**
999  * Auxiliary container class sets the initial condition.
1000  */
1001 template <unsigned int dim, class Model>
1003 {
1004 public:
1007 
1008  static constexpr const char * name() { return "InitProjectionAssemblyDG"; }
1009 
1010  /// Constructor.
1011  InitProjectionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues<3> *fe_values)
1012  : AssemblyBasePatch<dim>(fe_values), eq_fields_(eq_fields), eq_data_(eq_data),
1013  JxW_( this->bulk_values().JxW() ),
1014  init_shape_( this->bulk_values().scalar_shape() ) {
1016  this->used_fields_ += eq_fields_->init_condition;
1017  }
1018 
1019  /// Destructor.
1021 
1022  /// Initialize auxiliary vectors and other data members
1023  void initialize(ElementCacheMap *element_cache_map) {
1024  this->element_cache_map_ = element_cache_map;
1025 
1026  this->fe_values_->template initialize<dim>(*this->quad_);
1027  ndofs_ = this->n_dofs();
1028  dof_indices_.resize(ndofs_);
1029  local_matrix_.resize(4*ndofs_*ndofs_);
1030  local_rhs_.resize(ndofs_);
1031  }
1032 
1033 
1034  /// Assemble integral over element
1035  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
1036  {
1037  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
1038 
1040 
1041  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
1042  {
1043  for (unsigned int i=0; i<ndofs_; i++)
1044  {
1045  local_rhs_[i] = 0;
1046  for (unsigned int j=0; j<ndofs_; j++)
1047  local_matrix_[i*ndofs_+j] = 0;
1048  }
1049 
1050  for (auto p : this->bulk_points(element_patch_idx) )
1051  {
1052  double rhs_term = eq_fields_->init_condition[sbi](p)*JxW_(p);
1053 
1054  for (unsigned int i=0; i<ndofs_; i++)
1055  {
1056  for (unsigned int j=0; j<ndofs_; j++)
1057  local_matrix_[i*ndofs_+j] += init_shape_.shape(i)(p)*init_shape_.shape(j)(p)*JxW_(p);
1058 
1059  local_rhs_[i] += init_shape_.shape(i)(p)*rhs_term;
1060  }
1061  }
1062  eq_data_->ls[sbi]->set_values(ndofs_, &(dof_indices_[0]), ndofs_, &(dof_indices_[0]), &(local_matrix_[0]), &(local_rhs_[0]));
1063  }
1064  }
1065 
1066 
1067  private:
1068  /// Data objects shared with TransportDG
1071 
1072  /// Sub field set contains fields used in calculation.
1074 
1075  unsigned int ndofs_; ///< Number of dofs
1076  vector<LongIdx> dof_indices_; ///< Vector of global DOF indices
1077  vector<PetscScalar> local_matrix_; ///< Auxiliary vector for assemble methods
1078  vector<PetscScalar> local_rhs_; ///< Auxiliary vector for set_sources method.
1079 
1082 
1083  template < template<IntDim...> class DimAssembly>
1084  friend class GenericAssembly;
1085 
1086 };
1087 
1088 
1089 /**
1090  * Auxiliary container class sets the initial condition.
1091  */
1092 template <unsigned int dim, class Model>
1094 {
1095 public:
1098 
1099  static constexpr const char * name() { return "InitConditionAssemblyDG"; }
1100 
1101  /// Constructor.
1103  : AssemblyBase<dim>(), eq_fields_(eq_fields), eq_data_(eq_data) {
1105  this->used_fields_ += eq_fields_->init_condition;
1106 
1107  this->quad_ = new Quadrature(dim, RefElement<dim>::n_nodes);
1108  for(unsigned int i = 0; i<RefElement<dim>::n_nodes; i++)
1109  {
1110  this->quad_->weight(i) = 1.0;
1111  this->quad_->set(i) = RefElement<dim>::node_coords(i);
1112  }
1113  }
1114 
1115  /// Destructor.
1117 
1118  /// Initialize auxiliary vectors and other data members
1119  void initialize(ElementCacheMap *element_cache_map) {
1120  this->element_cache_map_ = element_cache_map;
1121  }
1122 
1123 
1124  /// Assemble integral over element
1125  inline void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
1126  {
1127  ASSERT_EQ(cell.dim(), dim).error("Dimension of element mismatch!");
1128 
1129  unsigned int k;
1130 
1131  for (unsigned int sbi=0; sbi<eq_data_->n_substances(); sbi++)
1132  {
1133  k=0;
1134  for (auto p : this->bulk_points(element_patch_idx) )
1135  {
1136  double val = eq_fields_->init_condition[sbi](p);
1137 
1138  eq_data_->output_vec[sbi].set(cell.get_loc_dof_indices()[k], val);
1139  k++;
1140  }
1141  }
1142  }
1143 
1144 
1145  private:
1146  /// Data objects shared with TransportDG
1149 
1150  /// Sub field set contains fields used in calculation.
1152 
1153  template < template<IntDim...> class DimAssembly>
1154  friend class GenericAssembly;
1155 
1156 };
1157 
1158 #endif /* ASSEMBLY_DG_HH_ */
1159 
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:801
ElQ< Vector > normal_
Definition: assembly_dg.hh:988
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:980
vector< PetscScalar > local_flux_balance_vector_
Auxiliary vector for set_boundary_conditions method.
Definition: assembly_dg.hh:984
void boundary_side_integral(DHCellSide cell_side)
Implements AssemblyBase::boundary_side_integral.
Definition: assembly_dg.hh:836
BdrConditionAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:804
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:799
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:798
FeQArray< Scalar > conc_shape_
Definition: assembly_dg.hh:989
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:960
~BdrConditionAssemblyDG()
Destructor.
Definition: assembly_dg.hh:821
PetscScalar local_flux_balance_rhs_
Auxiliary variable for set_boundary_conditions method.
Definition: assembly_dg.hh:985
FeQArray< Vector > conc_grad_
Definition: assembly_dg.hh:990
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:824
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:982
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:974
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:966
vector< PetscScalar > local_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:983
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:977
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
Definition: op_accessors.hh:95
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_
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:136
vector< PetscScalar > local_mass_balance_vector_
Same as previous.
Definition: assembly_dg.hh:139
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:41
MassAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:47
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:133
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
Definition: assembly_dg.hh:137
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:122
~MassAssemblyDG()
Destructor.
Definition: assembly_dg.hh:57
EqData * eq_data_
Definition: assembly_dg.hh:130
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:116
static constexpr const char * name()
Definition: assembly_dg.hh:44
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:60
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:135
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
Definition: assembly_dg.hh:74
FeQ< Scalar > JxW_
Definition: assembly_dg.hh:141
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:42
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:129
vector< PetscScalar > local_retardation_balance_vector_
Auxiliary vector for assemble mass matrix.
Definition: assembly_dg.hh:138
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:778
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:682
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:681
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assemble integral over element.
Definition: assembly_dg.hh:714
~SourcesAssemblyDG()
Destructor.
Definition: assembly_dg.hh:698
SourcesAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:687
vector< PetscScalar > local_source_balance_vector_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:779
void end() override
Implements AssemblyBase::end.
Definition: assembly_dg.hh:761
static constexpr const char * name()
Definition: assembly_dg.hh:684
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:769
vector< PetscScalar > local_source_balance_rhs_
Auxiliary vector for set_sources method.
Definition: assembly_dg.hh:780
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:701
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:773
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:775
FeQArray< Scalar > conc_shape_
Definition: assembly_dg.hh:783
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:777
void begin() override
Implements AssemblyBase::begin.
Definition: assembly_dg.hh:755
FeQ< Scalar > JxW_
Definition: assembly_dg.hh:782
TransportDG< Model >::EqData EqData
Definition: assembly_dg.hh:231
FeQArray< Vector > conc_grad_sidw_
Definition: assembly_dg.hh:665
void edge_integral(RangeConvert< DHEdgeSide, DHCellSide > edge_side_range)
Assembles the fluxes between sides of elements of the same dimension.
Definition: assembly_dg.hh:407
FieldSet used_fields_
Sub field set contains fields used in calculation.
Definition: assembly_dg.hh:645
unsigned int ndofs_
Number of dofs.
Definition: assembly_dg.hh:647
vector< vector< LongIdx > > side_dof_indices_
Vector of vectors of side DOF indices.
Definition: assembly_dg.hh:651
FeQArray< Vector > conc_grad_
Definition: assembly_dg.hh:664
StiffnessAssemblyDG(EqFields *eq_fields, EqData *eq_data, PatchFEValues< 3 > *fe_values)
Constructor.
Definition: assembly_dg.hh:236
FeQ< Scalar > JxW_
Definition: assembly_dg.hh:659
void boundary_side_integral(DHCellSide cell_side)
Assembles the fluxes on the boundary.
Definition: assembly_dg.hh:328
vector< double * > jumps
Auxiliary storage for jumps of shape functions.
Definition: assembly_dg.hh:657
vector< double * > waverages
Auxiliary storage for weighted averages of shape functions.
Definition: assembly_dg.hh:656
void dimjoin_intergral(DHCellAccessor cell_lower_dim, DHCellSide neighb_side)
Assembles the fluxes between elements of different dimensions.
Definition: assembly_dg.hh:575
void initialize(ElementCacheMap *element_cache_map)
Initialize auxiliary vectors and other data members.
Definition: assembly_dg.hh:265
vector< LongIdx > side_dof_indices_vb_
Vector of side DOF indices (assemble element-side fluxex)
Definition: assembly_dg.hh:652
FeQArray< Scalar > conc_shape_
Definition: assembly_dg.hh:662
void cell_integral(DHCellAccessor cell, unsigned int element_patch_idx)
Assembles the cell (volume) integral into the stiffness matrix.
Definition: assembly_dg.hh:295
FeQArray< Scalar > conc_shape_side_
Definition: assembly_dg.hh:663
TransportDG< Model >::EqFields EqFields
Definition: assembly_dg.hh:230
vector< double * > averages
Auxiliary storage for averages of shape functions.
Definition: assembly_dg.hh:655
vector< PetscScalar > local_matrix_
Auxiliary vector for assemble methods.
Definition: assembly_dg.hh:653
~StiffnessAssemblyDG()
Destructor.
Definition: assembly_dg.hh:258
static constexpr const char * name()
Definition: assembly_dg.hh:233
ElQ< Vector > normal_
Definition: assembly_dg.hh:661
vector< LongIdx > dof_indices_
Vector of global DOF indices.
Definition: assembly_dg.hh:650
FeQ< Scalar > JxW_side_
Definition: assembly_dg.hh:660
FeQJoin< Scalar > conc_join_shape_
Definition: assembly_dg.hh:666
EqFields * eq_fields_
Data objects shared with TransportDG.
Definition: assembly_dg.hh:641
unsigned int qsize_lower_dim_
Size of quadrature of dim-1.
Definition: assembly_dg.hh:648
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
double Scalar
Definition: op_accessors.hh:25
Declares top level factory classes of FE operations.
Class FEValues calculates finite element data on the actual cells such as shape function values,...
Store finite element reinit functions.
Definitions of particular quadrature rules on simplices.
Discontinuous Galerkin method for equation of transport with dispersion.