Loading...
Searching...
No Matches
CG_algorithms.cpp
1// ========================================================================== //
2// - COMPUTATIONAL GEOMETRY PACKAGE - //
3// //
4// Routines for computational geometry. //
5// ========================================================================== //
6// INFO //
7// ========================================================================== //
8// Author : Alessandro Alaia //
9// Version : v1.0 //
10// //
11// All rights reserved. //
12// ========================================================================== //
13
14// ========================================================================== //
15// INCLUDES //
16// ========================================================================== //
17# include "CG.hpp"
18
19// bitpit library
20# include "bitpit_common.hpp"
21# include "bitpit_SA.hpp"
22
23// ========================================================================== //
24// IMPLEMENTATIONS //
25// ========================================================================== //
26
27namespace bitpit {
28
29namespace CGAlgorithms{
30
31// -------------------------------------------------------------------------- //
32double grad1DUpdate(
33 int nSimplex,
34 std::vector<std::array<double,3>> &Vertex,
35 std::vector<std::vector<int>> &Simplex,
36 std::vector<std::vector<std::vector<int>>> &Adjacency,
37 std::vector<double> &val,
38 int T,
39 int i,
40 double g,
41 std::vector<bool> &flag
42) {
43
44// ========================================================================== //
45// double grad1DUpdate( //
46// int nSimplex, //
47// dvector2D &Vertex, //
48// std::vector<std::vector<int>> &Simplex, //
49// std::vector<std::vector<std::vector<int>>> &Adjacency, //
50// std::vector<double> &val, //
51// int T, //
52// int i, //
53// double g, //
54// std::vector<bool> &flag) //
55// //
56// Compute local solution to the 1D gradient limiting equation on a //
57// 1D manifold in a 2D Euclidean space. //
58// ========================================================================== //
59// INPUT //
60// ========================================================================== //
61// - nSimplex : int, number of simplicies //
62// - Vertex : std::vector<double>, vertex coordinate list. Vertex[i][0], //
63// Vertex[i][1] are the x, y, coordinates of the i-th vertex //
64// - Simplex : std::vector<std::vector<int>>, simplex-vertex connectivity. Simplex[i][0] and //
65// Simplex[i][1] are the global indices of vertices of the i-th //
66// segment. //
67// - Adjacency : std::vector<std::vector<std::vector<int>>>, simplex-simplex adjacency. Adjacency[i][j] stores //
68// the global indices of all simplicies adjacenct to the i-th //
69// simplex at vertex Simplex[i][j]. //
70// - val : std::vector<double>, scalar field at each mesh vertex //
71// - T : int, simplex global index //
72// - i : int, vertex local index //
73// - g : double, max slope //
74// - flag : std::vector<bool> with flag for dead (flag = false), and alive //
75// (flag = true) vertexes. //
76// ========================================================================== //
77// OUTPUT //
78// ========================================================================== //
79// - value : solution to the 1D gradient limiting equation //
80// ========================================================================== //
81
82BITPIT_UNUSED(nSimplex);
83
84// ========================================================================== //
85// VARIABLES DECLARATION //
86// ========================================================================== //
87
88// Local variables
89double value = 1.0e+18, value_0 = 1.0e+18;
90std::array<double,3> P0;
91P0.fill(0.0) ;
92
93// Counters
94int A, V, W, j, k, m;
95
96// ========================================================================== //
97// COMPUTE THE LOCAL SOLUTION TO THE 1D GRADIENT LIMITING EQUATION //
98// ========================================================================== //
99
100// Vertex global index ------------------------------------------------------ //
101V = Simplex[T][i];
102
103// Find dead neighboors ----------------------------------------------------- //
104W = Simplex[T][(i+1) % Simplex[T].size()];
105if (!flag[W]) {
106 value_0 = val[W];
107 P0 = Vertex[W];
108 value = std::min(value, value_0 + g * norm2(Vertex[V] - P0));
109}
110if (Adjacency[T][i][0] >= 0) {
111 m = Adjacency[T][i].size();
112 for (k = 0; k < m; k++) {
113 A = Adjacency[T][i][k];
114 j = 0;
115 if (Simplex[A][0] == V) { j = 1; }
116 W = Simplex[A][j];
117
118 if (!flag[W]) {
119 value_0 = val[W];
120 P0 = Vertex[W];
121 value = std::min(value, value_0 + g * norm2(Vertex[V] - P0));
122 }
123 } //next k
124}
125
126// Solve 1D grad limiting equation ------------------------------------------ //
127value = std::min(val[V], value);
128
129return(value); }
130
131// -------------------------------------------------------------------------- //
132void gradLimiting1D(
133 int nSimplex,
134 std::vector<std::array<double,3>> &Vertex,
135 std::vector<std::vector<int>> &Simplex,
136 std::vector<std::vector<std::vector<int>>> &Adjacency,
137 std::vector<double> &val,
138 double g
139) {
140
141// ========================================================================== //
142// void gradLimiting1D( //
143// int nSimplex, //
144// dvector2D &Vertex, //
145// std::vector<std::vector<int>> &Simplex, //
146// std::vector<std::vector<std::vector<int>>> &Adjacency, //
147// std::vector<double> &val, //
148// double g) //
149// //
150// Solve the 1D gradient limiting equation onto a 1D manifold in a 2D , //
151// Euclidean space, using fast marching method. //
152// ========================================================================== //
153// INPUT //
154// ========================================================================== //
155// - nSimplex : int, number of simplicies //
156// - Vertex : std::vector<double>, vertex coordinate list. Vertex[i][0], //
157// Vertex[i][1] are the x, y, coordinates of the i-th vertex //
158// - Simplex : std::vector<std::vector<int>>, simplex-vertex connectivity. Simplex[i][0] and //
159// Simplex[i][1] are the global indices of vertices of the i-th //
160// segment. //
161// - Adjacency : std::vector<std::vector<std::vector<int>>>, simplex-simplex adjacency. Adjacency[i][j] stores //
162// the global indices of all simplicies adjacenct to the i-th //
163// simplex at vertex Simplex[i][j]. //
164// - val : std::vector<double>, with scalar field to be limited. //
165// - g : double, max slope value. //
166// ========================================================================== //
167// OUTPUT //
168// ========================================================================== //
169// - none //
170// ========================================================================== //
171
172// ========================================================================== //
173// VARIABLES DECLARATION //
174// ========================================================================== //
175
176// Local variables
177int nVertex = Vertex.size();
178double ddummy;
179std::vector<bool> inserted(nVertex, false);
180std::vector<int> idummy1D(2, -1);
181// array<int,2> idummy1D;
182// std::vector<std::vector<int>> map(nVertex, std::vector<int>(2, -1)), *map_ = &map;
183std::vector< std::array<int,2> > map(nVertex), *map_ = &map;
184bitpit::MinPQueue<double, std::vector<int>> heap(nVertex, true, map_);
185
186// Counters
187int i, j, k;
188int T, V, A, W;
189int m;
190
191for (V = 0; V < nVertex; V++) {
192 map[V].fill(0) ;
193};
194
195// ========================================================================== //
196// BUILD MIN HEAP //
197// ========================================================================== //
198
199// Initialize data structure for min heap ----------------------------------- //
200k = 0;
201for (T = 0; T < nSimplex; T++) {
202 m = Simplex[T].size();
203 for (i = 0; i < m; i++) {
204 V = Simplex[T][i];
205 if (!inserted[V]) {
206
207 // Update mapper
208 map[k][0] = V;
209 map[V][1] = k;
210
211 // Insert vertex into min-heap
212 idummy1D[0] = T;
213 idummy1D[1] = i;
214 heap.insert(val[V], idummy1D);
215
216 // Update flag & counters
217 k++;
218 inserted[V] = true;
219 }
220 } //next i
221} //next T
222
223// ========================================================================== //
224// FAST GRADIENT LIMITING //
225// ========================================================================== //
226while (heap.heap_size > 0) {
227
228 // Extract root from min heap
229 heap.extract(ddummy, idummy1D);
230
231 // Update value for extracted item
232 T = idummy1D[0];
233 i = idummy1D[1];
234 V = Simplex[T][i];
235 inserted[V] = false;
236
237 // Update value for neighbors
238 j = (i + 1) % Simplex[T].size();
239 W = Simplex[T][j];
240 if (inserted[W]) {
241 val[W] = grad1DUpdate(nSimplex, Vertex, Simplex, Adjacency, val, T, j, g, inserted);
242 idummy1D[0] = T;
243 idummy1D[1] = j;
244 }
245 if (Adjacency[T][i][0] >= 0) {
246 m = Adjacency[T][i].size();
247 for (k = 0; k < m; k++) {
248 A = Adjacency[T][i][k];
249 j = 0;
250 if (Simplex[A][0] == V) { j = 1; }
251 W = Simplex[A][j];
252 if (inserted[W]) {
253 val[W] = grad1DUpdate(nSimplex, Vertex, Simplex, Adjacency, val, A, j, g, inserted);
254 idummy1D[0] = A;
255 idummy1D[1] = j;
256 heap.modify(map[W][1], val[W], idummy1D);
257 }
258 } //next k
259 }
260} //next item
261
262}
263
264// -------------------------------------------------------------------------- //
265double grad2DUpdate(
266 int nSimplex,
267 std::vector<std::array<double,3>> &Vertex,
268 std::vector<std::vector<int>> &Simplex,
269 std::vector<std::vector<std::vector<int>>> &ring_1,
270 std::vector<double> &val,
271 int T,
272 int i,
273 double g,
274 std::vector<bool> &flag
275) {
276
277// ========================================================================== //
278// double grad2DUpdate( //
279// int nSimplex, //
280// dvector2D &Vertex, //
281// std::vector<std::vector<int>> &Simplex, //
282// std::vector<std::vector<std::vector<int>>> &ring_1, //
283// std::vector<double> &val, //
284// int T, //
285// int i, //
286// double g, //
287// std::vector<bool> &flag) //
288// //
289// Compute local solution to the 2D gradient limiting equation on a //
290// 2D manifold in a 3D Euclidean space. //
291// ========================================================================== //
292// INPUT //
293// ========================================================================== //
294// - nSimplex : int, number of simplicies in the surface tasselation //
295// - Vertex : std::vector<double>, vertex coordinate list. Vertex[i][0], //
296// Vertex[i][1], ... are the x, y, ... coordinates of the i-th //
297// vertex //
298// - Simplex : std::vector<std::vector<int>>, simplex-vertex connectivity. Simplex[i][0] and //
299// Simplex[i][1] are the global indices of vertices of the i-th //
300// segment. //
301// - ring_1 : std::vector<std::vector<std::vector<int>>>, 1-ring of simplcies for each vertex. //
302// - val : std::vector<double>, scalar field at each mesh vertex //
303// - T : int, simplex global index //
304// - i : int, vertex local index //
305// - g : double, max slope //
306// - flag : std::vector<bool> with flag for dead (flag = false), and alive //
307// (flag = true) vertexes. //
308// ========================================================================== //
309// OUTPUT //
310// ========================================================================== //
311// - value : solution to the 1D gradient limiting equation //
312// ========================================================================== //
313
314BITPIT_UNUSED(nSimplex);
315
316// ========================================================================== //
317// VARIABLES DECLARATION //
318// ========================================================================== //
319
320// Local variables
321double value = 1.0e+18;
322
323// Counters
324size_t j;
325int A, V, W, k, m;
326
327// ========================================================================== //
328// COMPUTE THE LOCAL SOLUTION TO THE 1D GRADIENT LIMITING EQUATION //
329// ========================================================================== //
330
331// Vertex global index ------------------------------------------------------ //
332V = Simplex[T][i];
333
334// Find dead neighboors ----------------------------------------------------- //
335for (j = 0; j < ring_1[V].size(); ++j) {
336 A = ring_1[V][j][0];
337 k = ring_1[V][j][1];
338 m = (k - 1 + Simplex[A].size()) % Simplex[A].size();
339 W = Simplex[A][m];
340 if (!flag[W]) {
341 value = std::min(value, val[W] + g * norm2(Vertex[V] - Vertex[W]));
342 }
343 m = (k + 1) % Simplex[A].size();
344 W = Simplex[A][m];
345 if (!flag[W]) {
346 value = std::min(value, val[W] + g * norm2(Vertex[V] - Vertex[W]));
347 }
348} //next j
349
350// Solve 1D grad limiting equation ------------------------------------------ //
351value = std::min(val[V], value);
352
353return(value); }
354
355// -------------------------------------------------------------------------- //
356void gradLimiting2D(
357 int nSimplex,
358 std::vector<std::array<double,3>> &Vertex,
359 std::vector<std::vector<int>> &Simplex,
360 std::vector<double> &val,
361 double g
362) {
363
364// ========================================================================== //
365// void gradLimiting2D( //
366// int nSimplex, //
367// dvector2D &Vertex, //
368// std::vector<std::vector<int>> &Simplex, //
369// std::vector<double> &val, //
370// double g) //
371// //
372// Solve the 2D grad-limiting equation, using a fast marching method over //
373// a 2D manifold immersed in a 3D Euclidean space. //
374// ========================================================================== //
375// INPUT //
376// ========================================================================== //
377// - nSimplex : int, number of simplicies in surface tasselation //
378// - Vertex : dvector2D, vertex coordinate list. Vertex[i][0], //
379// Vertex[i][1], ... are the x, y, ... coordinates of the //
380// i-th vertex //
381// - Simplex : std::vector<std::vector<int>>, simplex-vertex connectivity //
382// - val : std::vector<double>, field to be smoothed //
383// - g : double, max gradient. //
384// ========================================================================== //
385// OUTPUT //
386// ========================================================================== //
387// - none //
388// ========================================================================== //
389
390// ========================================================================== //
391// VARIABLES DECLARATION //
392// ========================================================================== //
393
394// // Local variables
395int nVertex = Vertex.size();
396double ddummy;
397std::vector<bool> inserted(nVertex, false);
398std::vector<int> idummy1D(2, -1);
399std::vector<std::vector<std::vector<int>>> Ring1(nVertex);
400std::vector< std::array<int,2> > map(nVertex), *map_ = &map;
401bitpit::MinPQueue<double, std::vector<int>> heap(nVertex, true, map_);
402
403// // Counters
404size_t j;
405int i, k;
406int T, V, A, W;
407int m;
408
409for (V = 0; V < nVertex; V++) {
410 map[V].fill(0) ;
411};
412
413// ========================================================================== //
414// BUILD 1-RING OF VERTICES //
415// ========================================================================== //
416for (T = 0; T < nSimplex; T++) {
417 m = Simplex[T].size();
418 for (i = 0; i < m; ++i) {
419 V = Simplex[T][i];
420 idummy1D[0] = T;
421 idummy1D[1] = i;
422 Ring1[V].push_back(idummy1D);
423 } //next i
424} //next T
425
426// ========================================================================== //
427// BUILD MIN HEAP //
428// ========================================================================== //
429
430// Initialize data structure for min heap ----------------------------------- //
431k = 0;
432for (T = 0; T < nSimplex; T++) {
433 m = Simplex[T].size();
434 for (i = 0; i < m; i++) {
435 V = Simplex[T][i];
436 if (!inserted[V]) {
437
438 // Update mapper
439 map[k][0] = V;
440 map[V][1] = k;
441
442 // Insert vertex into min-heap
443 idummy1D[0] = T;
444 idummy1D[1] = i;
445 heap.insert(val[V], idummy1D);
446
447 // Update flag & counters
448 k++;
449 inserted[V] = true;
450 }
451 } //next i
452} //next T
453
454// ========================================================================== //
455// FAST GRADIENT LIMITING //
456// ========================================================================== //
457while (heap.heap_size > 0) {
458
459 // Extract root from min heap
460 heap.extract(ddummy, idummy1D);
461
462 // Update value for extracted item
463 T = idummy1D[0];
464 i = idummy1D[1];
465 V = Simplex[T][i];
466 inserted[V] = false;
467
468 // Update value for neighboring vertices
469 for (j = 0; j < Ring1[V].size(); ++j) {
470 A = Ring1[V][j][0];
471 k = Ring1[V][j][1];
472 m = (k - 1 + Simplex[A].size()) % Simplex[A].size();
473 W = Simplex[A][m];
474 if (inserted[W]) {
475 val[W] = grad2DUpdate(nSimplex, Vertex, Simplex, Ring1, val, A, m, g, inserted);
476 idummy1D[0] = A;
477 idummy1D[1] = m;
478 heap.modify(map[W][1], val[W], idummy1D);
479 };
480 m = (k + 1) % Simplex[A].size();
481 W = Simplex[A][m];
482 if (inserted[W]) {
483 val[W] = grad2DUpdate(nSimplex, Vertex, Simplex, Ring1, val, A, m, g, inserted);
484 idummy1D[0] = A;
485 idummy1D[1] = m;
486 heap.modify(map[W][1], val[W], idummy1D);
487 }
488 } //next j
489} //next item
490
491}
492
493// -------------------------------------------------------------------------- //
494double grad2DUpdate(
495 int nSimplex,
496 std::vector<std::array<double,3>> &Vertex,
497 std::vector<std::vector<int>> &Simplex,
498 std::vector<std::vector<int>> &Adjacency,
499 std::vector<double> &val,
500 int T,
501 double g,
502 std::vector<bool> &flag
503) {
504
505// ========================================================================== //
506// double grad2DUpdate( //
507// int nSimplex, //
508// dvector2D &Vertex, //
509// std::vector<std::vector<int>> &Simplex, //
510// std::vector<std::vector<int>> &Adjacency, //
511// std::vector<double> &val, //
512// int T, //
513// double g, //
514// std::vector<bool> &flag) //
515// //
516// Compute local solution to the 2D gradient limiting equation on a //
517// 2D volume. //
518// ========================================================================== //
519// INPUT //
520// ========================================================================== //
521// - nSimplex : int, number of simplicies in the surface tasselation //
522// - Vertex : std::vector<double>, vertex coordinate list. Vertex[i][0], //
523// Vertex[i][1], ... are the x, y, ... coordinates of the cell //
524// center of the i-th simplex //
525// - Simplex : std::vector<std::vector<int>>, simplex-vertex connectivity. Simplex[i][0] and //
526// Simplex[i][1] are the global indices of vertices of the i-th //
527// segment. //
528// - Adjacency : std::vector<std::vector<int>>, simplex-simplex adjacencies //
529// - val : std::vector<double>, scalar field at each mesh vertex //
530// - T : int, simplex global index //
531// - g : double, max slope //
532// - flag : std::vector<bool> with flag for dead (flag = false), and alive //
533// (flag = true) vertexes. //
534// ========================================================================== //
535// OUTPUT //
536// ========================================================================== //
537// - value : solution to the 2D gradient limiting equation //
538// ========================================================================== //
539
540BITPIT_UNUSED(nSimplex);
541BITPIT_UNUSED(Simplex);
542
543// ========================================================================== //
544// VARIABLES DECLARATION //
545// ========================================================================== //
546
547// Local variables
548double value = 1.0e+18;
549
550// Counters
551int A, j, m;
552
553// ========================================================================== //
554// COMPUTE THE LOCAL SOLUTION TO THE 2D GRADIENT LIMITING EQUATION //
555// ========================================================================== //
556
557// Find dead neighboors ----------------------------------------------------- //
558m = Adjacency[T].size();
559for (j = 0; j < m; ++j) {
560 A = Adjacency[T][j];
561 if (!flag[A]) {
562 value = std::min(value, val[A] + g * norm2(Vertex[T] - Vertex[A]));
563 }
564} //next j
565
566// Solve 1D grad limiting equation ------------------------------------------ //
567value = std::min(val[T], value);
568
569return(value); }
570
571// -------------------------------------------------------------------------- //
572void gradLimiting2D(
573 int nSimplex,
574 std::vector<std::array<double,3>> &Vertex,
575 std::vector<std::vector<int>> &Simplex,
576 std::vector<std::vector<int>> &Adjacency,
577 std::vector<double> &val,
578 double g
579) {
580
581// ========================================================================== //
582// void gradLimiting2D( //
583// int nSimplex, //
584// dvector2D &Vertex, //
585// std::vector<std::vector<int>> &Simplex, //
586// std::vector<std::vector<int>> &Adjacency, //
587// std::vector<double> &val, //
588// double g) //
589// //
590// Solve the 2D grad-limiting equation, using a fast marching method over //
591// a 2D domain. //
592// ========================================================================== //
593// INPUT //
594// ========================================================================== //
595// - nSimplex : int, number of simplicies in volume tasselation //
596// - Vertex : dvector2D, vertex coordinate list. Vertex[i][0], //
597// Vertex[i][1], ... are the x, y, ... coordinates of the //
598// cell center of the i-th simplex //
599// - Simplex : std::vector<std::vector<int>>, simplex-vertex connectivity //
600// - Adjacency : std::vector<std::vector<int>>, simplex-simplex adjacency //
601// - val : std::vector<double>, field to be smoothed //
602// - g : double, max gradient. //
603// ========================================================================== //
604// OUTPUT //
605// ========================================================================== //
606// - none //
607// ========================================================================== //
608
609// ========================================================================== //
610// VARIABLES DECLARATION //
611// ========================================================================== //
612
613// Local variables
614int idummy = 0;
615double ddummy = 0.;
616std::vector<bool> inserted(nSimplex, false);
617std::vector< std::array<int,2> > map(nSimplex), *map_ = &map;
618bitpit::MinPQueue<double, int> heap(nSimplex, true, map_);
619
620// Counters
621int j, k;
622int T, A;
623int m;
624
625for (T = 0; T < nSimplex; T++) {
626 map[T].fill(0) ;
627};
628
629// ========================================================================== //
630// BUILD MIN HEAP //
631// ========================================================================== //
632
633// Initialize data structure for min heap ----------------------------------- //
634k = 0;
635for (T = 0; T < nSimplex; T++) {
636 if (!inserted[T]) {
637
638 // Update mapper
639 map[k][0] = T;
640 map[T][1] = k;
641
642 // Insert vertex into min-heap
643 idummy = T;
644 heap.insert(val[T], idummy);
645
646 // Update flag & counters
647 k++;
648 inserted[T] = true;
649 }
650} //next T
651
652// ========================================================================== //
653// FAST GRADIENT LIMITING //
654// ========================================================================== //
655while (heap.heap_size > 0) {
656
657 // Extract root from min heap
658 heap.extract(ddummy, idummy);
659
660 // Update value for extracted item
661 T = idummy;
662 inserted[T] = false;
663
664 // Update value for neighboring vertices
665 m = Adjacency[T].size();
666 for (j = 0; j < m; ++j) {
667 A = Adjacency[T][j];
668 if (inserted[A]) {
669 val[A] = grad2DUpdate(nSimplex, Vertex, Simplex, Adjacency, val, A, g, inserted);
670 idummy = A;
671 heap.modify(map[A][1], val[A], idummy);
672 };
673 } //next j
674} //next item
675
676}
677
678}
679
680}
class for min priority queue.
double norm2(const std::array< T, d > &x)
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
--- layout: doxygen_footer ---