Plugins
Loading...
Searching...
No Matches
fv1_conv_impl.h
Go to the documentation of this file.
1/*
2 * Author: Dmitry Logashenko
3 *
4 * This file is part of UG4.
5 *
6 * UG4 is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU Lesser General Public License version 3 (as published by the
8 * Free Software Foundation) with the following additional attribution
9 * requirements (according to LGPL/GPL v3 §7):
10 *
11 * (1) The following notice must be displayed in the Appropriate Legal Notices
12 * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
13 *
14 * (2) The following notice must be displayed at a prominent place in the
15 * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
16 *
17 * (3) The following bibliography is recommended for citation and must be
18 * preserved in all covered files:
19 * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
20 * parallel geometric multigrid solver on hierarchically distributed grids.
21 * Computing and visualization in science 16, 4 (2013), 151-164"
22 * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
23 * flexible software system for simulating pde based models on high performance
24 * computers. Computing and visualization in science 16, 4 (2013), 165-179"
25 *
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU Lesser General Public License for more details.
30 */
31
32/*
33 * Implementation of the FV-discretization of a convection equation (in a non-divergent form).
34 */
35
36/* UG4 headers: */
40
41namespace ug{
42namespace LevelSet{
43
47template<typename TDomain>
50(
52 const char * functions,
53 const char * subsets
54)
55: IElemDisc<TDomain> (functions, subsets),
56 m_spUpwind (upwind), m_source (0), m_diffusion (0),
57 m_alpha(1.0), m_exGrad(new DataExport<MathVector<dim>, dim>(functions))
58{
59// check number of functions
60 if (this->num_fct () != 1)
61 UG_THROW ("Wrong number of functions: The ElemDisc 'FV1_Convection'"
62 " needs exactly 1 symbolic function.");
63
64// no derivatives of the velocity
65 m_imVelocity.set_comp_lin_defect (false);
66
67// register imports
69
70// register assemble functions
72}
73
75// check the grid and the shape functions
77
78template<typename TDomain>
80(
81 const std::vector<LFEID> & vLfeID,
82 bool bNonRegular
83)
84{
85// check the grid
86 if (bNonRegular)
87 UG_THROW ("ERROR in FV1_Convection:"
88 " The discretization does not support hanging nodes.\n");
89
90// check number of the components
91 if (vLfeID.size () != 1)
92 UG_THROW ("FV1_Convection: Only one component is supported.");
93
94// check that these are the Nedelec elements
95 if (vLfeID[0].order() != 1 || vLfeID[0].type() != LFEID::LAGRANGE)
96 UG_THROW ("FV1_Convection: This discretization works with the piecewise linear shape functions only.");
97}
98
100// assembling
102
104template<typename TDomain>
105template<typename TElem>
107(
108 ReferenceObjectID roid,
109 int si
110)
111{
112 typedef FV1Geometry<TElem, dim> TFVGeom;
113 static const int refDim = TElem::dim;
114
115// get the FV geometry
116 static TFVGeom& geo = GeomProvider<TFVGeom>::get ();
117
118// check the upwind method
119 if(m_spUpwind.invalid ())
120 UG_THROW("FV1_Convection: Upwind has not been set.");
121
122// set the local SCVF integration points
123 const MathVector<refDim>* vSCVFip = geo.scvf_local_ips();
124 const size_t numSCVFip = geo.num_scvf_ips();
125 m_imVelocity.template set_local_ips<refDim> (vSCVFip, numSCVFip, false);
126
127// set the FV geometry type in the upwind method
128 m_spUpwind->template set_geometry_type<TFVGeom> (geo);
129}
130
132template<typename TDomain>
133template<typename TElem>
137
139template<typename TDomain>
140template<typename TElem>
142(
143 const LocalVector & u,
144 GridObject * elem,
145 ReferenceObjectID roid, // id of reference element used for assembling
146 const position_type vCornerCoords []
147)
148{
149// update the FV geometry
150 typedef FV1Geometry<TElem, dim> TFVGeom;
151 static TFVGeom& geo = GeomProvider<TFVGeom>::get();
152 try
153 {
154 geo.update (elem, vCornerCoords, &(this->subset_handler()));
155 }
156 UG_CATCH_THROW("FV1_Convection: Cannot update the Finite Volume Geometry.");
157
158// set the local SCVF integration points
159 const MathVector<dim>* vSCVFip = geo.scvf_global_ips();
160 const size_t numSCVFip = geo.num_scvf_ips();
161 m_imVelocity.set_global_ips (vSCVFip, numSCVFip);
162}
163
165template<typename TDomain>
166template<typename TElem>
168(
169 LocalMatrix & J,
170 const LocalVector & u,
171 GridObject * elem,
172 const position_type vCornerCoords []
173)
174{
175// get the FV geometry
176 typedef FV1Geometry<TElem, dim> TFVGeom;
177 static TFVGeom& geo = GeomProvider<TFVGeom>::get ();
178
179// assemble the convective term
180 if (m_imVelocity.data_given())
181 {
182 // update the upwind method
183 if(! m_spUpwind->update (&geo, m_imVelocity.values (), NULL, false))
184 UG_THROW("ERROR in 'FV1_Convection: Cannot compute convection shapes.\n");
185 const size_t numConvShapes = m_spUpwind->num_sh();
186
187 // loop SCVFs
188 for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
189 {
190 // get current SCVF
191 const typename TFVGeom::SCVF& scvf = geo.scvf (ip);
192
193 for(size_t sh = 0; sh < numConvShapes; ++sh)
194 {
195 const number D_conv_flux = (* m_spUpwind) (ip, sh);
196
197 // fluxes through the SCVF (due the convection term in the divergence form)
198 J(_U_, scvf.from(), _U_, sh) += D_conv_flux;
199 J(_U_, scvf.to(), _U_, sh) -= D_conv_flux;
200
201 // sink due to the divergence
202 J(_U_, scvf.from(), _U_, scvf.from()) -= D_conv_flux;
203 J(_U_, scvf.to(), _U_, scvf.to() ) += D_conv_flux;
204 }
205 }
206 }
207
208// assemble the diffusion
209 if(m_diffusion != 0)
210 {
211 // loop SCVFs
212 for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
213 {
214 // get current SCVF
215 const typename TFVGeom::SCVF& scvf = geo.scvf (ip);
216
217 // loop shape functions
218 for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
219 {
220 MathVector<dim> normal= scvf.normal();
221 normal[dim-1] /= m_alpha;
222
223 const number D_diff_flux = m_diffusion * VecDot(scvf.global_grad(sh), normal);
224 J(_U_, scvf.from(), _U_, sh) -= D_diff_flux;
225 J(_U_, scvf.to() , _U_, sh) += D_diff_flux;
226 }
227 }
228 }
229}
230
232template<typename TDomain>
233template<typename TElem>
235(
236 LocalVector & d,
237 const LocalVector & u,
238 GridObject * elem,
239 const position_type vCornerCoords []
240)
241{
242// get the FV geometry
243 typedef FV1Geometry<TElem, dim> TFVGeom;
244 static TFVGeom& geo = GeomProvider<TFVGeom>::get();
245
246// assemble the convective term
247 if (m_imVelocity.data_given())
248 {
249 // update the upwind method
250 if(! m_spUpwind->update (&geo, m_imVelocity.values (), NULL, false))
251 UG_THROW("ERROR in 'FV1_Convection: Cannot compute convection shapes.\n");
252 const size_t numConvShapes = m_spUpwind->num_sh();
253
254 // loop SCVFs
255 for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
256 {
257 // get current SCVF
258 const typename TFVGeom::SCVF& scvf = geo.scvf (ip);
259
260 // fluxes through the SCVF (due the convection term in the divergence form)
261 number conv_flux = 0;
262 for(size_t sh = 0; sh < numConvShapes; ++sh)
263 conv_flux += u (_U_, sh) * (* m_spUpwind) (ip, sh);
264 d(_U_, scvf.from()) += conv_flux;
265 d(_U_, scvf.to() ) -= conv_flux;
266
267 // sink due to the divergence
268 for(size_t sh = 0; sh < numConvShapes; ++sh)
269 {
270 d(_U_, scvf.from()) -= u (_U_, scvf.from()) * (* m_spUpwind) (ip, sh);
271 d(_U_, scvf.to() ) += u (_U_, scvf.to() ) * (* m_spUpwind) (ip, sh);
272 }
273 }
274 }
275
276// assemble the diffusion
277 if(m_diffusion != 0)
278 {
279 // loop SCVFs
280 for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
281 {
282 // get current SCVF
283 const typename TFVGeom::SCVF& scvf = geo.scvf (ip);
284
285 // to compute D \nabla c
286 MathVector<dim> grad;
287
288 // compute gradient at ip
289 VecSet(grad, 0.0);
290 for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
291 VecScaleAppend(grad, u(_U_, sh), scvf.global_grad(sh));
292
293 // compute flux
294 MathVector<dim> normal= scvf.normal();
295 normal[dim-1] /= m_alpha;
296
297 const number diff_flux = m_diffusion * VecDot(grad, normal);
298
299 // add to local defect
300 d(_U_, scvf.from()) -= diff_flux;
301 d(_U_, scvf.to() ) += diff_flux;
302 }
303 }
304}
305
307template<typename TDomain>
308template<typename TElem>
310(
311 LocalMatrix & J,
312 const LocalVector & u,
313 GridObject * elem,
314 const position_type vCornerCoords []
315)
316{
317// get the FV geometry
318 typedef FV1Geometry<TElem, dim> TFVGeom;
319 static TFVGeom& geo = GeomProvider<TFVGeom>::get();
320
321// loop SCVs
322 for(size_t ip = 0; ip < geo.num_scv(); ++ip)
323 {
324 // get current SCV
325 const typename TFVGeom::SCV& scv = geo.scv (ip);
326
327 // get associated node
328 const int co = scv.node_id();
329
330 // Add to local matrix
331 J(_U_, co, _U_, co) += scv.volume ();
332 }
333}
334
336template<typename TDomain>
337template<typename TElem>
339(
340 LocalVector & d,
341 const LocalVector & u,
342 GridObject * elem,
343 const position_type vCornerCoords []
344)
345{
346// get the FV geometry
347 typedef FV1Geometry<TElem, dim> TFVGeom;
348 static TFVGeom& geo = GeomProvider<TFVGeom>::get();
349
350// loop SCVs
351 for(size_t ip = 0; ip < geo.num_scv(); ++ip)
352 {
353 // get current SCV
354 const typename TFVGeom::SCV& scv = geo.scv (ip);
355
356 // get associated node
357 const int co = scv.node_id();
358
359 // Add to local defect
360 d(_U_, co) += u (_U_, co) * scv.volume ();
361 }
362}
363
365template<typename TDomain>
366template<typename TElem>
368(
369 LocalVector & b,
370 GridObject * elem,
371 const position_type vCornerCoords []
372)
373{
374// get the FV geometry
375 typedef FV1Geometry<TElem, dim> TFVGeom;
376 static TFVGeom& geo = GeomProvider<TFVGeom>::get();
377
378// loop SCVs
379 for(size_t ip = 0; ip < geo.num_scv(); ++ip)
380 {
381 // get current SCV
382 const typename TFVGeom::SCV& scv = geo.scv (ip);
383
384 // get associated node
385 const int co = scv.node_id();
386
387 // add the source
388 b(_U_, co) += m_source * scv.volume ();
389 }
390}
391
393// register assembling functions
395
397template<typename TDomain>
399{
400// get all grid element types in this dimension and below
401 typedef typename domain_traits<dim>::DimElemList ElemList;
402
403// switch assemble functions
404 boost::mpl::for_each<ElemList> (RegisterLocalDiscr (this));
405}
406
408template<typename TDomain>
409template<typename TElem> // the element to register for
411{
413
414 this->clear_add_fct(id);
415
416 this->set_prep_elem_loop_fct(id, & this_type::template prepare_element_loop<TElem>);
417 this->set_prep_elem_fct (id, & this_type::template prepare_element<TElem>);
418 this->set_fsh_elem_loop_fct (id, & this_type::template finish_element_loop<TElem>);
419 this->set_add_jac_A_elem_fct(id, & this_type::template ass_JA_elem<TElem>);
420 this->set_add_jac_M_elem_fct(id, & this_type::template ass_JM_elem<TElem>);
421 this->set_add_def_A_elem_fct(id, & this_type::template ass_dA_elem<TElem>);
422 this->set_add_def_M_elem_fct(id, & this_type::template ass_dM_elem<TElem>);
423 this->set_add_rhs_elem_fct (id, & this_type::template ass_rhs_elem<TElem>);
424
425 static const int refDim = reference_element_traits<TElem>::dim;
426 m_exGrad->template set_fct<this_type,refDim>(id, this, &this_type::template ex_grad<TElem>);
427}
428
429
430
431// computes the linearized defect w.r.t to the velocity
432template<typename TDomain>
433template <typename TElem>
435ex_grad(MathVector<dim> vValue[],
436 const MathVector<dim> vGlobIP[],
437 number time, int si,
438 const LocalVector& u,
439 GridObject* elem,
440 const MathVector<dim> vCornerCoords[],
441 const MathVector<dim> vLocIP[],
442 const size_t nip,
443 bool bDeriv,
444 std::vector<std::vector<MathVector<dim> > > vvvDeriv[])
445{
446
447 // get the FV geometry
448 typedef FV1Geometry<TElem, dim> TFVGeom;
449 static TFVGeom& geo = GeomProvider<TFVGeom>::get();
450
451 // assemble the convective term
452 /* if (m_imVelocity.data_given())
453 {
454 // update the upwind method
455 if(! m_spUpwind->update (&geo, m_imVelocity.values (), NULL, false))
456 UG_THROW("ERROR in 'FV1_Convection: Cannot compute convection shapes.\n");
457 const size_t numConvShapes = m_spUpwind->num_sh();
458
459 // loop SCVFs
460 for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
461 {
462 // get current SCVF
463 const typename TFVGeom::SCVF& scvf = geo.scvf (ip);
464
465 // fluxes through the SCVF (due the convection term in the divergence form)
466 number conv_flux = 0;
467 for(size_t sh = 0; sh < numConvShapes; ++sh)
468 conv_flux += u (_U_, sh) * (* m_spUpwind) (ip, sh);
469 d(_U_, scvf.from()) += conv_flux;
470 d(_U_, scvf.to() ) -= conv_flux;
471
472 // sink due to the divergence
473 for(size_t sh = 0; sh < numConvShapes; ++sh)
474 {
475 d(_U_, scvf.from()) -= u (_U_, scvf.from()) * (* m_spUpwind) (ip, sh);
476 d(_U_, scvf.to() ) += u (_U_, scvf.to() ) * (* m_spUpwind) (ip, sh);
477 }
478 }
479 }*/
480 // assemble the diffusion
481 if(m_diffusion != 0)
482 {
483
484 UG_ASSERT(vLocIP == geo.scvf_local_ips(), "Huhh: Think twice!");
485
486 if(vLocIP == geo.scvf_local_ips())
487 {
488 // Loop Sub Control Volume Faces (SCVF)
489 for(size_t ip = 0; ip < geo.num_scvf(); ++ip)
490 {
491 // Get current SCVF
492 const typename TFVGeom::SCVF& scvf = geo.scvf(ip);
493
494 // compute gradient at ip
495 MathVector<dim> &grad = vValue[ip];
496 VecSet(grad, 0.0);
497 for(size_t sh = 0; sh < scvf.num_sh(); ++sh)
498 VecScaleAppend(grad, m_diffusion*u(_U_, sh), scvf.global_grad(sh));
499
500 grad[dim-1] /= m_alpha;
501
502
503 }
504 }
505
506
507}
508};
509
510} // end namespace LevelSet
511} // end namespace ug
512
513/* End of File */
static TGeom & get()
size_t num_fct() const
void register_import(IDataImport< dim > &Imp)
virtual void prepare_setting(const std::vector< LFEID > &vLfeID, bool bNonRegular)
check type of the grid and the trial space
Definition fv1_conv_impl.h:80
base_type::position_type position_type
position type
Definition fv1_conv.h:89
void ex_grad(MathVector< dim > vValue[], const MathVector< dim > vGlobIP[], number time, int si, const LocalVector &u, GridObject *elem, const MathVector< dim > vCornerCoords[], const MathVector< dim > vLocIP[], const size_t nip, bool bDeriv, std::vector< std::vector< MathVector< dim > > > vvvDeriv[])
computes the gradient of the concentration
Definition fv1_conv_impl.h:435
void finish_element_loop()
finalizes the loop over the elements: clear the source
Definition fv1_conv_impl.h:134
void ass_dM_elem(LocalVector &d, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the mass part of the defect of a time-dependent problem
Definition fv1_conv_impl.h:339
void register_loc_discr_func()
registers the local assembler functions for a given element
Definition fv1_conv_impl.h:410
void prepare_element(const LocalVector &u, GridObject *elem, ReferenceObjectID roid, const position_type vCornerCoords[])
prepares a given element for assembling: computes the discretization of the rot-rot operator
Definition fv1_conv_impl.h:142
void ass_rhs_elem(LocalVector &d, GridObject *elem, const position_type vCornerCoords[])
assembles the right-hand side
Definition fv1_conv_impl.h:368
void ass_JM_elem(LocalMatrix &J, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
computes the mass matrix of a time-dependent problem
Definition fv1_conv_impl.h:310
void prepare_element_loop(ReferenceObjectID roid, int si)
prepares the loop over the elements: checks whether the parameters are set, ...
Definition fv1_conv_impl.h:107
DataImport< MathVector< dim >, dim > m_imVelocity
data import for the velocity field (if used)
Definition fv1_conv.h:229
FV1_Convection(SmartPtr< IConvectionShapes< dim > > upwind, const char *functions, const char *subsets)
constructor
Definition fv1_conv_impl.h:50
void ass_dA_elem(LocalVector &d, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
assembles the local defect
Definition fv1_conv_impl.h:235
void register_all_loc_discr_funcs()
registers the local assembler functions for all the elements and dimensions
Definition fv1_conv_impl.h:398
void ass_JA_elem(LocalMatrix &J, const LocalVector &u, GridObject *elem, const position_type vCornerCoords[])
assembles the local stiffness matrix
Definition fv1_conv_impl.h:168
SmartPtr< TSubsetHandler > subset_handler()
Variant::Type type()
#define UG_ASSERT(expr, msg)
#define UG_CATCH_THROW(msg)
#define UG_THROW(msg)
double number
void VecScaleAppend(vector_t &vOut, typename vector_t::value_type s1, const vector_t &v1)
vector_t::value_type VecDot(const vector_t &v1, const vector_t &v2)
ReferenceObjectID
void VecSet(vector_t &dest, number alpha, const std::vector< size_t > vIndex)