ug4
Loading...
Searching...
No Matches
cons_gravity_linker.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2026: CEMSE, KAUST
3 * Author: Dmitry Logashenko
4 *
5 * This file is part of UG4.
6 *
7 * UG4 is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License version 3 (as published by the
9 * Free Software Foundation) with the following additional attribution
10 * requirements (according to LGPL/GPL v3 §7):
11 *
12 * (1) The following notice must be displayed in the Appropriate Legal Notices
13 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 *
15 * (2) The following notice must be displayed at a prominent place in the
16 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 *
18 * (3) The following bibliography is recommended for citation and must be
19 * preserved in all covered files:
20 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 * parallel geometric multigrid solver on hierarchically distributed grids.
22 * Computing and visualization in science 16, 4 (2013), 151-164"
23 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 * flexible software system for simulating pde based models on high performance
25 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
26 *
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU Lesser General Public License for more details.
31 */
32
33#ifndef __H__UG__LIB_DISC__SPATIAL_DISC__CONSISTENT_GRAVITY_LINKER__
34#define __H__UG__LIB_DISC__SPATIAL_DISC__CONSISTENT_GRAVITY_LINKER__
35
36#include <vector>
37
40#include "linker.h"
41#ifdef UG_FOR_LUA
43#endif
44
45namespace ug{
46
47
49// Consistent Gravity linker
51
53
71template <int dim>
73 : public StdDataLinker<ConsistentGravityLinker<dim>, MathVector<dim>, dim>
74{
77
79 static const int world_dim = dim;
80
81 public:
83 m_spDensity(NULL), m_spDDensity(NULL),
84 m_gravity(0), m_noDerivatives(false)
85 {
86 this->set_num_input(1);
87 }
88
89
90 inline void evaluate (MathVector<dim>& value,
91 const MathVector<dim>& globIP,
92 number time, int si) const
93 {
94 UG_THROW("ConsistentGravityLinker: Element required for evaluation.")
95 }
96
97 template <int refDim>
98 inline void evaluate(MathVector<dim> vValue[],
99 const MathVector<dim> vGlobIP[],
100 number time, int si,
101 GridObject* elem,
102 const MathVector<dim> vCornerCoords[],
103 const MathVector<refDim> vLocalIP[],
104 const size_t nip,
105 LocalVector* u,
106 const MathMatrix<refDim, dim>* vJT = NULL) const
107 {
108 const ReferenceObjectID roid = elem->reference_object_id();
109 const DimReferenceElement<refDim>& refElem = ReferenceElementProvider::get<refDim>(roid);
110 const size_t nco = refElem.num(ROID_VERTEX);
111
112 const LocalShapeFunctionSet<refDim>& trialSpace =
113 LocalFiniteElementProvider::get<refDim>(roid, LFEID(LFEID::LAGRANGE, refDim, 1));
114
115 // consistent gravity
116 StdLinConsistentGravity<refDim> ConsGravityMethod;
117 std::vector<MathVector<refDim> > vConsGravity(nco);
118 std::vector<MathVector<refDim> > vLocalGrad(nco);
119
120 // coefficients at the integration points
121 MathVector<dim> gravity; // we assume that the gravity is constant in the elem
122 std::vector<number> vDensity(nco);
123
124 (*m_spDensity)(&(vDensity[0]), vCornerCoords, time, si,
125 elem, vCornerCoords, refElem.corners(), nco, u, NULL);
126
127 try
128 {
129 ConsGravityMethod.template prepare<dim>
130 (&(vConsGravity[0]), nco, vCornerCoords, &(vDensity[0]), m_gravity);
131 }
132 UG_CATCH_THROW ("ConsistentDarcyVelLinker: Cannot prepare the consistent gravity.");
133
134 // get jacobians of the transformation mapping if not passed
135 std::vector<MathMatrix<refDim, dim> > vJT_;
136 if(vJT == NULL)
137 {
139 = ReferenceMappingProvider::get<refDim, dim>(roid, vCornerCoords);
140 vJT_.resize(nip);
141 mapping.jacobian_transposed(&(vJT_[0]), vLocalIP, nip);
142 vJT = &(vJT_[0]);
143 }
144
145 for(size_t ip = 0; ip < nip; ++ip)
146 {
147 // get the local gradient (assuming the Lagrange-1 basis functions)
148 trialSpace.grads(&(vLocalGrad[0]), vLocalIP[ip]);
149
150 // get the inverse Jacobian
152 RightInverse(JTInv, vJT[ip]);
153
154 // compute [rho*g]_consistent
155 ConsGravityMethod.template compute<dim>
156 (vValue[ip], vLocalIP[ip], JTInv, &(vLocalGrad[0]), &(vConsGravity[0]));
157 }
158 }
159
160 template <int refDim>
162 const ReferenceObjectID roid,
163 const MathVector<dim> vCornerCoords[])
164 {
165 const DimReferenceElement<refDim>& refElem = ReferenceElementProvider::get<refDim>(roid);
166
167 m_densityCornerS = m_spDensity->template register_local_ip_series<refDim>
168 (refElem.corners(), refElem.num(0), this->time_point(), false);
169 m_spDensity->set_global_ips(m_densityCornerS, vCornerCoords, refElem.num(0));
170 }
171
172 virtual void prepare_element(GridObject* elem, const MathVector<dim> vCornerCoords[])
173 {
174 const ReferenceObjectID roid = elem->reference_object_id();
175 const ReferenceElement& refElem = ReferenceElementProvider::get(roid);
176 const int ref_dim = refElem.dimension();
177 switch(ref_dim)
178 {
179 case 1: this->template prepare_dim_elem<1> (elem, roid, vCornerCoords); break;
180 case 2: this->template prepare_dim_elem<2> (elem, roid, vCornerCoords); break;
181 case 3: this->template prepare_dim_elem<3> (elem, roid, vCornerCoords); break;
182 default: UG_THROW("ConsistentDarcyVelLinker: Ref. dimension " << ref_dim << " not supported.");
183 }
184 }
185
186 template <int refDim>
188 const MathVector<dim> vGlobIP[],
189 number time, int si,
190 GridObject* elem,
191 const MathVector<dim> vCornerCoords[],
192 const MathVector<refDim> vLocalIP[],
193 const size_t nip,
194 LocalVector* u,
195 bool bDeriv,
196 int s,
197 std::vector<std::vector<MathVector<dim> > > vvvDeriv[],
198 const MathMatrix<refDim, dim>* vJT = NULL) const
199 {
200 const ReferenceObjectID roid = elem->reference_object_id();
201 const DimReferenceElement<refDim>& refElem = ReferenceElementProvider::get<refDim>(roid);
202 const size_t nco = refElem.num(ROID_VERTEX);
203
204 const LocalShapeFunctionSet<refDim>& trialSpace =
205 LocalFiniteElementProvider::get<refDim>(roid, LFEID(LFEID::LAGRANGE, refDim, 1));
206
207 // consistent gravity
208 StdLinConsistentGravity<refDim> ConsGravityMethod;
209 std::vector<MathVector<refDim> > vConsGravity(nco);
210
211 // inverse jacobians of the transformation at the integration points
212 std::vector<MathMatrix<dim,refDim> > vJTInv(nip);
213
214 // local gradients at the integration points
215 std::vector<MathVector<refDim> > vLocalGrad(nco);
216
217 // get the data of the ip series
218 const number* vDensity = m_spDensity->values(m_densityCornerS);
219
220 // prepare the consistent gravity term
221 try
222 {
223 ConsGravityMethod.template prepare<dim>
224 (&(vConsGravity[0]), nco, vCornerCoords, vDensity, m_gravity);
225 }
226 UG_CATCH_THROW ("ConsistentGravityLinker: Cannot prepare the consistent gravity.");
227
228 // get jacobians of the transformation mapping if not passed
229 std::vector<MathMatrix<refDim, dim> > vJT_;
230 if(vJT == NULL)
231 {
233 = ReferenceMappingProvider::get<refDim, dim>(roid, vCornerCoords);
234 vJT_.resize(nip);
235 mapping.jacobian_transposed(&(vJT_[0]), vLocalIP, nip);
236 vJT = &(vJT_[0]);
237 }
238
239 for(size_t ip = 0; ip < nip; ++ip)
240 {
241 // get the local gradient (assuming the Lagrange-1 basis functions)
242 trialSpace.grads(&(vLocalGrad[0]), vLocalIP[ip]);
243
244 // get the inverse Jacobian
245 RightInverse(vJTInv[ip], vJT[ip]);
246
247 // compute [rho*g]_consistent
248 ConsGravityMethod.template compute<dim>
249 (vValue[ip], vLocalIP[ip], vJTInv[ip], &(vLocalGrad[0]), &(vConsGravity[0]));
250 }
251
252 if(!bDeriv)
253 return;
254
255 // Compute the derivatives at all ips
256
257 this->set_zero(vvvDeriv, nip);
258
259 if(m_noDerivatives || this->zero_derivative() || (!m_spDDensity.valid()) || m_spDDensity->zero_derivative())
260 return;
261
262 // prepare derivatives of the primary function at the corners
263 std::vector<std::vector<MathVector<refDim> > > vvDConsGravity(nco);
264 try
265 {
266 std::vector<number> DCoVal(nco);
267 DCoVal.assign(nco, 0);
268 for (size_t co = 0; co < nco; co++)
269 {
270 DCoVal[co] = 1;
271 vvDConsGravity[co].resize(nco);
272 ConsGravityMethod.template prepare<dim>
273 (&(vvDConsGravity[co][0]), nco, vCornerCoords, &(DCoVal[0]), m_gravity);
274 DCoVal[co] = 0;
275 }
276 }
277 UG_CATCH_THROW ("ConsistentGravityLinker: Cannot prepare Consistent Gravity for its derivatives.");
278
279 // compute the derivatives of the density
280 if(m_noDerivatives || m_spDDensity->zero_derivative())
281 return;
282
283 for(size_t fct = 0; fct < m_spDDensity->num_fct(); ++fct) // fct = concentration, pressure, ...
284 {
285 // get common fct id for this function
286 const size_t commonFct = this->input_common_fct(_RHO_, fct);
287 if(this->num_sh(commonFct) != nco)
288 UG_THROW ("ConsistentGravityLinker: Number of shapes mismatch.");
289
290 for(size_t ip = 0; ip < nip; ++ip) // we derive the cons. grav. at this ip
291 {
292 trialSpace.grads(&(vLocalGrad[0]), vLocalIP[ip]);
293
294 for(size_t co = 0; co < nco; ++co) // w.r.t to the DoF at this corner (shape idx.)
295 {
296 const number* vDDensity = m_spDDensity->deriv(m_densityCornerS, co, fct);
297 MathVector<dim>& deriv = vvvDeriv[ip][commonFct][co];
298
299 ConsGravityMethod.template compute<dim>(deriv,
300 vLocalIP[ip], vJTInv[ip], &(vLocalGrad[0]), &(vvDConsGravity[co][0]));
301 VecScale(deriv, deriv, vDDensity[co]);
302
303 /* Note that here we assume that the density has the local dependence
304 * on the arguments (concentration, pressure, ...): The density at
305 * corner co depends only on the DoFs at that corner. However, this
306 * excludes any differential operators, interpolations etc.
307 */
308 }
309 }
310 }
311 }
312
313 public:
314
317 {
318 m_spDensity = data;
319 m_spDDensity = data.template cast_dynamic<DependentUserData<number, dim> >();
320 base_type::set_input(_RHO_, data, data);
321 }
322
324 {
326 }
327
330 {
331 m_gravity = g;
332 }
333
335 void set_gravity(const std::vector<number>& vGravity)
336 {
337 if(vGravity.size() != dim)
338 UG_THROW("ConsistentGravityLinker: Illegal dimension of the specified gravity vector.");
339 for(size_t i = 0; i < dim; i++) m_gravity[i] = vGravity[i];
340 }
341
344 {
345 m_gravity = 0;
346 m_gravity[dim-1] = g;
347 }
348
349 protected:
351 static const size_t _RHO_ = 0;
355
358
359
360 public:
362
363 protected:
364 // disable the derivatives
366};
367
368} // end namespace ug
369
370#endif /* __H__UG__LIB_DISC__SPATIAL_DISC__CONSISTENT_GRAVITY_LINKER__ */
Definition smart_pointer.h:107
Linker for the consistent gravity (according to P. Frolkovic)
Definition cons_gravity_linker.h:74
void set_gravity(number g)
set gravity in the z direction
Definition cons_gravity_linker.h:343
void eval_and_deriv(MathVector< dim > vValue[], const MathVector< dim > vGlobIP[], number time, int si, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< refDim > vLocalIP[], const size_t nip, LocalVector *u, bool bDeriv, int s, std::vector< std::vector< MathVector< dim > > > vvvDeriv[], const MathMatrix< refDim, dim > *vJT=NULL) const
Definition cons_gravity_linker.h:187
void prepare_dim_elem(GridObject *elem, const ReferenceObjectID roid, const MathVector< dim > vCornerCoords[])
Definition cons_gravity_linker.h:161
SmartPtr< CplUserData< number, dim > > m_spDensity
Definition cons_gravity_linker.h:352
void evaluate(MathVector< dim > &value, const MathVector< dim > &globIP, number time, int si) const
Definition cons_gravity_linker.h:90
void set_gravity(MathVector< dim > g)
set gravity vector
Definition cons_gravity_linker.h:329
virtual void prepare_element(GridObject *elem, const MathVector< dim > vCornerCoords[])
called in the preparation for a particular element
Definition cons_gravity_linker.h:172
void evaluate(MathVector< dim > vValue[], const MathVector< dim > vGlobIP[], number time, int si, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< refDim > vLocalIP[], const size_t nip, LocalVector *u, const MathMatrix< refDim, dim > *vJT=NULL) const
Definition cons_gravity_linker.h:98
void set_gravity(const std::vector< number > &vGravity)
set gravity from an array
Definition cons_gravity_linker.h:335
static const size_t _RHO_
import density
Definition cons_gravity_linker.h:351
static const int world_dim
The world dimension.
Definition cons_gravity_linker.h:79
ConsistentGravityLinker()
Definition cons_gravity_linker.h:82
StdDataLinker< ConsistentGravityLinker< dim >, MathVector< dim >, dim > base_type
Base class type.
Definition cons_gravity_linker.h:76
void set_no_derivatives(bool v)
Definition cons_gravity_linker.h:361
void set_density(number val)
Definition cons_gravity_linker.h:323
size_t m_densityCornerS
Definition cons_gravity_linker.h:354
bool m_noDerivatives
Definition cons_gravity_linker.h:365
SmartPtr< DependentUserData< number, dim > > m_spDDensity
Definition cons_gravity_linker.h:353
MathVector< dim > m_gravity
constant gravity
Definition cons_gravity_linker.h:357
void set_density(SmartPtr< CplUserData< number, dim > > data)
set density import
Definition cons_gravity_linker.h:316
constant scalar user data
Definition const_user_data.h:153
Type based UserData.
Definition user_data.h:506
const TData * values(size_t s) const
returns all values for a series
Definition user_data.h:521
const TData & value(size_t s, size_t ip) const
returns the value at ip
Definition user_data.h:517
dimension dependent base class for reference elements
Definition reference_element.h:183
const MathVector< dim > * corners() const
coordinates of reference corner in a vector
Definition reference_element.h:189
virtual base class for reference mappings
Definition reference_mapping_provider.h:53
virtual void jacobian_transposed(MathMatrix< dim, worldDim > &JT, const MathVector< dim > &locPos) const =0
returns transposed of jacobian
The base class for all geometric objects, such as vertices, edges, faces, volumes,...
Definition grid_base_objects.h:157
virtual ReferenceObjectID reference_object_id() const =0
number time() const
get the current evaluation time
Definition user_data.h:287
const MathVector< dim > & ip(size_t s, size_t ip) const
returns global ip
Definition user_data.h:406
void set_global_ips(size_t s, const MathVector< dim > *vPos, size_t numIP)
set global positions
Definition user_data_impl.h:231
Identifier for Local Finite Elements.
Definition local_finite_element_id.h:98
@ LAGRANGE
Definition local_finite_element_id.h:104
virtual base class for local shape function sets
Definition local_shape_function_set.h:70
virtual void grads(grad_type *vGrad, const MathVector< dim > &x) const =0
returns all gradients evaluated at a point
Definition local_algebra.h:198
A class for fixed size, dense matrices.
Definition math_matrix.h:63
a mathematical Vector with N entries.
Definition math_vector.h:97
base class for reference elements
Definition reference_element.h:70
size_t num(int dim) const
returns the number of geometric objects of dim
Definition reference_element.h:95
int dimension() const
returns the dimension where reference element lives
Definition reference_element.h:80
static const DimReferenceElement< dim > & get(ReferenceObjectID roid)
returns a dimension dependent Reference Element
Definition reference_element.h:280
combines several UserDatas to a new UserData of a specified type
Definition linker.h:54
void set_num_input(size_t num)
sets the number of inputs
Definition linker.h:107
size_t input_common_fct(size_t i, size_t fct) const
returns the number in the common FctGrp for a fct of an input
Definition linker.h:153
virtual void set_input(size_t i, SmartPtr< ICplUserData< dim > > input, SmartPtr< UserDataInfo > info)
sets an input
Definition linker.h:114
virtual bool zero_derivative() const
returns if derivative is zero
Definition linker_impl.h:179
Class for the computation of the standard version ('Voss-Souza-type') of the consistent gravity.
Definition consistent_gravity.h:100
MathMatrix< N, M, T >::value_type RightInverse(MathMatrix< N, M, T > &mOut, const MathMatrix< M, N, T > &m)
Right-Inverse of a Matrix.
Definition math_matrix_functions_common_impl.hpp:679
#define UG_CATCH_THROW(msg)
Definition error.h:64
#define UG_THROW(msg)
Definition error.h:57
double number
Definition types.h:124
void VecScale(vector_t &vOut, const vector_t &v, typename vector_t::value_type s)
scales a MathVector<N>
Definition math_vector_functions_common_impl.hpp:252
the ug namespace
ReferenceObjectID
these ids are used to identify the shape of a geometric object.
Definition grid_base_objects.h:74
@ ROID_VERTEX
Definition grid_base_objects.h:76
SmartPtr< T, FreePolicy > make_sp(T *inst)
returns a SmartPtr for the passed raw pointer
Definition smart_pointer.h:839