Plugins
Loading...
Searching...
No Matches
rivers_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
13/*
14 * Implementation of the surface rivers represented as sets of 1d segments in 3d.
15 */
16
17#ifdef UG_PARALLEL
19#endif
20
21namespace ug {
22namespace d3f {
23
24/*----- Class 'VertexLowDimRecharge': -----*/
25
27template <typename TGridFunction>
29(
30 const char* subsetNames,
31 number top_tolerance,
32 int top_grid_level
33)
34{
35 domain_type& domain = * m_lsPosZ.lsf()->domain ();
36 MultiGrid& mg = * domain.grid ();
37 MGSubsetHandler& sh = * domain.subset_handler ();
38
39// parse the subset names
40 SubsetGroup ssGrp (domain.subset_handler ());
41 ssGrp.add (TokenizeString (subsetNames));
42
43// create the tree
44 m_top_tolerance = top_tolerance;
45 m_spTopTracerTree = SmartPtr<top_tracer_tree_t> (new top_tracer_tree_t (mg, domain.position_attachment ()));
46
47// fill the tree
48 std::vector<g_surf_elem_t*> top_faces;
49 for (size_t i = 0; i < ssGrp.size (); i++)
50 {
51 int si = ssGrp [i];
52 if (top_grid_level >= 0) // if the grid level specified
53 for (g_surf_iter_t it = sh.begin<g_surf_elem_t> (si, top_grid_level);
54 it != sh.end<g_surf_elem_t> (si, top_grid_level); ++it)
55 top_faces.push_back (*it);
56 else
57 for (int lvl = 0; lvl < (int) sh.num_levels(); lvl++)
58 for (g_surf_iter_t it = sh.begin<g_surf_elem_t> (si, lvl);
59 it != sh.end<g_surf_elem_t> (si, lvl); ++it)
60 {
61 g_surf_elem_t * t = *it;
62 if (! mg.has_children (t))
63 top_faces.push_back (t);
64 }
65 }
66 m_spTopTracerTree->create_tree (top_faces.begin (), top_faces.end ());
67}
68
70template <typename TGridFunction>
72(
73 const MathVector<dim> & over
74)
75{
76 m_topTracePoints.clear ();
77
78 MathVector<dim> up_dir;
79 up_dir = 0;
80 up_dir [dim - 1] = 1;
81 RayElementIntersections (m_topIntersectionRecords, * (m_spTopTracerTree.get ()), over, up_dir, m_top_tolerance);
82
83 for_each_in_vec (top_intersection_record_t& r, m_topIntersectionRecords)
84 {
85 m_topTracePoints.push_back (PointOnRay (over, up_dir, r.smin));
86 }
87 end_for;
88
89 return m_topTracePoints.size ();
90}
91
93template <typename TGridFunction>
95(
96 SmartPtr<grid_func_type> spRecharge
97)
98{
99 typedef typename domain_type::position_accessor_type position_accessor_type;
100 typedef typename grid_func_type::template traits<Vertex>::const_iterator const_vrt_iter_t;
101
102// Coordinates of the points
103 position_accessor_type & aaPos = spRecharge->domain()->position_accessor ();
104
105// Loop the vertices
106 std::vector<DoFIndex> ind (1);
107 const_vrt_iter_t vrtIterEnd = spRecharge->template end<Vertex> ();
108 for (const_vrt_iter_t iter = spRecharge->template begin<Vertex> (); iter != vrtIterEnd; ++iter)
109 {
110 Vertex * vrt = * iter;
111 spRecharge->inner_dof_indices (vrt, 0, ind);
112 DoFRef (*spRecharge, ind[0]) = simple_smoothed_recharge_at (aaPos[vrt]);
113 }
114}
115
117template <typename TGridFunction>
119(
120 SmartPtr<grid_func_type> spRecharge
121)
122{
123 typedef typename domain_type::position_accessor_type position_accessor_type;
124 typedef typename grid_func_type::template traits<Vertex>::const_iterator const_vrt_iter_t;
125
126// Coordinates of the points
127 position_accessor_type & aaPos = spRecharge->domain()->position_accessor ();
128
129// Reinitialize the depth measurer and compute the depths of the free surface
130 compute_depths ();
131
132// Loop the vertices
133 std::vector<DoFIndex> ind (1);
134 const_vrt_iter_t vrtIterEnd = spRecharge->template end<Vertex> ();
135 for (const_vrt_iter_t iter = spRecharge->template begin<Vertex> (); iter != vrtIterEnd; ++iter)
136 {
137 Vertex * vrt = * iter;
138 spRecharge->inner_dof_indices (vrt, 0, ind);
139 DoFRef (*spRecharge, ind[0]) = smoothed_recharge_at (aaPos[vrt]);
140 }
141}
142
143/*----- Class 'VertexWellRecharge': -----*/
144
146template <typename TGridFunction>
148{
149// Prepare the object for a new level-set function
150 this->prepare_ls_height ();
151
152// Loop the wells
153 for (size_t well_i = 0; well_i < m_wells.size (); well_i++)
154 {
155 well_recharge_data_t& well = m_wells [well_i];
156
157 well.well_depth = well.well_depth_spec;
158
159 // get the depth of the free surface at the center
160 well.fs_depth = this->get_ls_height_at (well.x);
161
162 // take into the account the actual top
163 if (this->ls_depth_is_relative ())
164 {
165 // get the height of the "top of the domain" over this segment
166 number top_depth;
167 if (this->min_top_depth (well.x, top_depth) == 0)
168 {
169 well.well_depth = std::numeric_limits<number>::max (); // the well is not covered by the top
170 continue; // skip the computation of the river depth for this segment
171 }
172 // correct the depth of the river for this segment
173 well.well_depth += top_depth;
174 }
175
176 // restrict the depth of the river
177 if (this->restrict_depth () && well.fs_depth != - std::numeric_limits<number>::max ()
178 && well.well_depth < well.fs_depth - this->max_depth_diff ())
179 well.well_depth = well.fs_depth - this->max_depth_diff ();
180 }
181
182#ifdef UG_PARALLEL
183// reduce the depths
185 std::vector<number> fs_depth_vec (m_wells.size ());
186 std::vector<number> well_depth_vec (m_wells.size ());
187 for (size_t well_i = 0; well_i < m_wells.size (); well_i++)
188 {
189 well_recharge_data_t& well = m_wells [well_i];
190 fs_depth_vec [well_i] = well.fs_depth;
191 well_depth_vec [well_i] = well.well_depth;
192 }
193 std::vector<number> red_fs_depth_vec;
194 std::vector<number> red_well_depth_vec;
195 procComm.allreduce (fs_depth_vec, red_fs_depth_vec, PCL_RO_MAX);
196 procComm.allreduce (well_depth_vec, red_well_depth_vec, PCL_RO_MIN);
197 if (red_fs_depth_vec.size () != fs_depth_vec.size () || red_well_depth_vec.size () != well_depth_vec.size ())
198 UG_THROW ("VertexWellRecharge: Failed to reduce the depth vectors.");
199 for (size_t well_i = 0; well_i < m_wells.size (); well_i++)
200 {
201 well_recharge_data_t& well = m_wells [well_i];
202 well.fs_depth = red_fs_depth_vec [well_i];
203 well.well_depth = red_well_depth_vec [well_i];
204 }
205#endif // UG_PARALLEL
206}
207
209template <typename TGridFunction>
211(
212 MathVector<dim> & x
213) const
214{
215// get the low-dimensional vector for x
216 MathVector<dim-1> xc;
217 for (size_t i = 0; i < dim-1; i++) xc[i] = x[i];
218
219// loop the wells
220 number sum = 0;
221 for (size_t well_i = 0; well_i < m_wells.size (); well_i++)
222 {
223 const well_recharge_data_t& well = m_wells [well_i];
224 number dist = VecDistance (xc, well.x);
225
226 if (dist > this->smooth_len ())
227 continue; // the well is too far away
228
229 // get the depth of the free surface at the well
230 number fs_depth = well.fs_depth;
231 if (fs_depth == - std::numeric_limits<number>::max ()) // this value should be set explicitly
232 continue; // the segment is not under the free surface; no contribution
233
234 // get the depth of the well
235 number well_depth = well.well_depth;
236 if (well_depth == std::numeric_limits<number>::max ()) // this value should be set explicitly
237 continue; // the segment is not under the top of the domain; no contribution
238
239 // add the contribution
240 number well_q = this->object_recharge (well_depth, fs_depth, this->m_width)
241 * cone_mollifier<this_type::mol_dim> (dist, this->smooth_len());
242 if (this->no_inflow () && well_q >= 0)
243 continue;
244 sum += well_q;
245 }
246
247 return sum;
248}
249
250template <typename TGridFunction>
258
259/*----- Class 'VertexRiverRecharge': -----*/
260
262template <typename TGridFunction>
264(
265 number riverWidth
266)
267{
268 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
269
270 Grid & riverGrid = m_spRiverNetwork->grid ();
271
272 EdgeConstIterator iterEnd = riverGrid.template end<Edge> ();
273 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
274 m_aaRiverWidth[*iter] = riverWidth;
275}
276
278template <typename TGridFunction>
280(
281 number riverWidth,
282 int ssi
283)
284{
285 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
286
287 const GridSubsetHandler& SH = m_spRiverNetwork->subset_handler ();
288
289// Loop the segments
290 EdgeConstIterator iterEnd = SH.template end<Edge> (ssi);
291 for (EdgeConstIterator iter = SH.template begin<Edge> (ssi); iter != iterEnd; ++iter)
292 m_aaRiverWidth[*iter] = riverWidth;
293}
294
296template <typename TGridFunction>
298(
299 number riverWidth,
300 const char * ss_name
301)
302{
303 const GridSubsetHandler& SH = m_spRiverNetwork->subset_handler ();
304 std::vector<std::string> names;
305
306 TokenizeTrimString (ss_name, names);
307
308 for (size_t i = 0; i < names.size (); i++)
309 {
310 const int ssi = SH.get_subset_index (names[i].c_str());
311 if (ssi < 0)
312 UG_THROW ("VertexRiverRecharge::set_river_width: no subset '" << names[i] << "' found in the river grid!");
313 set_river_width (riverWidth, ssi);
314 }
315}
316
318template <typename TGridFunction>
320{
321 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
322 Grid & riverGrid = m_spRiverNetwork->grid ();
323 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor ();
324
325 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
326 typedef Grid::traits<Vertex>::const_iterator VertConstIterator;
327
328 typedef Grid::VertexAttachmentAccessor<depth_attachment_type> nodal_depth_accessor_type;
329 depth_attachment_type aNodalFSDepth;
330 nodal_depth_accessor_type aaNodalFSDepth;
331 riverGrid.attach_to_vertices (aNodalFSDepth);
332 aaNodalFSDepth.access (riverGrid, aNodalFSDepth);
333
334// Prepare the object for a new level-set function
335 this->prepare_ls_height ();
336
337// Loop the river nodes
338 VertConstIterator vertIterEnd = riverGrid.template end<Vertex> ();
339 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
340 {
341 Vertex * vert = *vertIter;
342 aaNodalFSDepth[vert] = this->get_ls_height_at (river_vrt_pos_acc [vert]);
343 }
344
345#ifdef UG_PARALLEL
346// reduce the depths
348 std::vector<number> fs_depth_vec (riverGrid.num_vertices ());
349 size_t vert_i = 0;
350 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
351 fs_depth_vec [vert_i++] = aaNodalFSDepth [*vertIter];
352 std::vector<number> red_fs_depth_vec;
353 procComm.allreduce (fs_depth_vec, red_fs_depth_vec, PCL_RO_MAX);
354 if (red_fs_depth_vec.size () != fs_depth_vec.size ())
355 UG_THROW ("VertexRiverRecharge: Failed to reduce the free surface depth vector.");
356 vert_i = 0;
357 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
358 aaNodalFSDepth [*vertIter] = red_fs_depth_vec [vert_i++];
359#endif // UG_PARALLEL
360
361// Loop the segments
362 EdgeConstIterator iterEnd = riverGrid.template end<Edge> ();
363 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
364 {
365 Edge * seg = *iter;
366
367 // get the depths of the free surface at the ends of the segment
368 number fs_depth_1 = aaNodalFSDepth [seg->vertex (0)];
369 number fs_depth_2 = aaNodalFSDepth [seg->vertex (1)];
370
371 // check the validity
372 if (fs_depth_1 != - std::numeric_limits<number>::max () && fs_depth_2 != - std::numeric_limits<number>::max ())
373 m_aaFSDepth[seg] = (fs_depth_1 + fs_depth_2) / 2;
374 else // otherwise we skip the segment
375 m_aaFSDepth[seg] = - std::numeric_limits<number>::max ();
376 }
377
378 riverGrid.detach_from_vertices (aNodalFSDepth);
379}
380
382template <typename TGridFunction>
384{
385 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
386 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
387
388 Grid & riverGrid = m_spRiverNetwork->grid ();
389 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor ();
390
391// Prepare the object for a new level-set function
392 this->prepare_ls_height ();
393
394// Loop the segments
395 EdgeConstIterator iterEnd = riverGrid.template end<Edge> ();
396 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
397 {
398 Edge * seg = *iter;
399
400 // get the center of the segment
401 MathVector<dim-1> seg_center_c;
402 seg_center_c = river_vrt_pos_acc [seg->vertex (0)];
403 seg_center_c += river_vrt_pos_acc [seg->vertex (1)];
404 seg_center_c /= 2;
405
406 // get the depth of the free surface at the center
407 number fs_depth = this->get_ls_height_at (seg_center_c);
408 m_aaFSDepth[seg] = fs_depth;
409 }
410
411#ifdef UG_PARALLEL
412// reduce the depths
414 std::vector<number> fs_depth_vec (riverGrid.num_edges ());
415 size_t seg_i = 0;
416 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
417 fs_depth_vec [seg_i++] = m_aaFSDepth [*iter];
418 std::vector<number> red_fs_depth_vec;
419 procComm.allreduce (fs_depth_vec, red_fs_depth_vec, PCL_RO_MAX);
420 if (red_fs_depth_vec.size () != fs_depth_vec.size ())
421 UG_THROW ("VertexRiverRecharge: Failed to reduce the free surface depth vector.");
422 seg_i = 0;
423 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
424 m_aaFSDepth [*iter] = red_fs_depth_vec [seg_i++];
425#endif // UG_PARALLEL
426}
427
429template <typename TGridFunction>
431{
432 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
433 typedef SegmentNetwork::gauge_accessor_t river_depth_acc_t;
434 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
435
436 Grid & riverGrid = m_spRiverNetwork->grid ();
437 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor ();
438 river_depth_acc_t river_vrt_depth_acc = river_network()->gauge_accessor ();
439
440// Compute the depth of the free surface
441 if (m_bNodalFSDepth)
442 this->compute_fs_depths_at_nodes ();
443 else
444 this->compute_fs_depths_at_segments ();
445
446// Loop the segments
447 EdgeConstIterator iterEnd = riverGrid.template end<Edge> ();
448 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
449 {
450 Edge * seg = *iter;
451
452 // get the data at the ends of the segment
453
454 Vertex * vrt_0 = seg->vertex (0);
455 number depth_0 = river_vrt_depth_acc[vrt_0];
456
457 Vertex * vrt_1 = seg->vertex (1);
458 number depth_1 = river_vrt_depth_acc[vrt_1];
459
460 number seg_depth = (depth_0 + depth_1) / 2;
461
462 // take into the account the actual top
463 if (this->ls_depth_is_relative ())
464 {
465 // get the data at the center
466 MathVector<dim-1> pos_0 = river_vrt_pos_acc[vrt_0];
467 MathVector<dim-1> pos_1 = river_vrt_pos_acc[vrt_1];
468 MathVector<dim-1> seg_center_c;
469 seg_center_c = pos_0; seg_center_c += pos_1; seg_center_c /= 2;
470
471 // get the height of the "top of the domain" over this segment
472 number top_depth;
473 if (this->min_top_depth (seg_center_c, top_depth) == 0)
474 {
475 m_aaRiverDepth[seg] = std::numeric_limits<number>::max (); // the segment is not covered by the top
476 continue; // skip the computation of the river depth for this segment
477 }
478 // correct the depth of the river for this segment
479 seg_depth += top_depth;
480 }
481
482 // restrict the depth of the river
483 number fs_depth = m_aaFSDepth[seg];
484 if (this->restrict_depth () && fs_depth != - std::numeric_limits<number>::max ()
485 && seg_depth < fs_depth - this->max_depth_diff ())
486 seg_depth = fs_depth - this->max_depth_diff ();
487
488 // set the river depth for the segment
489 m_aaRiverDepth[seg] = seg_depth;
490 }
491
492#ifdef UG_PARALLEL
493// reduce the depths
495 std::vector<number> river_depth_vec (riverGrid.num_edges ());
496 size_t seg_i = 0;
497 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
498 river_depth_vec [seg_i++] = m_aaRiverDepth [*iter];
499 std::vector<number> red_river_depth_vec;
500 procComm.allreduce (river_depth_vec, red_river_depth_vec, PCL_RO_MIN);
501 if (red_river_depth_vec.size () != river_depth_vec.size ())
502 UG_THROW ("VertexRiverRecharge: Failed to reduce the river depth vector.");
503 seg_i = 0;
504 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
505 m_aaRiverDepth [*iter] = red_river_depth_vec [seg_i++];
506#endif // UG_PARALLEL
507
508// check the depths
509 if (m_bCheckTopCovering)
510 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
511 {
512 Edge * seg = *iter;
513 if (m_aaRiverDepth [seg] == std::numeric_limits<number>::max ())
514 UG_THROW ("VertexRiverRecharge: River segment ["
515 << river_vrt_pos_acc[seg->vertex(0)] << ", " << river_vrt_pos_acc[seg->vertex(1)]
516 << "] is not (completely) covered by the top subset.");
517 }
518 if (m_bCheckFSCovering)
519 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
520 {
521 Edge * seg = *iter;
522 if (m_aaRiverDepth [seg] != std::numeric_limits<number>::max ()
523 && m_aaFSDepth [seg] == - std::numeric_limits<number>::max ())
524 UG_THROW ("VertexRiverRecharge: River segment ["
525 << river_vrt_pos_acc[seg->vertex(0)] << ", " << river_vrt_pos_acc[seg->vertex(1)]
526 << "] is not (completely) covered by the free surface.");
527 }
528
529// print the total recharge
530 if (m_bPrintTotalRecharge)
531 do_print_total_recharge ();
532}
533
535template <typename TGridFunction>
537{
538 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
539 typedef SegmentNetwork::gauge_accessor_t river_depth_acc_t;
540 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
541
542 Grid & riverGrid = m_spRiverNetwork->grid ();
543 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor ();
544 number total_recharge = 0;
545
546 EdgeConstIterator iterEnd = riverGrid.template end<Edge> ();
547 for (EdgeConstIterator iter = riverGrid.template begin<Edge> (); iter != iterEnd; ++iter)
548 {
549 Edge * seg = *iter;
550
551 // get the length of the segment
552 MathVector<dim-1> pos_0 = river_vrt_pos_acc[seg->vertex (0)];
553 MathVector<dim-1> pos_1 = river_vrt_pos_acc[seg->vertex (1)];
554 number seg_length = VecDistance (pos_0, pos_1);
555
556 // get the depth of the free surface at the center
557 number fs_depth = fs_depth_for (seg);
558 if (fs_depth == - std::numeric_limits<number>::max ()) // this value should be set explicitly
559 continue; // the segment is not under the free surface; no contribution
560
561 // get the depth of the river
562 number seg_depth = river_depth_for (seg);
563 if (seg_depth == std::numeric_limits<number>::max ()) // this value should be set explicitly
564 continue; // the segment is not under the top of the domain; no contribution
565
566 number seg_recharge = this->object_recharge (seg_depth, fs_depth, river_width_for (seg));
567 if (this->no_inflow () && seg_recharge >= 0)
568 continue;
569
570 total_recharge += seg_recharge * seg_length;
571 }
572 UG_LOG ("----> Total contribution by the rivers: " << total_recharge << '\n');
573
574 if (! m_sTotalRechargeFile.empty ())
575 {
576# ifdef UG_PARALLEL
577 pcl::ProcessCommunicator proc_comm;
578 if (pcl::ProcRank () != proc_comm.get_proc_id (0))
579 return; // only the master process should print
580# endif
581 std::ofstream output (m_sTotalRechargeFile.c_str (), std::ofstream::app);
582 UG_COND_THROW (output.fail (), "VertexRiverRecharge: Cannot open data file '" << m_sTotalRechargeFile << "' for output!");
583 output << m_sOutputPrefix << ' ' << total_recharge << '\n';
584 }
585}
586
588template <typename TGridFunction>
590(
591 MathVector<dim> & x
592) const
593{
594 typedef Grid::traits<Edge>::const_iterator edge_iter_t;
595 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
596
597 Grid & riverGrid = river_network()->grid ();
598 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor ();
599
600// get the low-dimensional vector for x
601 MathVector<dim-1> xc;
602 for (size_t i = 0; i < dim-1; i++) xc[i] = x[i];
603
604// loop the segments of the river grid
605 number sum = 0;
606 for (edge_iter_t s_iter = riverGrid.begin<Edge>(); s_iter != riverGrid.end<Edge>(); ++s_iter)
607 {
608 Edge * seg = *s_iter;
609
610 // get the the center and the distance to the center
611
612 Vertex * vrt_0 = seg->vertex (0);
613 MathVector<dim-1> pos_0 = river_vrt_pos_acc[vrt_0];
614
615 Vertex * vrt_1 = seg->vertex (1);
616 MathVector<dim-1> pos_1 = river_vrt_pos_acc[vrt_1];
617
618 MathVector<dim-1> seg_center_c;
619 seg_center_c = pos_0; seg_center_c += pos_1; seg_center_c /= 2;
620
621 number dist = VecDistance (xc, seg_center_c);
622 if (dist >= this->smooth_len ())
623 continue; // this segment is too far, we skip it! (Note that this imposes some assumptions to the mollifier.)
624
625 number seg_length = VecDistance (pos_0, pos_1);
626
627 // get the depth of the free surface at the center
628 number fs_depth = fs_depth_for (seg);
629 if (fs_depth == - std::numeric_limits<number>::max ()) // this value should be set explicitly
630 continue; // the segment is not under the free surface; no contribution
631
632 // get the depth of the river
633 number seg_depth = river_depth_for (seg);
634 if (seg_depth == std::numeric_limits<number>::max ()) // this value should be set explicitly
635 continue; // the segment is not under the top of the domain; no contribution
636
637 // add the contribution
638 number river_q = this->object_recharge (seg_depth, fs_depth, river_width_for (seg))
639 * cone_mollifier<this_type::mol_dim> (dist, this->smooth_len()) * seg_length;
640 if (this->no_inflow () && river_q >= 0)
641 continue;
642 sum += river_q;
643 }
644
645 return sum;
646}
647
649template <typename TGridFunction>
651{
652 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
653 typedef SegmentNetwork::gauge_accessor_t river_depth_acc_t;
654 Grid & riverGrid = m_spRiverNetwork->grid ();
655 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor ();
656 river_depth_acc_t river_vrt_depth_acc = river_network()->gauge_accessor ();
657
658 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
659 typedef Grid::traits<Vertex>::const_iterator VertConstIterator;
660
661 typedef Grid::VertexAttachmentAccessor<depth_attachment_type> nodal_depth_accessor_type;
662 depth_attachment_type aNodalFSDepth;
663 nodal_depth_accessor_type aaNodalFSDepth;
664 riverGrid.attach_to_vertices (aNodalFSDepth);
665 aaNodalFSDepth.access (riverGrid, aNodalFSDepth);
666
667// Prepare the object for a new level-set function
668 this->prepare_ls_height ();
669
670// Loop the river nodes
671 VertConstIterator vertIterEnd = riverGrid.template end<Vertex> ();
672 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
673 {
674 Vertex * vert = *vertIter;
675 aaNodalFSDepth[vert] = this->get_ls_height_at (river_vrt_pos_acc [vert]);
676 }
677
678#ifdef UG_PARALLEL
679// reduce the depths
681 std::vector<number> fs_depth_vec (riverGrid.num_vertices ());
682 size_t vert_i = 0;
683 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
684 fs_depth_vec [vert_i++] = aaNodalFSDepth [*vertIter];
685 std::vector<number> red_fs_depth_vec;
686 procComm.allreduce (fs_depth_vec, red_fs_depth_vec, PCL_RO_MAX);
687 if (red_fs_depth_vec.size () != fs_depth_vec.size ())
688 UG_THROW ("VertexRiverRecharge: Failed to reduce the free surface depth vector.");
689 vert_i = 0;
690 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
691 aaNodalFSDepth [*vertIter] = red_fs_depth_vec [vert_i++];
692#endif // UG_PARALLEL
693
694// Write the depth back to the rivers
695 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
696 {
697 number depth = aaNodalFSDepth [*vertIter];
698 if (depth != - std::numeric_limits<number>::max ()) // if the vertex is not covered by the FS, do not reset the orig. depth
699 river_vrt_depth_acc[*vertIter] = depth;
700 }
701
702 riverGrid.detach_from_vertices (aNodalFSDepth);
703}
704
706template <typename TGridFunction>
708(
709 const char * file_name
710)
711{
712 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
713 typedef SegmentNetwork::gauge_accessor_t river_depth_acc_t;
714 Grid & riverGrid = m_spRiverNetwork->grid ();
715 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor ();
716 river_depth_acc_t river_vrt_depth_acc = river_network()->gauge_accessor ();
717
718 typedef Grid::traits<Edge>::const_iterator EdgeConstIterator;
719 typedef Grid::traits<Vertex>::const_iterator VertConstIterator;
720
721 typedef Grid::VertexAttachmentAccessor<depth_attachment_type> nodal_depth_accessor_type;
722 depth_attachment_type aNodalFSDepth;
723 nodal_depth_accessor_type aaNodalFSDepth;
724 riverGrid.attach_to_vertices (aNodalFSDepth);
725 aaNodalFSDepth.access (riverGrid, aNodalFSDepth);
726
727// Prepare the object for a new level-set function
728 this->prepare_ls_height ();
729
730// Loop the river nodes
731 VertConstIterator vertIterEnd = riverGrid.template end<Vertex> ();
732 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
733 {
734 Vertex * vert = *vertIter;
735 aaNodalFSDepth[vert] = this->get_ls_height_at (river_vrt_pos_acc [vert]);
736 }
737
738#ifdef UG_PARALLEL
739// reduce the depths
741 std::vector<number> fs_depth_vec (riverGrid.num_vertices ());
742 size_t vert_i = 0;
743 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
744 fs_depth_vec [vert_i++] = aaNodalFSDepth [*vertIter];
745 std::vector<number> red_fs_depth_vec;
746 procComm.allreduce (fs_depth_vec, red_fs_depth_vec, PCL_RO_MAX);
747 if (red_fs_depth_vec.size () != fs_depth_vec.size ())
748 UG_THROW ("VertexRiverRecharge: Failed to reduce the free surface depth vector.");
749 vert_i = 0;
750 for (VertConstIterator vertIter = riverGrid.template begin<Vertex> (); vertIter != vertIterEnd; ++vertIter)
751 aaNodalFSDepth [*vertIter] = red_fs_depth_vec [vert_i++];
752#endif // UG_PARALLEL
753
754// Save the file
755 m_spRiverNetwork->save_to_file_with_ (aaNodalFSDepth, file_name);
756
757 riverGrid.detach_from_vertices (aNodalFSDepth);
758}
759
760template <typename TGridFunction>
762(
763 MathVector<dim> & x
764) const
765{
766 typedef SegmentNetwork::position_accessor_t river_vrt_pos_acc_t;
767 typedef SegmentNetwork::gauge_accessor_t river_depth_acc_t;
768 typedef Grid::traits<Edge>::const_iterator edge_iter_t;
769
770 Grid & riverGrid = river_network()->grid ();
771 river_vrt_pos_acc_t river_vrt_pos_acc = river_network()->position_accessor();
772 river_depth_acc_t river_vrt_depth_acc = river_network()->gauge_accessor();
773
774// get the low-dimensional vector for x
775 MathVector<dim-1> xc;
776 for (size_t i = 0; i < dim-1; i++) xc[i] = x[i];
777
778
779 // loop the segments of the river grid
780 number sum = 0;
781 for (edge_iter_t s_iter = riverGrid.begin<Edge>(); s_iter != riverGrid.end<Edge>(); ++s_iter)
782 {
783 Edge * seg = *s_iter;
784
785 // get the the center and the distance to the center
786
787 Vertex * vrt_0 = seg->vertex (0);
788 MathVector<dim-1> pos_0 = river_vrt_pos_acc[vrt_0];
789 number depth_0 = river_vrt_depth_acc[vrt_0];
790
791 Vertex * vrt_1 = seg->vertex (1);
792 MathVector<dim-1> pos_1 = river_vrt_pos_acc[vrt_1];
793 number depth_1 = river_vrt_depth_acc[vrt_1];
794
795 MathVector<dim-1> seg_center_c;
796 seg_center_c = pos_0; seg_center_c += pos_1; seg_center_c *= 0.5;
797
798 number dist = VecDistance (xc, seg_center_c);
799 if (dist >= this->smooth_len ())
800 continue; // this segment is too far, we skip it! (Note that this imposes some assumptions to the mollifier.)
801
802 number seg_length = VecDistance (pos_0, pos_1);
803 number seg_depth = (depth_0 + depth_1)*0.5;
804
805 // add the contribution
806 number river_q = seg_depth * cone_mollifier<this_type::mol_dim> (dist, this->smooth_len()) * seg_length * 0.5;
807 // this->object_recharge (seg_depth, fs_depth)
808 if (this->no_inflow () && river_q >= 0) continue;
809
810 sum += river_q;
811 }
812
813 return sum;
814}
815
816} // namespace d3f
817} // end namespace ug
818
819/* End of File */
size_t allreduce(const size_t &t, pcl::ReduceOperation op) const
int get_proc_id(size_t index) const
virtual Vertex * vertex(size_t index) const
void attach_to_vertices(IAttachment &attachment)
size_t num_vertices() const
void detach_from_vertices(IAttachment &attachment)
geometry_traits< TGeomObj >::iterator begin()
size_t num_edges() const
geometry_traits< TGeomObj >::iterator end()
int get_subset_index(const char *name) const
bool has_children(TElem *elem) const
geometry_traits< TElem >::iterator end(int subsetIndex, int level)
geometry_traits< TElem >::iterator begin(int subsetIndex, int level)
void add(const char *name)
size_t size() const
TGridFunction::domain_type domain_type
type of the domain
Definition rivers.h:91
void simple_compute(SmartPtr< grid_func_type > spRecharge)
computes the recharge at the vertices
Definition rivers_impl.h:95
void set_relative_to(const char *subsetNames, number top_tolerance, int top_grid_level)
specifyes the subsets of the top
Definition rivers_impl.h:29
grid_dim_traits< dim >::side_type g_surf_elem_t
type of the elements constituting surfaces in the grid
Definition rivers.h:106
geometry_traits< g_surf_elem_t >::iterator g_surf_iter_t
type of the iterator of the grid surface elements
Definition rivers.h:109
void compute(SmartPtr< grid_func_type > spRecharge)
computes the recharge at the vertices
Definition rivers_impl.h:119
size_t get_top_z(const MathVector< dim > &over)
get the intersection with the top
Definition rivers_impl.h:72
void save_river_depth(const char *file_name)
save the river network with the fs depth in a file
Definition rivers_impl.h:708
void do_print_total_recharge()
prints the total recharge
Definition rivers_impl.h:536
void compute_fs_depths_at_nodes()
computes the depths of the free surface at the nodes of the river vertices
Definition rivers_impl.h:319
void set_river_width(number riverWidth)
sets river width for all segments
Definition rivers_impl.h:264
virtual number smoothed_recharge_at(MathVector< dim > &x) const
computes the smoothed recharge at a given point
Definition rivers_impl.h:590
virtual number simple_smoothed_recharge_at(MathVector< dim > &x) const
computes the smoothed recharge at a given point neglecting the depths, width etc.
Definition rivers_impl.h:762
void reset_river_depth()
set the river depth from the fs depth
Definition rivers_impl.h:650
void compute_fs_depths_at_segments()
computes the depths of the free surface at the centers of the river segments
Definition rivers_impl.h:383
virtual void compute_depths()
fills the attachment with the depths of the free surface
Definition rivers_impl.h:430
virtual void compute_depths()
fills the attachment with the depths of the free surface
Definition rivers_impl.h:147
virtual number smoothed_recharge_at(MathVector< dim > &x) const
computes the smoothed recharge at a given point
Definition rivers_impl.h:211
virtual number simple_smoothed_recharge_at(MathVector< dim > &x) const
computes the smoothed recharge at a given point
Definition rivers_impl.h:252
int ProcRank()
#define PCL_RO_MAX
#define PCL_RO_MIN
vector< string > TokenizeString(const char *str, const char delimiter=',')
UG_API std::vector< std::string > TokenizeTrimString(const std::string &str, const char delimiter=',')
#define UG_THROW(msg)
#define UG_LOG(msg)
#define UG_COND_THROW(cond, msg)
double number
vector_t PointOnRay(const vector_t &from, const vector_t &dir, number s)
vector_t::value_type VecDistance(const vector_t &v1, const vector_t &v2)
bool RayElementIntersections(std::vector< RayElemIntersectionRecord< typename tree_t::elem_t > > &intersectionsOut, const tree_t &tree, const typename tree_t::vector_t &rayFrom, const typename tree_t::vector_t &rayDir, const number small=1.e-12)
const number & DoFRef(const TMatrix &mat, const DoFIndex &iInd, const DoFIndex &jInd)
geometry_traits< TElem >::const_iterator const_iterator
data of a recharge well
Definition rivers.h:356
MathVector< dim-1 > x
coordinates of the well
Definition rivers.h:357
number well_depth
effective level of the well
Definition rivers.h:361
number well_depth_spec
level of the well as specified
Definition rivers.h:358
number fs_depth
depth of the free surface at the well (computed)
Definition rivers.h:360
#define for_each_in_vec(_vfeDecl, _vfeVec)
#define end_for