Flow123d  release_2.2.0-23-g01927c6
darcy_flow_assembly.hh
Go to the documentation of this file.
1 /*
2  * darcy_flow_assembly.hh
3  *
4  * Created on: Apr 21, 2016
5  * Author: jb
6  */
7 
8 #ifndef SRC_FLOW_DARCY_FLOW_ASSEMBLY_HH_
9 #define SRC_FLOW_DARCY_FLOW_ASSEMBLY_HH_
10 
11 #include <memory>
12 #include "mesh/mesh.h"
13 #include "fem/mapping_p1.hh"
14 #include "fem/fe_p.hh"
15 #include "fem/fe_values.hh"
16 #include "fem/fe_rt.hh"
18 #include "flow/mh_dofhandler.hh"
19 
20 
21 
22 
23 
24 
25 
27  {
28  public:
29  typedef std::shared_ptr<DarcyMH::EqData> AssemblyDataPtr;
31 
32  virtual ~AssemblyBase() {}
33 
34  /**
35  * Generic creator of multidimensional assembly, i.e. vector of
36  * particular assembly objects.
37  */
38  template< template<int dim> class Impl >
39  static MultidimAssembly create(typename Impl<1>::AssemblyDataPtr data) {
40  return { std::make_shared<Impl<1> >(data),
41  std::make_shared<Impl<2> >(data),
42  std::make_shared<Impl<3> >(data) };
43 
44  }
45 
46 
47  // assembly just A block of local matrix
49 
50  // assembly compatible neighbourings
51  virtual void assembly_local_vb(double *local_vb,
52  ElementFullIter ele,
53  Neighbour *ngh) = 0;
54 
55  // compute velocity value in the barycenter
56  // TODO: implement and use general interpolations between discrete spaces
58 
60  {}
61 
62 
63  };
64 
65 
66 
67 
68 
69 
70 
71  template<int dim>
72  class AssemblyMH : public AssemblyBase
73  {
74  public:
76  : quad_(3),
77  fe_values_(map_, quad_, fe_rt_,
79 
80  side_quad_(1),
81  fe_side_values_(map_, side_quad_, fe_p_disc_, update_normal_vectors),
82 
83  velocity_interpolation_quad_(0), // veloctiy values in barycenter
84  velocity_interpolation_fv_(map_,velocity_interpolation_quad_, fe_rt_, update_values | update_quadrature_points),
85 
86  ad_(data),
87  system_(data->system_)
88  {}
89 
90 
91  ~AssemblyMH<dim>() override
92  {}
93 
94  arma::mat::fixed<dim+1,dim+1> assembly_local_geometry_matrix(ElementFullIter ele)
95 
96  {
97  //START_TIMER("Assembly<dim>::assembly_local_matrix");
98  fe_values_.reinit(ele);
99  unsigned int ndofs = fe_values_.get_fe()->n_dofs();
100  unsigned int qsize = fe_values_.get_quadrature()->size();
101  arma::mat::fixed<dim+1,dim+1> local_matrix;
102  local_matrix.zeros();
103  arma::vec3 &gravity_vec = ad_->gravity_vec_;
104 
105  for (unsigned int k=0; k<qsize; k++)
106  {
107  for (unsigned int i=0; i<ndofs; i++)
108  {
109  for (unsigned int j=0; j<ndofs; j++)
110  local_matrix[i*ndofs+j] +=
111  arma::dot(fe_values_.shape_vector(i,k),
112  (ad_->anisotropy.value(ele->centre(), ele->element_accessor() )).i()
113  * fe_values_.shape_vector(j,k)
114  )
115  * fe_values_.JxW(k);
116  ad_->system_.loc_side_rhs[i] +=
117  arma::dot(
118  gravity_vec,
119  fe_values_.shape_vector(i,k)
120  ) * fe_values_.JxW(k);
121  }
122  }
123 
124  return local_matrix;
125  }
126 
128  {
129  double cs = ad_->cross_section.value(ele.centre(), ele.element_accessor());
130  double conduct = ad_->conductivity.value(ele.centre(), ele.element_accessor());
131 
132  double scale = 1 / cs /conduct;
133  *(system_.local_matrix) = scale*assembly_local_geometry_matrix(ele.full_iter());
134  }
135 
136  void assembly_local_vb(double *local_vb, ElementFullIter ele, Neighbour *ngh) override
137  {
138  //START_TIMER("Assembly<dim>::assembly_local_vb");
139  // compute normal vector to side
140  arma::vec3 nv;
141  ElementFullIter ele_higher = ad_->mesh->element.full_iter(ngh->side()->element());
142  fe_side_values_.reinit(ele_higher, ngh->side()->el_idx());
143  nv = fe_side_values_.normal_vector(0);
144 
145  double value = ad_->sigma.value( ele->centre(), ele->element_accessor()) *
146  2*ad_->conductivity.value( ele->centre(), ele->element_accessor()) *
147  arma::dot(ad_->anisotropy.value( ele->centre(), ele->element_accessor())*nv, nv) *
148  ad_->cross_section.value( ngh->side()->centre(), ele_higher->element_accessor() ) * // cross-section of higher dim. (2d)
149  ad_->cross_section.value( ngh->side()->centre(), ele_higher->element_accessor() ) /
150  ad_->cross_section.value( ele->centre(), ele->element_accessor() ) * // crossection of lower dim.
151  ngh->side()->measure();
152 
153  local_vb[0] = -value; local_vb[1] = value;
154  local_vb[2] = value; local_vb[3] = -value;
155  }
156 
157 
159  {
160  //START_TIMER("Assembly<dim>::make_element_vector");
161  arma::vec3 flux_in_center;
162  flux_in_center.zeros();
163 
164  velocity_interpolation_fv_.reinit(ele);
165  for (unsigned int li = 0; li < ele->n_sides(); li++) {
166  flux_in_center += ad_->mh_dh->side_flux( *(ele->side( li ) ) )
167  * velocity_interpolation_fv_.shape_vector(li,0);
168  }
169 
170  flux_in_center /= ad_->cross_section.value(ele->centre(), ele->element_accessor() );
171  return flux_in_center;
172  }
173 
174 
175  // assembly volume integrals
180 
181  // assembly face integrals (BC)
185 
186  // Interpolation of velocity into barycenters
189 
190  // data shared by assemblers of different dimension
193 
194  };
195 
196 
197 #endif /* SRC_FLOW_DARCY_FLOW_ASSEMBLY_HH_ */
const arma::vec3 centre() const
Class MappingP1 implements the affine transformation of the unit cell onto the actual cell...
Shape function values.
Definition: update_flags.hh:87
MappingP1< dim, 3 > map_
std::vector< std::shared_ptr< AssemblyBase > > MultidimAssembly
QGauss< dim-1 > side_quad_
virtual void assembly_local_matrix(LocalElementAccessorBase< 3 > ele)=0
ElementAccessor< 3 > element_accessor()
virtual arma::vec3 make_element_vector(ElementFullIter ele)=0
arma::vec3 make_element_vector(ElementFullIter ele) override
arma::vec3 centre() const
Definition: sides.cc:122
Class FEValues calculates finite element data on the actual cells such as shape function values...
FESideValues< dim, 3 > fe_side_values_
FE_P_disc< 0, dim, 3 > fe_p_disc_
static constexpr bool value
Definition: json.hpp:87
Symmetric Gauss-Legendre quadrature formulae on simplices.
AssemblyDataPtr ad_
std::shared_ptr< DarcyMH::EqData > AssemblyDataPtr
Transformed quadrature points.
FE_RT0< dim, 3 > fe_rt_
Definitions of basic Lagrangean finite elements with polynomial shape functions.
SideIter side()
Shape function gradients.
Definition: update_flags.hh:95
Mixed-hybrid model of linear Darcy flow, possibly unsteady.
FEValues< dim, 3 > velocity_interpolation_fv_
virtual void update_water_content(LocalElementAccessorBase< 3 > ele)
double measure() const
Definition: sides.cc:29
QGauss< dim > quad_
Normal vectors.
virtual ~AssemblyBase()
ElementFullIter element() const
Definition: side_impl.hh:52
void assembly_local_matrix(LocalElementAccessorBase< 3 > ele) override
FEValues< dim, 3 > fe_values_
Definitions of particular quadrature rules on simplices.
unsigned int el_idx() const
Definition: side_impl.hh:81
void assembly_local_vb(double *local_vb, ElementFullIter ele, Neighbour *ngh) override
static MultidimAssembly create(typename Impl< 1 >::AssemblyDataPtr data)
QGauss< dim > velocity_interpolation_quad_
arma::mat::fixed< dim+1, dim+1 > assembly_local_geometry_matrix(ElementFullIter ele)
virtual void assembly_local_vb(double *local_vb, ElementFullIter ele, Neighbour *ngh)=0
ElementFullIter full_iter()
Definitions of Raviart-Thomas finite elements.
RichardsSystem system_
Transformed quadrature weights.