Plugins
Loading...
Searching...
No Matches
inout_bnd_impl.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2025 Gesellschaft fuer Anlagen- und Reaktorsicherheit gGmbH
3 * SPDX-License-Identifier: EUPL-1.2
4 * SPDX-FileContributor: Dmitry Logashenko
5 * SPDX-FileContributor: Goethe Universität Frankfurt
6 * SPDX-FileType: SOURCE
7 *
8 * This file is part of d3f++.
9 * d3f++ is an extension for UG4. Licensing information and citation requirements of UG4 are provided in LICENSES/UG4-LGPL_2.1
10 */
11
12
17namespace ug {
18namespace d3f {
19
20/*----- Class OutFlowBC -----*/
21
25template <typename TDomain, typename TAlgebra>
27(
28 std::string ss_names,
29 std::string fct_names
30)
31{
32 std::vector<std::string> v_ss_names;
33 std::vector<std::string> v_fct_names;
34
35 TokenizeTrimString (ss_names, v_ss_names);
36 for (size_t i = 0; i < v_ss_names.size(); i++)
37 {
38 v_fct_names.clear();
39 TokenizeTrimString (fct_names, v_fct_names);
40 if (v_fct_names.empty ()) continue;
41 std::vector<std::string> & face_fct = m_mStoF[v_ss_names[i]];
42 for (size_t j = 0; j < v_fct_names.size(); j++)
43 face_fct.push_back(v_fct_names[j]);
44 }
45}
46
50template <typename TDomain, typename TAlgebra>
52(
53 std::string fct_names,
54 number scaling
55)
56{
57 std::vector<std::string> v_fct_names;
58 TokenizeTrimString (fct_names, v_fct_names);
59 for (size_t i = 0; i < v_fct_names.size (); i++)
60 m_mFtoM [v_fct_names [i]] = scaling;
61}
62
66template <typename TDomain, typename TAlgebra>
68(
69 const FunctionPattern * fct_pattern,
70 std::vector<number> & v_scaling
71) const
72{
73 typedef fct_name_scaling_map_type::const_iterator scaling_iter_type;
74
75// set the default scaling
76 v_scaling.resize (fct_pattern->num_fct ());
77 for (size_t i = 0; i < v_scaling.size (); i++)
78 v_scaling[i] = 1;
79
80// loop the specifications and extract the scaling
81 for (scaling_iter_type iter = m_mFtoM.begin (); iter != m_mFtoM.end (); ++iter)
82 {
83 const char * fct_name = iter->first.c_str ();
84 number fct_scale = iter->second;
85
86 for (size_t i = 0; i < v_scaling.size (); i++)
87 if (strcmp (fct_name, fct_pattern->name (i)) == 0)
88 v_scaling [i] = fct_scale;
89 }
90}
91
95template <typename TDomain, typename TAlgebra>
97(
98 matrix_type & J,
99 const vector_type & u,
101 int type,
102 number time,
104 const number s_a0
105)
106{
107 if (m_spVolStabData.invalid())
108 UG_THROW ("OutFlowBC: No volume stabilization specified!");
109
110 typedef bc_data_map_type::iterator t_face_iter;
111
112 std::vector<DoFIndex> multInd;
113 SubsetGroup ssGrp (base_type::m_spApproxSpace->subset_handler ());
114 FunctionGroup fctGrp (base_type::m_spApproxSpace->function_pattern ());
115
116// Get the scaling of the equations
117 std::vector<number> vScaling;
118 names_to_ids_in_scaling (base_type::m_spApproxSpace->function_pattern().get (), vScaling);
119
120// Loop the entries of the map
121 for (t_face_iter face = m_mStoF.begin(); face != m_mStoF.end(); ++face)
122 {
123 ssGrp.clear ();
124 ssGrp.add (face->first);
125
126 fctGrp.clear ();
127 fctGrp.add (face->second);
128
129 // Loop over the subsets
130 for (size_t i = 0; i < ssGrp.size (); i++)
131 {
132 int si = ssGrp [i];
133
134 // Loop the edges
135 t_vert_iterator iterEnd = dd->end<Vertex> (si);
136 for (t_vert_iterator iter = dd->begin<Vertex> (si); iter != iterEnd; iter++)
137 {
138 Vertex * vrt = *iter;
139 MathVector<2> & flux_parts = m_spVolStabData->value(vrt);
140 number flux = s_a0 * flux_parts[0] + flux_parts[1];
141
142 // Loop functions
143 for(size_t j = 0; j < fctGrp.size (); j++)
144 {
145 size_t fct = fctGrp [j];
146
147 // Get the multiindices
148 if (dd->inner_dof_indices (vrt, fct, multInd) != 1)
149 UG_THROW ("OutFlowBC: More than one DoF per vertex. Not the Lagrange element?");
150
151 // Add the flux to the diagonal
152 DoFRef (J, multInd[0], multInd[0]) += flux * vScaling[fct];
153 }
154 }
155 }
156 }
157}
158
162template <typename TDomain, typename TAlgebra>
164(
165 vector_type& d,
166 const vector_type& u,
168 int type,
169 number time,
171 const std::vector<number> * vScaleMass,
172 const std::vector<number> * vScaleStiff
173)
174{
175 if (vScaleMass == NULL || vScaleStiff == NULL)
176 UG_THROW ("OutFlowBC: This BC can be used for instationary problems only!");
177 if (m_spVolStabData.invalid())
178 UG_THROW ("OutFlowBC: No volume stabilization specified!");
179
180 typedef bc_data_map_type::iterator t_face_iter;
181
182 std::vector<DoFIndex> multInd;
183 SubsetGroup ssGrp (base_type::m_spApproxSpace->subset_handler ());
184 FunctionGroup fctGrp (base_type::m_spApproxSpace->function_pattern ());
185
186// Get the scaling of the equations
187 std::vector<number> vScaling;
188 names_to_ids_in_scaling (base_type::m_spApproxSpace->function_pattern().get (), vScaling);
189
190// Loop the entries of the map
191 for (t_face_iter face = m_mStoF.begin(); face != m_mStoF.end(); ++face)
192 {
193 ssGrp.clear ();
194 ssGrp.add (face->first);
195
196 fctGrp.clear ();
197 fctGrp.add (face->second);
198
199 // Loop over the subsets
200 for (size_t i = 0; i < ssGrp.size (); i++)
201 {
202 int si = ssGrp [i];
203
204 // Loop the edges
205 t_vert_iterator iterEnd = dd->end<Vertex> (si);
206 for (t_vert_iterator iter = dd->begin<Vertex> (si); iter != iterEnd; iter++)
207 {
208 Vertex * vrt = *iter;
209 MathVector<2> & flux_part = m_spVolStabData->value(vrt);
210 number flux = (* vScaleStiff)[0] * flux_part[0] + (* vScaleMass)[0] * flux_part[1];
211
212 // Loop functions
213 for(size_t j = 0; j < fctGrp.size (); j++)
214 {
215 size_t fct = fctGrp [j];
216
217 // Get the multiindices
218 if (dd->inner_dof_indices (vrt, fct, multInd) != 1)
219 UG_THROW ("OutFlowBC: More than one DoF per vertex. Not the Lagrange element?");
220
221 // Take into account the outflow flux
222 DoFRef (d, multInd[0]) += flux * vScaling[fct] * DoFRef (u, multInd[0]);
223 }
224 }
225 }
226 }
227}
228
229/*----- Class InOutFlowBC -----*/
230
234template <typename TDomain, typename TAlgebra>
236(
237 std::string ss_names,
238 std::string fct_names,
239 number val,
241)
242{
243 std::vector<std::string> v_ss_names;
244 std::vector<std::string> v_fct_names;
245
246 TokenizeTrimString (ss_names, v_ss_names);
247 for (size_t i = 0; i < v_ss_names.size(); i++)
248 {
249 v_fct_names.clear();
250 TokenizeTrimString (fct_names, v_fct_names);
251 if (v_fct_names.empty ()) continue;
252 std::map<std::string, t_inDirichlet> & face_fct = m_mStoF[v_ss_names[i]];
253 for (size_t j = 0; j < v_fct_names.size(); j++)
254 {
255 t_inDirichlet & data = face_fct[v_fct_names[j]];
256 data.val = val;
257 data.func = func;
258 }
259 }
260}
261
265template <typename TDomain, typename TAlgebra>
267(
268 std::string fct_names,
269 number scaling
270)
271{
272 std::vector<std::string> v_fct_names;
273 TokenizeTrimString (fct_names, v_fct_names);
274 for (size_t i = 0; i < v_fct_names.size (); i++)
275 m_mFtoM [v_fct_names [i]] = scaling;
276}
277
281template <typename TDomain, typename TAlgebra>
283(
284 const FunctionPattern * fct_pattern,
285 std::vector<number> & v_scaling
286) const
287{
288 typedef fct_name_scaling_map_type::const_iterator scaling_iter_type;
289
290// set the default scaling
291 v_scaling.resize (fct_pattern->num_fct ());
292 for (size_t i = 0; i < v_scaling.size (); i++)
293 v_scaling[i] = 1;
294
295// loop the specifications and extract the scaling
296 for (scaling_iter_type iter = m_mFtoM.begin (); iter != m_mFtoM.end (); ++iter)
297 {
298 const char * fct_name = iter->first.c_str ();
299 number fct_scale = iter->second;
300
301 for (size_t i = 0; i < v_scaling.size (); i++)
302 if (strcmp (fct_name, fct_pattern->name (i)) == 0)
303 v_scaling [i] = fct_scale;
304 }
305}
306
310template <typename TDomain, typename TAlgebra>
312(
313 matrix_type & J,
314 const vector_type & u,
316 int type,
317 number time,
319 const number s_a0
320)
321{
322 if (m_spVolStabData.invalid())
323 UG_THROW ("InOutFlowBC: No volume stabilization specified!");
324
325 typedef typename bc_data_map_type::iterator t_face_iter;
326 typedef typename std::map<std::string, t_inDirichlet>::iterator t_func_iter;
327
328 std::vector<DoFIndex> multInd;
329 SubsetGroup ssGrp (base_type::m_spApproxSpace->subset_handler ());
330 FunctionGroup fctGrp (base_type::m_spApproxSpace->function_pattern ());
331
332// Get the scaling of the equations
333 std::vector<number> vScaling;
334 names_to_ids_in_scaling (base_type::m_spApproxSpace->function_pattern().get (), vScaling);
335
336// Loop the entries of the map
337 for (t_face_iter face = m_mStoF.begin(); face != m_mStoF.end(); ++face)
338 {
339 ssGrp.clear ();
340 ssGrp.add (face->first);
341
342 fctGrp.clear ();
343 t_func_iter func_end = face->second.end();
344 for (t_func_iter func_iter = face->second.begin(); func_iter != func_end; ++func_iter)
345 fctGrp.add (func_iter->first);
346
347 // Loop over the subsets
348 for (size_t i = 0; i < ssGrp.size (); i++)
349 {
350 int si = ssGrp [i];
351
352 // Loop the edges
353 t_vert_iterator iterEnd = dd->end<Vertex> (si);
354 for (t_vert_iterator iter = dd->begin<Vertex> (si); iter != iterEnd; iter++)
355 {
356 Vertex * vrt = *iter;
357 MathVector<2> & flux_parts = m_spVolStabData->value(vrt);
358 number flux = s_a0 * flux_parts[0] + flux_parts[1];
359
360 // Loop functions
361 for(size_t j = 0; j < fctGrp.size (); j++)
362 {
363 size_t fct = fctGrp [j];
364
365 // Get the multiindices
366 if (dd->inner_dof_indices (vrt, fct, multInd) != 1)
367 UG_THROW ("InOutFlowBC: More than one DoF per vertex. Not the Lagrange element?");
368
369 if (flux > 0)
370 {
371 // Add the flux to the diagonal
372 DoFRef (J, multInd[0], multInd[0]) += flux * vScaling[fct];
373 // Mark the vertex as an outflow vertex
374 m_spVolStabData->set_flag (vrt, true);
375 }
376 else
377 {
378 // Dirichlet: Set the identity matrix
379 SetDirichletRow (J, multInd[0]);
380 // Mark the vertex as a Dirichlet vertex
381 m_spVolStabData->set_flag (vrt, false);
382 }
383 }
384 }
385 }
386 }
387}
388
392template <typename TDomain, typename TAlgebra>
394(
395 vector_type& d,
396 const vector_type& u,
398 int type,
399 number time,
401 const std::vector<number> * vScaleMass,
402 const std::vector<number> * vScaleStiff
403)
404{
405 if (vScaleMass == NULL || vScaleStiff == NULL)
406 UG_THROW ("InOutFlowBC: This BC can be used for instationary problems only!");
407 if (m_spVolStabData.invalid())
408 UG_THROW ("InOutFlowBC: No volume stabilization specified!");
409
410 typedef typename bc_data_map_type::iterator t_face_iter;
411 typedef typename std::map<std::string, t_inDirichlet>::iterator t_func_iter;
412
413 std::vector<DoFIndex> multInd;
414 SubsetGroup ssGrp (base_type::m_spApproxSpace->subset_handler ());
415 FunctionGroup fctGrp (base_type::m_spApproxSpace->function_pattern ());
416
417// Get the scaling of the equations
418 std::vector<number> vScaling;
419 names_to_ids_in_scaling (base_type::m_spApproxSpace->function_pattern().get (), vScaling);
420
421// Loop the entries of the map
422 for (t_face_iter face = m_mStoF.begin(); face != m_mStoF.end(); ++face)
423 {
424 ssGrp.clear ();
425 ssGrp.add (face->first);
426
427 fctGrp.clear ();
428 t_func_iter func_end = face->second.end();
429 for (t_func_iter func_iter = face->second.begin(); func_iter != func_end; ++func_iter)
430 fctGrp.add (func_iter->first);
431
432 // Loop over the subsets
433 for (size_t i = 0; i < ssGrp.size (); i++)
434 {
435 int si = ssGrp [i];
436
437 // Loop the edges
438 t_vert_iterator iterEnd = dd->end<Vertex> (si);
439 for (t_vert_iterator iter = dd->begin<Vertex> (si); iter != iterEnd; iter++)
440 {
441 Vertex * vrt = *iter;
442 MathVector<2> & flux_part = m_spVolStabData->value(vrt);
443 number flux = (* vScaleStiff)[0] * flux_part[0] + (* vScaleMass)[0] * flux_part[1];
444
445 // Loop functions
446 for(size_t j = 0; j < fctGrp.size (); j++)
447 {
448 size_t fct = fctGrp [j];
449
450 // Get the multiindices
451 if (dd->inner_dof_indices (vrt, fct, multInd) != 1)
452 UG_THROW ("InOutFlowBC: More than one DoF per vertex. Not the Lagrange element?");
453
454 if (flux > 0)
455 {
456 // Take into account the outflow flux
457 DoFRef (d, multInd[0]) += flux * vScaling[fct] * DoFRef (u, multInd[0]);
458 // Mark the vertex as an outflow vertex
459 m_spVolStabData->set_flag (vrt, true);
460 }
461 else
462 {
463 // Dirichlet
464 DoFRef (d, multInd[0]) = 0;
465 // Mark the vertex as a Dirichlet vertex
466 m_spVolStabData->set_flag (vrt, false);
467 }
468 }
469 }
470 }
471 }
472}
473
475template <typename TDomain, typename TAlgebra>
477(
478 vector_type & u,
480 int type,
481 number time
482)
483{
484 if (m_spVolStabData.invalid())
485 UG_THROW ("InOutFlowBC: No volume stabilization specified!");
486
487 typedef typename bc_data_map_type::iterator t_face_iter;
488 typedef typename std::map<std::string, t_inDirichlet>::iterator t_func_iter;
489
490 std::vector<DoFIndex> multInd;
491 SubsetGroup ssGrp (base_type::m_spApproxSpace->subset_handler ());
492 ConstSmartPtr<FunctionPattern> fctPattern = base_type::m_spApproxSpace->function_pattern ();
493 typename domain_type::position_accessor_type aaPos = base_type::m_spApproxSpace->domain()->position_accessor();
494
495// Loop the entries of the map
496 for (t_face_iter face = m_mStoF.begin(); face != m_mStoF.end(); ++face)
497 {
498 ssGrp.clear ();
499 ssGrp.add (face->first);
500
501 // Loop over the subsets
502 for (size_t i = 0; i < ssGrp.size (); i++)
503 {
504 int si = ssGrp [i];
505
506 // Loop the edges
507 t_vert_iterator iterEnd = dd->end<Vertex> (si);
508 for (t_vert_iterator iter = dd->begin<Vertex> (si); iter != iterEnd; iter++)
509 {
510 Vertex * vrt = *iter;
511 if (m_spVolStabData->flag (vrt)) continue; // this is outflow, we do nothing here
512
513 // Loop functions
514 t_func_iter func_end = face->second.end();
515 for (t_func_iter func_iter = face->second.begin(); func_iter != func_end; ++func_iter)
516 {
517 // Get the index of the function
518 size_t fct_id = fctPattern->fct_id_by_name (func_iter->first.c_str ());
519
520 // Get the multiindices
521 if (dd->inner_dof_indices (vrt, fct_id, multInd) != 1)
522 UG_THROW ("InOutFlowBC: More than one DoF per vertex. Not the Lagrange element?");
523
524 // Get the Dirichlet value for this vertex
525 t_inDirichlet & inflow_data = func_iter->second;
526 if (inflow_data.func.valid ())
527 (* inflow_data.func) (inflow_data.val, aaPos[vrt], time, si);
528
529 // Set the value
530 DoFRef (u, multInd[0]) = inflow_data.val;
531 /*TODO: These values must depend on the function! */
532 }
533 }
534 }
535 }
536}
537
538} // namespace d3f
539} // end namespace ug
540
541/* End of File */
size_t size() const
void add(const char *name)
size_t num_fct() const
const char * name(size_t fct) const
void add(const char *name)
size_t size() const
void adjust_jacobian(matrix_type &J, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=SPNULL, const number s_a0=1.0)
sets a unity row at the inflow vertices and apply the volume stabilization otherwise
Definition inout_bnd_impl.h:312
void names_to_ids_in_scaling(const FunctionPattern *fct_pattern, std::vector< number > &v_scaling) const
transform the scaling specification from the names to the id's
Definition inout_bnd_impl.h:283
void adjust_defect(vector_type &d, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=SPNULL, const std::vector< number > *vScaleMass=NULL, const std::vector< number > *vScaleStiff=NULL)
sets a zero value in the defect at the inflow vertices and apply the volume stabilization otherwise
Definition inout_bnd_impl.h:394
void adjust_solution(vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0)
sets the dirichlet value in the solution at the inflow vertices
Definition inout_bnd_impl.h:477
void add_spec(std::string ss_names, std::string fct_names, number val, SmartPtr< UserData< number, dim > > func)
adds a boundary condition data specification
Definition inout_bnd_impl.h:236
void scale(std::string fct_names, number scaling)
sets scaling for a given functions
Definition inout_bnd_impl.h:267
algebra_type::vector_type vector_type
type of algebra vector
Definition inout_bnd.h:235
algebra_type::matrix_type matrix_type
type of algebra matrix
Definition inout_bnd.h:232
void names_to_ids_in_scaling(const FunctionPattern *fct_pattern, std::vector< number > &v_scaling) const
transform the scaling specification from the names to the id's
Definition inout_bnd_impl.h:68
void scale(std::string fct_names, number scaling)
sets scaling for a given functions
Definition inout_bnd_impl.h:52
void adjust_jacobian(matrix_type &J, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=SPNULL, const number s_a0=1.0)
apply the volume stabilization to the Jacobian
Definition inout_bnd_impl.h:97
algebra_type::matrix_type matrix_type
type of algebra matrix
Definition inout_bnd.h:69
algebra_type::vector_type vector_type
type of algebra vector
Definition inout_bnd.h:72
void adjust_defect(vector_type &d, const vector_type &u, ConstSmartPtr< DoFDistribution > dd, int type, number time=0.0, ConstSmartPtr< VectorTimeSeries< vector_type > > vSol=SPNULL, const std::vector< number > *vScaleMass=NULL, const std::vector< number > *vScaleStiff=NULL)
apply the volume stabilization to the defect
Definition inout_bnd_impl.h:164
void add(std::string ss_names, std::string fct_names)
adds a combination of subsets and functions to the condition
Definition inout_bnd_impl.h:27
function get(x, y, z, t)
SmartPtr< TSubsetHandler > subset_handler()
Variant::Type type()
UG_API std::vector< std::string > TokenizeTrimString(const std::string &str, const char delimiter=',')
#define UG_THROW(msg)
double number
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
void SetDirichletRow(TMatrix &mat, const DoFIndex &ind)
auxiliary class for the Dirichlet values
Definition inout_bnd.h:243
number val
constant value (if specified)
Definition inout_bnd.h:244
SmartPtr< UserData< number, dim > > func
value as a function (if not SPNULL)
Definition inout_bnd.h:245