rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
RSVSintegration.cpp
1 #include "RSVSintegration.hpp"
2 
3 #include <cmath>
4 #include <fstream>
5 #include <iomanip>
6 #include <iostream>
7 #include <string>
8 #include <tuple>
9 #include <vector>
10 
11 #include "RSVSalgorithm.hpp"
12 #include "RSVScalc.hpp"
13 #include "RSVSclass.hpp"
14 #include "RSVSmath.hpp"
15 #include "filesystem.hpp"
16 #include "meshprocessing.hpp"
17 #include "meshrefinement.hpp"
18 #include "parameters.hpp"
19 #include "postprocessing.hpp"
20 #include "snake.hpp"
21 #include "snakeengine.hpp"
22 #include "tetgenrsvs.hpp"
23 #include "voxel.hpp"
24 #include "warning.hpp"
25 
26 using namespace std;
27 
28 int SAFE_ALGO_TestConn(snake &snakein)
29 {
30  int ret = 0;
31 
32  if (snakein.Check3D())
33  {
34 #ifdef SAFE_ALGO
35  ret = snakein.snakeconn.TestConnectivityBiDir(__PRETTY_FUNCTION__);
36 #endif // SAFE_ALGO
37  }
38 
39  return (ret);
40 }
41 
42 void SnakeConnectivityUpdate_legacy(snake &snakein, vector<int> &isImpact)
43 {
44  int start_s;
45 
46  start_s = clock();
47 
48  start_s = rsvs3d::TimeStamp("position: ", start_s);
49 
50  snakein.SnaxImpactDetection(isImpact);
51  MergeAllContactVertices(snakein, isImpact);
52  snakein.PrepareForUse();
53 
54  start_s = rsvs3d::TimeStamp("Merge: ", start_s);
55 
56  CleanupSnakeConnec(snakein);
57 
58  start_s = rsvs3d::TimeStamp("Clean: ", start_s);
59  snakein.SnaxImpactDetection(isImpact);
60  SpawnArrivedSnaxels(snakein, isImpact);
61 
62  start_s = rsvs3d::TimeStamp("Spawn: ", start_s);
63 
64  snakein.SnaxImpactDetection(isImpact);
65  snakein.SnaxAlmostImpactDetection(isImpact, 0.01);
66  snakein.PrepareForUse();
67  SAFE_ALGO_TestConn(snakein);
68  MergeAllContactVertices(snakein, isImpact);
69  snakein.PrepareForUse();
70  SAFE_ALGO_TestConn(snakein);
71 
72  start_s = rsvs3d::TimeStamp("Impact: ", start_s);
73 
74  CleanupSnakeConnec(snakein);
75 
76  SAFE_ALGO_TestConn(snakein);
77  snakein.OrientFaces();
78 
79  start_s = rsvs3d::TimeStamp("Clean: ", start_s);
80 }
81 
82 void SnakeConnectivityUpdate_robust(snake &snakein, vector<int> &isImpact)
83 {
84  /*
85  Performs the snake step except the movement of the snake.
86 
87  This one performs it in two steps:
88  1) Impact Merge Clean
89  2) Impact Spawn Impact Merge Clean
90 
91  This function might be better in snakeengine.cpp
92  */
93  double impactAlmostRange = 0.2;
94 
95  int start_s, start_f;
96  start_f = clock();
97 
98  //===============================
99  // Impact on edge
100  // ======================
101  // Impact
102  SAFE_ALGO_TestConn(snakein);
103  snakein.SnaxImpactDetection(isImpact);
104  snakein.PrepareForUse();
105  start_s = rsvs3d::TimeStamp("Impact: ", start_f);
106  // ======================
107  // Merge
108  MergeAllContactVertices(snakein, isImpact);
109  snakein.PrepareForUse();
110  start_s = rsvs3d::TimeStamp("Merge: ", start_s);
111  // ======================
112  // Clean
113  CleanupSnakeConnec(snakein);
114  snakein.PrepareForUse();
115  SAFE_ALGO_TestConn(snakein);
116  snakein.OrientFaces();
117  start_s = rsvs3d::TimeStamp("Clean: ", start_s);
118 
119  //===============================
120  // Spawn
121  // ======================
122  // Impact
123  SAFE_ALGO_TestConn(snakein);
124  snakein.SnaxImpactDetection(isImpact);
125  snakein.SnaxAlmostImpactDetection(isImpact, impactAlmostRange);
126  snakein.PrepareForUse();
127  start_s = rsvs3d::TimeStamp("Impact: ", start_s);
128  // ======================
129  // Spawn
130  SAFE_ALGO_TestConn(snakein);
131  snakein.SnaxImpactDetection(isImpact);
132  SpawnArrivedSnaxels(snakein, isImpact);
133  start_s = rsvs3d::TimeStamp("Spawn: ", start_s);
134  // ======================
135  // Impact
136  SAFE_ALGO_TestConn(snakein);
137  snakein.SnaxImpactDetection(isImpact);
138  snakein.PrepareForUse();
139  start_s = rsvs3d::TimeStamp("Impact: ", start_s);
140  // ======================
141  // Merge
142  MergeAllContactVertices(snakein, isImpact);
143  snakein.PrepareForUse();
144  start_s = rsvs3d::TimeStamp("Merge: ", start_s);
145  // ======================
146  // Clean
147  CleanupSnakeConnec(snakein);
148  snakein.PrepareForUse();
149  SAFE_ALGO_TestConn(snakein);
150  snakein.OrientFaces();
151  start_s = rsvs3d::TimeStamp("Clean: ", start_s);
152 
153  rsvs3d::TimeStamp(" - Connec Update: ", start_f);
154 }
155 
156 void SnakeConnectivityUpdate(snake &snakein, vector<int> &isImpact, double impactAlmostRange)
157 {
158  /*
159  Performs the snake step except the movement of the snake.
160  This one performs it in a 'single' step:
161  Impact Spawn Impact Merge Clean
162 
163  This function might be better in snakeengine.cpp
164  */
165 
166  int start_s, start_f;
167  start_f = clock();
168  // double stepLength = 1e-5;
169  //===============================
170  // Spawn
171  // ======================
172  // Impact
173  SAFE_ALGO_TestConn(snakein);
174  snakein.SnaxImpactDetection(isImpact);
175  snakein.SnaxAlmostImpactDetection(isImpact, impactAlmostRange);
176  snakein.PrepareForUse();
177  start_s = rsvs3d::TimeStamp("Impact: ", start_f);
178  // ======================
179  // Spawn
180  SAFE_ALGO_TestConn(snakein);
181  snakein.SnaxImpactDetection(isImpact);
182  snakein.snaxs.SetMaxIndex();
183  // int maxIndPreSpawn = snakein.snaxs.GetMaxIndex();
184  SpawnArrivedSnaxels(snakein, isImpact);
185  start_s = rsvs3d::TimeStamp("Spawn: ", start_s);
186  // snakein.PrepareForUse();
187  // ==============
188  // step away from edge
189  // snakein.TakeSpawnStep(maxIndPreSpawn, stepLength);
190  // snakein.UpdateCoord();
191  // snakein.PrepareForUse();
192  // ======================
193  // Impact
194  SAFE_ALGO_TestConn(snakein);
195  snakein.SnaxImpactDetection(isImpact);
196  snakein.PrepareForUse();
197  start_s = rsvs3d::TimeStamp("Impact: ", start_s);
198  // ======================
199  // Merge
200  MergeAllContactVertices(snakein, isImpact);
201  snakein.PrepareForUse();
202  start_s = rsvs3d::TimeStamp("Merge: ", start_s);
203  // ======================
204  // Clean
205  CleanupSnakeConnec(snakein);
206  // Take Spawn step
207  snakein.PrepareForUse();
208  SAFE_ALGO_TestConn(snakein);
209  snakein.OrientFaces();
210  start_s = rsvs3d::TimeStamp("Clean: ", start_s);
211  rsvs3d::TimeStamp(" - Connec Update: ", start_f);
212 }
213 
214 void SnakeSpawnStep(snake &snakein, int maxIndPreSpawn, double stepLength, std::string smmoothMethod)
215 {
216  // double stepLength = 1e-5;
217 
218  snakein.TakeSpawnStep(maxIndPreSpawn, stepLength);
219  snakein.PrepareForUse();
220  snakein.UpdateCoord();
221  snakein.OrientFaces();
222  snakein.TakeSmoothSpawnStep(maxIndPreSpawn, stepLength, smmoothMethod);
223  snakein.PrepareForUse();
224  snakein.UpdateCoord();
225 }
226 
227 void SnakeConnectivityUpdate_2D(snake &snakein, vector<int> &isImpact)
228 {
229  /*
230  Performs the snake step except the movement of the snake.
231  This one performs it in a 'single' step:
232  Impact Spawn Impact Merge Clean
233 
234  This function might be better in snakeengine.cpp
235  */
236  double impactAlmostRange = 0.2;
237 
238  int start_s, start_f;
239  start_f = clock();
240 
241  //===============================
242  // Spawn
243  // ======================
244  // Impact
245  SAFE_ALGO_TestConn(snakein);
246  snakein.SnaxImpactDetection(isImpact);
247  snakein.SnaxAlmostImpactDetection(isImpact, impactAlmostRange);
248  snakein.PrepareForUse();
249  start_s = rsvs3d::TimeStamp("Impact: ", start_f);
250  // ======================
251  // Spawn
252  SAFE_ALGO_TestConn(snakein);
253  snakein.SnaxImpactDetection(isImpact);
254  SpawnArrivedSnaxels(snakein, isImpact);
255  start_s = rsvs3d::TimeStamp("Spawn: ", start_s);
256  // ======================
257  // Impact
258  SAFE_ALGO_TestConn(snakein);
259  snakein.SnaxImpactDetection(isImpact);
260  snakein.PrepareForUse();
261  start_s = rsvs3d::TimeStamp("Impact: ", start_s);
262  // ======================
263  // Merge
264  MergeAllContactVertices(snakein, isImpact);
265  snakein.PrepareForUse();
266  start_s = rsvs3d::TimeStamp("Merge: ", start_s);
267  // ======================
268  // Clean
269  CleanupSnakeConnec(snakein);
270  snakein.PrepareForUse();
271  SAFE_ALGO_TestConn(snakein);
272  snakein.OrientFaces();
273  start_s = rsvs3d::TimeStamp("Clean: ", start_s);
274 
275  rsvs3d::TimeStamp(" - Connec Update: ", start_f);
276 }
277 
278 double SnakePositionUpdate(snake &rsvsSnake, std::vector<double> &dt, double snaxtimestep, double snaxdiststep)
279 {
280  rsvsSnake.CalculateTimeStep(dt, snaxtimestep, snaxdiststep);
281  rsvsSnake.UpdateDistance(dt, snaxdiststep, true);
282 
283  rsvsSnake.UpdateCoord();
284  rsvsSnake.PrepareForUse();
285  return *max_element(dt.begin(), dt.end());
286 }
287 // ====================
288 // integrate
289 // prepare
290 // ====================
291 
292 void integrate::Prepare(integrate::RSVSclass &RSVSobj)
293 {
294  // likely inputs (now in RSVSclass)
295  // param::parameters paramconf;
296  // mesh snakeMesh;
297  // mesh voluMesh;
298  // snake rsvsSnake;
299  // triangulation rsvsTri;
300  // tecplotfile outSnake;
301  // Locally defined
302 
303  param::parameters origconf;
304 
305  origconf = RSVSobj.paramconf;
306  RSVSobj.paramconf.PrepareForUse();
307  RSVSobj.setVelocityEngine(origconf.snak.engine);
308  integrate::ApplyDevSettings(RSVSobj);
309 
310  RSVSobj.rsvsSnake.clear();
311  RSVSobj.voluMesh.clear();
312  RSVSobj.snakeMesh.clear();
313  RSVSobj.rsvsTri.clear();
314 
315  integrate::prepare::Mesh(RSVSobj.paramconf.grid, RSVSobj.paramconf.files.ioin, RSVSobj.snakeMesh, RSVSobj.voluMesh);
316  integrate::prepare::Snake(RSVSobj.paramconf.snak, RSVSobj.paramconf.rsvs, RSVSobj.paramconf.files.ioin,
317  RSVSobj.snakeMesh, RSVSobj.voluMesh, RSVSobj.rsvsSnake);
318  integrate::prepare::Triangulation(RSVSobj.snakeMesh, RSVSobj.rsvsSnake, RSVSobj.rsvsTri);
319  integrate::prepare::Output(RSVSobj.paramconf, origconf, RSVSobj.outSnake, RSVSobj.outgradientsnake,
320  RSVSobj.outvectorsnake, RSVSobj.logFile, RSVSobj.coutFile, RSVSobj.cerrFile);
321 
322  RSVSobj.voluMesh.SetEdgeLengths();
323  RSVSobj.voluMesh.PrepareForUse();
324  RSVSobj.snakeMesh.SetEdgeLengths();
325  RSVSobj.snakeMesh.PrepareForUse();
326  RSVSobj.rsvsSnake.PrepareForUse();
327  RSVSobj.rsvsTri.PrepareForUse();
328 }
329 
330 void integrate::ApplyDevSettings(integrate::RSVSclass &RSVSobj)
331 {
332  auto &devset = RSVSobj.paramconf.dev;
333 
334  RSVSobj.calcObj->setDevParameters(devset);
335  RSVSobj.rsvsSnake.SetSnaxDistanceLimit_conserveShape(devset.snaxDistanceLimit_conserveShape);
336  SetEnvironmentEpsilon(devset.rsvsepsilons);
337 }
338 
339 void integrate::prepare::Mesh(const param::grid &gridconf, const param::ioin &ioinconf, mesh &snakeMesh, mesh &voluMesh)
340 {
341  /*prepares the snake and volume meshes gor the RSVS process*/
342  // Local declaration
343  // Used to calculate volumes in the mesh
344  RSVScalc calcVolus, calcSnakVolu;
345 
346  if (gridconf.activegrid.compare("voxel") == 0)
347  {
348  integrate::prepare::grid::Voxel(gridconf, snakeMesh, voluMesh);
349  }
350  else if (gridconf.activegrid.compare("voronoi") == 0)
351  {
352  integrate::prepare::grid::Voronoi(gridconf, snakeMesh, voluMesh);
353  }
354  else if (gridconf.activegrid.compare("load") == 0)
355  {
356  integrate::prepare::grid::Load(ioinconf, snakeMesh, voluMesh);
357  }
358  else
359  {
360  RSVS3D_ERROR_ARGUMENT((gridconf.activegrid + " not recognised. "
361  "Invalid parameter activegrid passed to "
362  "RSVS process.")
363  .c_str());
364  }
365 
366  snakeMesh.PrepareForUse();
367  snakeMesh.OrientFaces();
368  calcSnakVolu.CalculateMesh(snakeMesh);
369  calcSnakVolu.ReturnConstrToMesh(snakeMesh, &volu::volume);
370 
371  voluMesh.PrepareForUse();
372  voluMesh.OrientFaces();
373  calcVolus.CalculateMesh(voluMesh);
374  calcVolus.ReturnConstrToMesh(voluMesh, &volu::volume);
375 
376  std::cout << "Meshes prepared..." << std::endl;
377 }
378 
379 void integrate::prepare::grid::Voxel(const param::grid &gridconf, mesh &snakeMesh, mesh &voluMesh)
380 {
381  int ii;
382  auto gridSize = gridconf.voxel.gridsizebackground;
383  vector<int> elmMapping, backgroundGrid;
384 
385  backgroundGrid.reserve(int(gridSize.size()));
386  for (int i = 0; i < int(gridSize.size()); ++i)
387  {
388  backgroundGrid.push_back(gridSize[i]);
389  gridSize[i] = gridSize[i] * gridconf.voxel.gridsizesnake[i];
390  }
391 
392  // Initial build of the grid
393  BuildBlockGrid(gridSize, snakeMesh);
394  snakeMesh.Scale(gridconf.domain);
395  snakeMesh.PrepareForUse();
396  snakeMesh.OrientFaces();
397 
398  // map elements to coarse grid
399  if (snakeMesh.WhatDim() == 3)
400  {
401  for (ii = 0; ii < snakeMesh.volus.size(); ++ii)
402  {
403  elmMapping.push_back(1);
404  }
405  }
406  else if (snakeMesh.WhatDim() == 2)
407  {
408  for (ii = 0; ii < snakeMesh.surfs.size(); ++ii)
409  {
410  elmMapping.push_back(1);
411  }
412  }
413  else
414  {
415  RSVS3D_ERROR_ARGUMENT("Incorrect dimension");
416  }
417  CartesianMapping(snakeMesh, elmMapping, backgroundGrid);
418  CoarsenMesh(snakeMesh, voluMesh, elmMapping);
419  snakeMesh.AddParent(&voluMesh, elmMapping);
420 }
421 
422 void integrate::prepare::grid::Voronoi(const param::grid &gridconf, mesh &snakeMesh, mesh &voluMesh)
423 {
424  // Vector points are already loaded
425  tetgen::apiparam inparam;
426  inparam.edgelengths = {gridconf.voronoi.snakecoarseness, double(gridconf.voronoi.vorosnakelayers)};
427  inparam.distanceTol = gridconf.voronoi.distancebox;
428  for (int i = 0; i < 3; ++i)
429  {
430  inparam.lowerB[i] = gridconf.domain[i][0];
431  inparam.upperB[i] = gridconf.domain[i][1];
432  }
433  tetgen::RSVSVoronoiMesh(gridconf.voronoi.inputpoints, voluMesh, snakeMesh, inparam);
434 }
435 
436 void integrate::prepare::grid::Load(const param::ioin &ioinconf, mesh &snakeMesh, mesh &voluMesh)
437 {
438  snakeMesh.read(ioinconf.snakemeshname.c_str());
439  voluMesh.read(ioinconf.volumeshname.c_str());
440  snakeMesh.PrepareForUse(true);
441  voluMesh.PrepareForUse(true);
442 
443  // need to find mesh lineage
444  auto snakMeshVolPts = CoordInVolume(snakeMesh);
445  auto elmMapping = voluMesh.VertexInVolume(snakMeshVolPts, 3);
446 
447  snakeMesh.AddParent(&voluMesh, elmMapping);
448 
449  snakeMesh.PrepareForUse();
450  voluMesh.PrepareForUse();
451 }
452 
453 void integrate::prepare::Snake(const param::snaking &snakconf, const param::rsvs &rsvsconf, const param::ioin &ioinconf,
454  mesh &snakeMesh, // non const as it is passed to the snake as a pointer
455  mesh &voluMesh, snake &rsvsSnake)
456 {
457  // go through the rsvs conf figuring out which fill option to use.
458  int nElms;
459  if (voluMesh.WhatDim() == 3)
460  {
461  nElms = voluMesh.volus.size();
462  if (rsvsconf.filefill.active)
463  {
464  voluMesh.LoadTargetFill(rsvsconf.filefill.fill);
465  }
466  else if (rsvsconf.makefill.active)
467  {
468  // TODO add a fill builder
469  }
470  else if (rsvsconf.cstfill.active)
471  {
472  for (int i = 0; i < nElms; ++i)
473  {
474  voluMesh.volus[i].target = rsvsconf.cstfill.fill;
475  }
476  }
477  }
478  else if (voluMesh.WhatDim() == 2)
479  {
480  nElms = voluMesh.surfs.size();
481  if (rsvsconf.filefill.active)
482  {
483  voluMesh.LoadTargetFill(rsvsconf.filefill.fill);
484  }
485  else if (rsvsconf.makefill.active)
486  {
487  // TODO add a fill builder
488  }
489  else if (rsvsconf.cstfill.active)
490  {
491  for (int i = 0; i < nElms; ++i)
492  {
493  voluMesh.surfs[i].target = rsvsconf.cstfill.fill;
494  }
495  }
496  }
497  voluMesh.PrepareForUse();
498 
499  rsvsSnake.SetSnakeMesh(&snakeMesh);
500  if (!ioinconf.snakefile.empty())
501  {
502  rsvsSnake.read(ioinconf.snakefile.c_str());
503  rsvsSnake.SetSnakeMesh(&snakeMesh);
504  rsvsSnake.PrepareForUse(true);
505  rsvsSnake.OrientFaces();
506  rsvsSnake.AssignInternalVerts();
507  }
508  else
509  {
510  SpawnRSVS(rsvsSnake, snakconf.initboundary);
511  }
512  rsvsSnake.PrepareForUse(true);
513  rsvsSnake.OrientFaces();
514 }
515 
516 void integrate::prepare::Triangulation(mesh &snakeMesh, snake &rsvsSnake, triangulation &rsvsTri)
517 {
518  rsvsTri.PrepareForUse();
519  TriangulateMesh(snakeMesh, rsvsTri);
520  rsvsTri.PrepareForUse();
521  TriangulateSnake(rsvsSnake, rsvsTri);
522  rsvsTri.PrepareForUse();
523  rsvsTri.CalcTriVertPos();
524  rsvsTri.PrepareForUse();
525  MaintainTriangulateSnake(rsvsTri);
526  rsvsTri.PrepareForUse();
527 }
528 
529 void integrate::prepare::Output(const param::parameters &paramconf, const param::parameters &origconf,
530  tecplotfile &outSnake, tecplotfile &outgradientsnake, tecplotfile &outvectorsnake,
531  std::ofstream &logFile, std::ofstream &coutFile, std::ofstream &cerrFile)
532 {
533  std::string outSnakeName;
534 
535  if (paramconf.files.ioout.outdir.size() != 0)
536  {
537  filesystem::create_directories(paramconf.files.ioout.outdir);
538  }
539 
540  outSnakeName = utils::OutputFileName(paramconf, constants::tecplotsnake, ".plt");
541  outSnake.OpenFile(outSnakeName.c_str());
542 
543  if (integrate::constants::outputs::printGradientsSnake(paramconf.files.ioout.logginglvl))
544  {
545  outSnakeName = utils::OutputFileName(paramconf, constants::tecplotgradient, ".plt");
546  outgradientsnake.OpenFile(outSnakeName.c_str());
547  }
548  if (integrate::constants::outputs::printVectorSnake(paramconf.files.ioout.logginglvl))
549  {
550  outSnakeName = utils::OutputFileName(paramconf, constants::tecplotvectors, ".plt");
551  outvectorsnake.OpenFile(outSnakeName.c_str());
552  }
553 
554  outSnakeName = utils::OutputFileName(paramconf, "config_call_", ".json");
555  param::io::writeflat(outSnakeName, origconf);
556 
557  outSnakeName = utils::OutputFileName(paramconf, "config_active_", ".json");
558  param::io::writeflat(outSnakeName, paramconf);
559  // Open a text log file
560 
561  outSnakeName = utils::OutputFileName(paramconf, "convergence_", ".log");
562  logFile.open(outSnakeName);
563  logFile.precision(16);
564  logFile << std::scientific;
565 
566  if (paramconf.files.ioout.redirectcout)
567  {
568  outSnakeName = utils::OutputFileName(paramconf, "cout_", ".txt");
569  coutFile.open(outSnakeName);
570  std::cout.rdbuf(coutFile.rdbuf());
571  }
572  if (paramconf.files.ioout.redirectcerr)
573  {
574  outSnakeName = utils::OutputFileName(paramconf, "cerr_", ".txt");
575  cerrFile.open(outSnakeName);
576  std::cerr.rdbuf(cerrFile.rdbuf());
577  }
578  integrate::utils::SpecialiseTemplateFiles(paramconf);
579 }
580 
581 // ====================
582 // integrate
583 // execute
584 // ====================
585 
586 void integrate::execute::All(integrate::RSVSclass &RSVSobj)
587 {
588  auto coutbuff = std::cout.rdbuf();
589  auto cerrbuff = std::cerr.rdbuf();
590 
591  auto startTime = rsvs3d::TimeStamp(NULL, 0);
592  std::cout << "Start RSVS preparation" << std::endl;
593  integrate::Prepare(RSVSobj);
594 
595  std::cout << "Preparation finished - start iteration" << std::endl;
596  auto iterateInfo = integrate::execute::RSVSiterate(RSVSobj);
597 
598  std::cout << "Iteration finished - start PostProcessing" << std::endl;
599  integrate::execute::PostProcessing(RSVSobj, iterateInfo.timeT, iterateInfo.nVoluZone, iterateInfo.stepNum);
600 
601  std::cout << "PostProcessing finished - start Exporting" << std::endl;
602  integrate::execute::Exporting(RSVSobj);
603 
604  std::cout << "Exporting finished - close." << std::endl;
605  auto endTime = rsvs3d::TimeStamp(NULL, 0);
606  std::cout << "3D-RSVS completed in " << ceil(rsvs3d::Clock2ms(endTime - startTime) / 1000.0) << " seconds.";
607 
608  std::cout.rdbuf(coutbuff);
609  std::cerr.rdbuf(cerrbuff);
610 }
611 
612 void integrate::execute::Interactive(integrate::RSVSclass &RSVSobj)
613 {
614  auto coutbuff = std::cout.rdbuf();
615  auto cerrbuff = std::cerr.rdbuf();
616 
617  auto startTime = rsvs3d::TimeStamp(NULL, 0);
618  std::cout << "Start RSVS preparation" << std::endl;
619  integrate::Prepare(RSVSobj);
620 
621  RSVSobj.viewer.setInteractiveCallback(RSVSobj);
622  RSVSobj.viewer.show();
623  auto endTime = rsvs3d::TimeStamp(NULL, 0);
624  std::cout << "3D-RSVS completed in " << ceil(rsvs3d::Clock2ms(endTime - startTime) / 1000.0) << " seconds.";
625 
626  std::cout.rdbuf(coutbuff);
627  std::cerr.rdbuf(cerrbuff);
628 }
629 
630 integrate::iteratereturns integrate::execute::RSVSiterate(integrate::RSVSclass &RSVSobj)
631 {
632  vector<double> dt;
633  vector<int> isImpact;
634  int stepNum, maxStep, nVoluZone;
635  double totT = 0;
636 
637  auto start_s = clock();
638  // for n Steps
639  RSVSobj.setVelocityEngine(RSVSobj.paramconf.snak.engine);
640  integrate::ApplyDevSettings(RSVSobj);
641 
642  RSVSobj.voluMesh.PrepareForUse();
643  RSVSobj.outSnake.PrintMesh(RSVSobj.snakeMesh);
644  RSVSobj.outSnake.PrintMesh(RSVSobj.voluMesh);
645  nVoluZone = RSVSobj.outSnake.ZoneNum();
646 
647  maxStep = RSVSobj.paramconf.snak.maxsteps;
648  for (stepNum = 0; stepNum < maxStep; ++stepNum)
649  {
650  start_s = clock();
651  // RSVSobj.calcObj->limLag=10000.0;
652  std::cout << std::endl << "Step " << std::setw(4) << stepNum << " ";
653  RSVSobj.calcObj->CalculateVelocities(RSVSobj.rsvsTri, RSVSobj.paramconf.rsvs.solveralgorithm);
654  start_s = rsvs3d::TimeStamp(" solve:", start_s);
655 
656  CalculateNoNanSnakeVel(RSVSobj.rsvsSnake);
657 
658  integrate::execute::Logging(RSVSobj, totT, nVoluZone, stepNum);
659 
660  totT += SnakePositionUpdate(RSVSobj.rsvsSnake, dt, RSVSobj.paramconf.snak.snaxtimestep,
661  RSVSobj.paramconf.snak.snaxdiststep);
662 
663  int maxIndPreSpawn = RSVSobj.rsvsSnake.snaxs.GetMaxIndex();
664  SnakeConnectivityUpdate(RSVSobj.rsvsSnake, isImpact, RSVSobj.paramconf.snak.multiarrivaltolerance);
665  start_s = clock();
666  SnakeSpawnStep(RSVSobj.rsvsSnake, maxIndPreSpawn, RSVSobj.paramconf.snak.spawnposition,
667  RSVSobj.paramconf.dev.smoothstepmethod);
668  std::cout << RSVSobj.paramconf.dev.smoothstepmethod << " ; ";
669  start_s = rsvs3d::TimeStamp(" spawn step:", start_s);
670  MaintainTriangulateSnake(RSVSobj.rsvsTri);
671  start_s = rsvs3d::TimeStamp(" triangulate:", start_s);
672  }
673  std::cout << std::endl << "RSVS iteration finished" << std::endl;
674  integrate::iteratereturns retStruct(nVoluZone, stepNum, totT);
675  return (retStruct);
676 }
677 
678 bool integrate::constants::outputs::plotSnakeInPolyscope(int lvl)
679 {
680 #ifndef HEADLESS
681  return integrate::constants::outputs::printBaseSnake(lvl) || integrate::constants::outputs::printFullSnake(lvl) ||
682  integrate::constants::outputs::printGradientsSnake(lvl) ||
683  integrate::constants::outputs::printVectorSnake(lvl);
684 #else
685  return false;
686 #endif
687 }
688 
689 void integrate::execute::Logging(integrate::RSVSclass &RSVSobj, double totT, int nVoluZone, int stepNum)
690 {
691  // Simple function which directs to the correct output
692  int logLvl = RSVSobj.paramconf.files.ioout.logginglvl;
693 
694  // The maximum number for which there is a specific
695 
696  if (0 < logLvl)
697  {
698  // calcObj logging outputs different amounts of data
699  // depending.
700  RSVSobj.logFile << "> step" << stepNum << " :,";
701  RSVSobj.logFile << totT << endl;
702  integrate::execute::logging::Log(RSVSobj.logFile, RSVSobj.calcObj, RSVSobj.paramconf.files.ioout.logginglvl);
703  }
704  if (integrate::constants::outputs::printBaseSnake(logLvl))
705  {
706  integrate::execute::logging::Snake(RSVSobj.outSnake, RSVSobj.rsvsSnake, RSVSobj.voluMesh, totT, nVoluZone);
707  }
708  if (integrate::constants::outputs::printFullSnake(logLvl))
709  {
710  integrate::execute::logging::FullTecplot(RSVSobj.outSnake, RSVSobj.rsvsSnake, RSVSobj.rsvsTri, RSVSobj.voluMesh,
711  totT, nVoluZone, stepNum);
712  }
713  if (integrate::constants::outputs::printGradientsSnake(logLvl))
714  {
715  integrate::execute::logging::Gradients(RSVSobj.calcObj, RSVSobj.rsvsTri, RSVSobj.outgradientsnake, totT,
716  RSVSobj.paramconf.snak.engine);
717  }
718  if (integrate::constants::outputs::printVectorSnake(logLvl))
719  {
720  integrate::execute::logging::SnakeVectors(RSVSobj.outvectorsnake, RSVSobj.rsvsSnake, totT);
721  }
722  if (integrate::constants::outputs::plotSnakeInPolyscope(logLvl))
723  {
724  RSVSobj.viewer.addSnake(integrate::constants::polyscopeSnakeName, RSVSobj.rsvsSnake);
725  if (integrate::constants::outputs::printVectorSnake(logLvl))
726  {
727  RSVSobj.viewer.addSurfaceProperties(integrate::constants::polyscopeSnakeName, RSVSobj.rsvsSnake.snakeconn);
728  }
729  RSVSobj.viewer.show(0);
730  }
731 }
732 
733 void integrate::execute::PostProcessing(integrate::RSVSclass &RSVSobj, double totT, int nVoluZone, int stepNum)
734 {
735  int logLvl = RSVSobj.paramconf.files.ioout.outputlvl;
736  if (RSVSobj.paramconf.files.ioout.logginglvl != 5)
737  {
738  logLvl = max(RSVSobj.paramconf.files.ioout.outputlvl, RSVSobj.paramconf.files.ioout.logginglvl);
739  }
740 
741  if (logLvl > 1)
742  {
743  integrate::execute::postprocess::Snake(RSVSobj.rsvsSnake, RSVSobj.voluMesh, RSVSobj.paramconf);
744  }
745 
746  if (0 < logLvl)
747  {
748  RSVSobj.logFile << "> final step" << stepNum << " :,";
749  RSVSobj.logFile << totT << endl;
750  RSVSobj.logFile << totT << endl;
751  integrate::execute::postprocess::Log(RSVSobj.logFile, RSVSobj.calcObj,
752  RSVSobj.paramconf.files.ioout.logginglvl);
753  std::cout << std::endl;
754  }
755  if (integrate::constants::outputs::printBaseSnake(logLvl))
756  {
757  integrate::execute::logging::Snake(RSVSobj.outSnake, RSVSobj.rsvsSnake, RSVSobj.voluMesh, totT, nVoluZone);
758  }
759  if (integrate::constants::outputs::printFullSnake(logLvl))
760  {
761  integrate::execute::postprocess::FullTecplot(RSVSobj.outSnake, RSVSobj.rsvsSnake, RSVSobj.rsvsTri,
762  RSVSobj.voluMesh, totT, nVoluZone, stepNum);
763  }
764  if (integrate::constants::outputs::printGradientsSnake(logLvl))
765  {
766  integrate::execute::postprocess::Gradients(RSVSobj.calcObj, RSVSobj.rsvsTri, RSVSobj.outgradientsnake, totT,
767  RSVSobj.paramconf.snak.engine);
768  }
769  if (integrate::constants::outputs::printVectorSnake(logLvl))
770  {
771  integrate::execute::logging::SnakeVectors(RSVSobj.outvectorsnake, RSVSobj.rsvsSnake, totT);
772  }
773  if (integrate::constants::outputs::plotSnakeInPolyscope(logLvl))
774  {
775  RSVSobj.viewer.show();
776  }
777 }
778 
779 void integrate::execute::Exporting(integrate::RSVSclass &RSVSobj)
780 {
781  RSVSobj.rsvsSnake.Scale(RSVSobj.paramconf.grid.physdomain);
782  auto &paramconf = RSVSobj.paramconf;
783  auto outSnakeName = utils::OutputFileName(paramconf, "rsvs3D_export_", ".plt");
784 
785  tecplotfile outSnake;
786  outSnake.OpenFile(outSnakeName.c_str());
787 
788  outSnake.PrintSnake(RSVSobj.rsvsSnake);
789  outSnake.PrintMesh(*RSVSobj.rsvsSnake.snakemesh());
790  outSnake.PrintMesh(RSVSobj.voluMesh);
791 
792  for (auto exportType : RSVSobj.paramconf.files.exportconfig)
793  {
794  if (exportType.first.compare("su2") == 0)
795  {
796  integrate::execute::exporting::SU2(exportType.second, RSVSobj.rsvsSnake, RSVSobj.paramconf);
797  }
798  else if (exportType.first.compare("") == 0 && exportType.second.compare("") == 0)
799  {
800  /*Do nothing, this is the default*/
801  }
802  else if (exportType.first.compare("snake") == 0)
803  {
804  RSVSobj.rsvsSnake.Scale(RSVSobj.paramconf.grid.domain);
805  auto fileToOpen = utils::OutputFileName(paramconf, "SnakeConnExport_", ".msh");
806  auto tecFileToOpen = utils::OutputFileName(paramconf, "SnakeSensitivity_", ".plt");
807  auto tecconfig = RSVSobj.paramconf.files.ioout.tecplot;
808  tecconfig.loglvlspecialisation.push_back({-1, "RSVS_sensitivity"});
809  integrate::utils::SpecialiseTemplateFile(tecconfig, -1, paramconf.files.ioout, "SnakeSensitivity_");
810  RSVSobj.rsvsSnake.snakeconn.write(fileToOpen.c_str());
811  tecplotfile tecsens;
812  tecsens.OpenFile(tecFileToOpen.c_str());
813  if (RSVSobj.paramconf.snak.engine == "rsvs")
814  {
815  RSVScalc *calcObj = dynamic_cast<RSVScalc *>(RSVSobj.calcObj.get());
816  calcObj->CalculateTriangulation(RSVSobj.rsvsTri);
817  calcObj->CheckAndCompute(RSVSobj.paramconf.rsvs.solveralgorithm, true);
818  RSVSobj.rsvsSnake.Scale(RSVSobj.paramconf.grid.physdomain);
819  tecsens.PrintSnakeSensitivityVector(RSVSobj.rsvsTri, *calcObj);
820  }
821  }
822  else
823  {
824  RSVS3D_ERROR_NOTHROW((std::string("The export argument '") + exportType.first +
825  "' is not known. Check <input file>.json for parameter : "
826  "/files/exportconfig/...")
827  .c_str());
828  }
829  }
830 
831  RSVSobj.rsvsSnake.Scale(RSVSobj.paramconf.grid.domain);
832 }
833 
834 // ====================
835 // integrate
836 // execute
837 // logging
838 // ====================
839 
840 void integrate::execute::logging::Log(std::ofstream &logFile, RSVSCalculator &calcObj, int loglvl)
841 {
842  // Make a logging function for
843  // volume convergence and velocity convergence
844  calcObj->ConvergenceLog(logFile, loglvl);
845 }
846 
847 void integrate::execute::logging::Snake(tecplotfile &outSnake, snake &rsvsSnake, mesh &voluMesh, double totT,
848  int nVoluZone)
849 {
850  rsvsSnake.snakeconn.PrepareForUse();
851  rsvsSnake.snakeconn.OrientFaces();
852  outSnake.PrintVolumeDat(voluMesh, nVoluZone, 1, totT);
853  outSnake.PrintSnake(rsvsSnake, 2, totT, rsvs3d::constants::tecplot::polygon);
854 }
855 
856 void integrate::execute::logging::FullTecplot(tecplotfile &outSnake, snake &rsvsSnake, triangulation &rsvsTri,
857  mesh &voluMesh, double totT, int nVoluZone, int stepNum)
858 {
859  std::vector<int> vertList;
860  int jj;
861  if (rsvsSnake.snaxs.size() > 0)
862  {
863  rsvsSnake.snakeconn.PrepareForUse();
864  outSnake.PrintSnake(rsvsSnake, 1, totT, rsvs3d::constants::tecplot::polygon);
865  outSnake.PrintTriangulation(rsvsTri, &triangulation::dynatri, 2, totT, rsvs3d::constants::tecplot::polygon);
866  outSnake.PrintTriangulation(rsvsTri, &triangulation::intertri, 3, totT, rsvs3d::constants::tecplot::line);
867  if (stepNum == 0 && rsvsTri.intertri.size() == 0)
868  {
869  outSnake.PrintTriangulation(rsvsTri, &triangulation::dynatri, 3, totT, rsvs3d::constants::tecplot::line,
870  {rsvsTri.dynatri(0)->index});
871  }
872  outSnake.PrintTriangulation(rsvsTri, &triangulation::trisurf, 4, totT, rsvs3d::constants::tecplot::line);
873  if (stepNum == 0 && rsvsTri.trisurf.size() == 0)
874  {
875  outSnake.PrintTriangulation(rsvsTri, &triangulation::dynatri, 4, totT, rsvs3d::constants::tecplot::line,
876  {rsvsTri.dynatri(0)->index});
877  }
878  if (int(rsvsTri.acttri.size()) > 0)
879  {
880  outSnake.PrintTriangulation(rsvsTri, &triangulation::stattri, 5, totT, rsvs3d::constants::tecplot::line,
881  rsvsTri.acttri);
882  }
883  else if (stepNum == 0)
884  {
885  outSnake.PrintTriangulation(rsvsTri, &triangulation::dynatri, 5, totT, rsvs3d::constants::tecplot::line,
886  {rsvsTri.dynatri(0)->index});
887  }
888 
889  vertList.clear();
890  for (jj = 0; jj < int(rsvsSnake.isMeshVertIn.size()); ++jj)
891  {
892  if (rsvsSnake.isMeshVertIn[jj])
893  {
894  vertList.push_back(rsvsSnake.snakemesh()->verts(jj)->index);
895  }
896  }
897  if (int(rsvsSnake.isMeshVertIn.size()) == 0)
898  {
899  vertList.push_back(rsvsSnake.snakemesh()->verts(0)->index);
900  }
901  outSnake.PrintMesh(*(rsvsSnake.snakemesh()), 6, totT, rsvs3d::constants::tecplot::point, vertList);
902  outSnake.PrintVolumeDat(voluMesh, nVoluZone, 7, totT);
903  outSnake.PrintSnake(rsvsSnake, 8, totT);
904  }
905 }
906 
907 void integrate::execute::logging::Gradients(const RSVSCalculator &calcObj, const triangulation &rsvsTri,
908  tecplotfile &outgradientsnake, double totT,
909  const std::string &snakingEngine)
910 {
911  if (snakingEngine == "rsvs")
912  {
913  const RSVScalc *calcObjChild = dynamic_cast<RSVScalc *>(calcObj.get());
914  outgradientsnake.PrintSnakeGradients(rsvsTri, *calcObjChild, 1, totT);
915  }
916 }
917 
918 void integrate::execute::logging::SnakeVectors(tecplotfile &outSnake, snake &rsvsSnake, double totT)
919 {
920  outSnake.PrintSnake(rsvs3d::constants::tecplot::snakedata::snaxel, rsvsSnake, 1, totT,
921  rsvs3d::constants::tecplot::polygon);
922  int zoneShare = outSnake.ZoneNum();
923  outSnake.PrintSnake(rsvs3d::constants::tecplot::snakedata::normal, rsvsSnake, 2, totT,
924  rsvs3d::constants::tecplot::polygon, zoneShare);
925  outSnake.PrintSnake(rsvs3d::constants::tecplot::snakedata::laplacian, rsvsSnake, 3, totT,
926  rsvs3d::constants::tecplot::polygon, zoneShare);
927  outSnake.PrintSnake(rsvs3d::constants::tecplot::snakedata::direction, rsvsSnake, 4, totT,
928  rsvs3d::constants::tecplot::polygon, zoneShare);
929 }
930 
931 void integrate::execute::logging::SnakePolyscope(polyscopersvs::PolyScopeRSVS &viewer, const snake &rsvsSnake)
932 {
933  viewer.addSnake(integrate::constants::polyscopeSnakeName, rsvsSnake);
934  viewer.show(0);
935 }
936 
937 // ====================
938 // integrate
939 // execute
940 // postprocess
941 // ====================
942 void integrate::execute::postprocess::Log(std::ofstream &logFile, RSVSCalculator &calcObj, int loglvl)
943 {
944  integrate::execute::logging::Log(logFile, calcObj, loglvl + 2);
945 }
946 
947 void integrate::execute::postprocess::Snake(snake &rsvsSnake, mesh &voluMesh, param::parameters &paramconf)
948 {
949  std::string fileToOpen;
950 
951  fileToOpen = utils::OutputFileName(paramconf, "VoluMesh_", ".msh");
952  voluMesh.write(fileToOpen.c_str());
953  paramconf.files.ioin.volumeshname = fileToOpen;
954 
955  fileToOpen = utils::OutputFileName(paramconf, "SnakeMesh_", ".msh");
956  rsvsSnake.snakemesh()->write(fileToOpen.c_str());
957  paramconf.files.ioin.snakemeshname = fileToOpen;
958 
959  fileToOpen = utils::OutputFileName(paramconf, "SnakeConn_", ".msh");
960  rsvsSnake.snakeconn.write(fileToOpen.c_str());
961 
962  fileToOpen = utils::OutputFileName(paramconf, "Snake_", ".3snk");
963  rsvsSnake.write(fileToOpen.c_str());
964  paramconf.files.ioin.snakefile = fileToOpen;
965 
966  paramconf.files.ioin.casename = "restart_" + paramconf.files.ioout.pattern;
967  fileToOpen = utils::OutputFileName(paramconf, "config_restart_", ".json");
968  param::io::writeflat(fileToOpen, paramconf);
969 }
970 
971 void integrate::execute::postprocess::FullTecplot(tecplotfile &outSnake, snake &rsvsSnake, triangulation &rsvsTri,
972  mesh &voluMesh, double totT, int nVoluZone, int stepNum)
973 {
974  integrate::execute::logging::FullTecplot(outSnake, rsvsSnake, rsvsTri, voluMesh, totT, nVoluZone, stepNum);
975 }
976 
977 void integrate::execute::postprocess::Gradients(const RSVSCalculator &calcObj, const triangulation &rsvsTri,
978  tecplotfile &outgradientsnake, double totT,
979  const std::string &snakingEngine)
980 {
981  integrate::execute::logging::Gradients(calcObj, rsvsTri, outgradientsnake, totT, snakingEngine);
982 }
983 // ====================
984 // integrate
985 // execute
986 // exporting
987 // ====================
988 
989 void integrate::execute::exporting::SU2(std::string su2ConfStr, snake &rsvsSnake, param::parameters &paramconf)
990 {
991  std::string su2Path = "", patternReplace = "<pattern>";
992  std::string su2FileStr = su2ConfStr.substr(0, su2ConfStr.find(","));
993  // Make correct file path relative to the output directory
994  su2Path += paramconf.files.ioout.outdir + "/";
995 
996  auto patternIt = su2FileStr.find(patternReplace);
997  if (patternIt < su2FileStr.size())
998  {
999  su2Path += su2FileStr.substr(0, patternIt) + paramconf.files.ioout.pattern +
1000  su2FileStr.substr(patternIt + patternReplace.size());
1001  }
1002  else
1003  {
1004  su2Path += su2FileStr;
1005  }
1006 
1007  const filesystem::path pathout = su2Path;
1008  filesystem::create_directories(pathout.parent_path());
1009 
1010  tetgen::apiparam su2MeshParam(su2ConfStr.substr(su2ConfStr.find(",") + 1));
1011  tetgen::SnakeToSU2(rsvsSnake, su2Path, su2MeshParam);
1012 }
1013 
1014 // ====================
1015 //
1016 // Utilities
1017 //
1018 // ====================
1019 
1020 void integrate::utils::WriteModifiedTemplate(const std::string &fileIn, const std::string &fileOut,
1021  const std::string &oldLine, const std::string newLine)
1022 {
1023  ifstream in(fileIn, ios::in);
1024  if (in.fail())
1025  {
1026  RSVS3D_ERROR_NOTHROW((fileIn + " was not found, template could not be"
1027  " specialised.")
1028  .c_str());
1029  return;
1030  }
1031  ofstream out(fileOut, ios::out);
1032  std::string tempString;
1033  while (!in.eof())
1034  {
1035  getline(in, tempString);
1036  auto pos = tempString.find(oldLine);
1037  if (pos != std::string::npos)
1038  {
1039  out << tempString.substr(0, pos) << newLine << std::endl;
1040  break;
1041  }
1042  else
1043  {
1044  out << tempString << std::endl;
1045  }
1046  }
1047 
1048  out << in.rdbuf();
1049 }
1050 
1051 void integrate::utils::SpecialiseTemplateFiles(const param::parameters &paramconf)
1052 {
1053  // param::tecplottemplate&
1054  auto &tecconfig = paramconf.files.ioout.tecplot;
1055  int loglvl = paramconf.files.ioout.logginglvl;
1056 
1057  if (integrate::constants::outputs::printBaseSnake(loglvl))
1058  {
1059  SpecialiseTemplateFile(tecconfig, 2, paramconf.files.ioout, constants::tecplotsnake);
1060  }
1061  else if (integrate::constants::outputs::printFullSnake(loglvl))
1062  {
1063  SpecialiseTemplateFile(tecconfig, 3, paramconf.files.ioout, constants::tecplotsnake);
1064  }
1065  if (integrate::constants::outputs::printGradientsSnake(loglvl))
1066  {
1067  SpecialiseTemplateFile(tecconfig, 5, paramconf.files.ioout, constants::tecplotgradient);
1068  }
1069  if (integrate::constants::outputs::printVectorSnake(loglvl))
1070  {
1071  SpecialiseTemplateFile(tecconfig, 6, paramconf.files.ioout, constants::tecplotvectors);
1072  }
1073  if (loglvl > integrate::constants::outputs::numberdefined)
1074  {
1075  SpecialiseTemplateFile(tecconfig, loglvl, paramconf.files.ioout, constants::tecplotsnake);
1076  }
1077 }
1078 
1079 void integrate::utils::SpecialiseTemplateFile(const param::tecplottemplate &tecconfig, int logLvl,
1080  const param::ioout &ioout, std::string fileName)
1081 {
1082  // Build the name of the correct file from logging lvl and
1083  std::string templateLayout, outputLayout;
1084  templateLayout = tecconfig.TemplateLogging(logLvl);
1085  outputLayout = ioout.outdir + "/";
1086  outputLayout += tecconfig.TemplateLogging(logLvl, false, std::string("_") + ioout.pattern);
1087  std::string lineOut =
1088  tecconfig.filenameregex + "'\"" + integrate::utils::OutputFileName("", ioout.pattern, fileName, ".plt") + "\"'";
1089  integrate::utils::WriteModifiedTemplate(templateLayout, outputLayout, tecconfig.filenameregex, lineOut);
1090 }
1091 
1092 std::string integrate::utils::OutputFileName(const param::parameters &paramconf, std::string fileName,
1093  std::string extension)
1094 {
1095  return OutputFileName(paramconf.files.ioout.outdir, paramconf.files.ioout.pattern, fileName, extension);
1096 }
1097 
1098 std::string integrate::utils::OutputFileName(const std::string rootDirectory, const std::string &filePattern,
1099  std::string fileName, std::string extension)
1100 {
1101  if (rootDirectory.compare("") == 0)
1102  {
1103  return fileName + filePattern + extension;
1104  }
1105  return rootDirectory + "/" + fileName + filePattern + extension;
1106 }
1107 
1108 // ===================
1109 // Tests
1110 // ===================
1111 
1112 int integrate::test::Prepare()
1113 {
1114  param::parameters paramconf, origconf;
1115  mesh snakeMesh;
1116  mesh voluMesh;
1117  snake rsvsSnake;
1118  triangulation rsvsTri;
1119  tecplotfile outSnake;
1120  tecplotfile outgradientSnake;
1121  tecplotfile outvectorSnake;
1122  std::ofstream logFile;
1123  std::ofstream coutFile;
1124  std::ofstream cerrFile;
1125 
1126  origconf = paramconf;
1127  paramconf.PrepareForUse();
1128  try
1129  {
1130  integrate::prepare::Mesh(paramconf.grid, paramconf.files.ioin, snakeMesh, voluMesh);
1131  voluMesh.volus.disp();
1132  }
1133  catch (std::exception const &ex)
1134  {
1135  cerr << "integrate::prepare::Mesh(paramconf.grid, snakeMesh, "
1136  "voluMesh);"
1137  << endl;
1138  cerr << "Exception: " << ex.what() << endl;
1139  return -1;
1140  }
1141 
1142  try
1143  {
1144  integrate::prepare::Snake(paramconf.snak, paramconf.rsvs, paramconf.files.ioin, snakeMesh, voluMesh, rsvsSnake);
1145  }
1146  catch (std::exception const &ex)
1147  {
1148  cerr << "integrate::prepare::Snake(paramconf.snak, snakeMesh,"
1149  " rsvsSnake);"
1150  << endl;
1151  cerr << "Exception: " << ex.what() << endl;
1152  return -1;
1153  }
1154 
1155  try
1156  {
1157  integrate::prepare::Triangulation(snakeMesh, rsvsSnake, rsvsTri);
1158  }
1159  catch (std::exception const &ex)
1160  {
1161  cerr << "integrate::prepare::Triangulation" << endl;
1162  cerr << "Exception: " << ex.what() << endl;
1163  return -1;
1164  }
1165 
1166  try
1167  {
1168  integrate::prepare::Output(paramconf, origconf, outSnake, outgradientSnake, outvectorSnake, logFile, coutFile,
1169  cerrFile);
1170  }
1171  catch (std::exception const &ex)
1172  {
1173  cerr << "integrate::prepare::Output" << endl;
1174  cerr << "Exception: " << ex.what() << endl;
1175  return -1;
1176  }
1177 
1178  return (0);
1179 }
1180 
1181 int integrate::test::All()
1182 {
1183  integrate::RSVSclass RSVSobj;
1184  auto coutbuff = std::cout.rdbuf();
1185  auto cerrbuff = std::cout.rdbuf();
1186 
1187  integrate::Prepare(RSVSobj);
1188  auto iterateInfo = integrate::execute::RSVSiterate(RSVSobj);
1189 
1190  integrate::execute::PostProcessing(RSVSobj, iterateInfo.timeT, iterateInfo.nVoluZone, iterateInfo.stepNum);
1191  std::cout.rdbuf(coutbuff);
1192  std::cerr.rdbuf(cerrbuff);
1193  std::cout << std::endl << " cout Buffer restored" << std::endl;
1194  std::cerr << " cerr Buffer restored" << std::endl;
1195  return 0;
1196 }
1197 
1198 bool integrate::constants::outputs::printBaseSnake(int lvl)
1199 {
1200  return lvl == 2 || lvl == 5 || lvl == 7;
1201 };
1202 bool integrate::constants::outputs::printFullSnake(int lvl)
1203 {
1204  return lvl == 3 || lvl == 4 || numberdefined < lvl;
1205 };
1206 bool integrate::constants::outputs::printGradientsSnake(int lvl)
1207 {
1208  return lvl == 4 || lvl == 5 || lvl == 7 || numberdefined < lvl;
1209 };
1210 bool integrate::constants::outputs::printVectorSnake(int lvl)
1211 {
1212  return lvl == 6 || lvl == 7 || numberdefined < lvl;
1213 };
Functions which are part of the RSVS algorithm but not core to the snaking process.
Provides the infrastructure for calculation of the RSVS equations.
Simple class containing all the information needed for the 3D-RSVS execution.
Integration into the full 3 dimensional Restricted Snake Volume of Solid method.
std::string OutputFileName(const param::parameters &paramconf, std::string fileName, std::string extension)
Convenience function to generate file names for RSVS.
Performs Volume and Area calculations for the RSVS process.
Class to handle the RSVS calculation.
Definition: RSVScalc.hpp:130
void CalculateMesh(mesh &meshin)
Calculates the mesh volumes.
Definition: RSVScalc.cpp:294
void ReturnConstrToMesh(triangulation &triRSVS) const
Returns a constraint to the triangulation::meshDep.
Definition: RSVScalc.cpp:400
void CheckAndCompute(int calcMethod=0, bool sensCalc=false)
Prepare the active arrays for SQP calculation and calculate the SQP step.
void CalculateTriangulation(const triangulation &triRSVS, int derivMethod=0)
Calculates the triangulation volume and area derivatives.
Definition: RSVScalc.cpp:95
Class for mesh handling.
Definition: mesh.hpp:592
std::vector< int > VertexInVolume(const std::vector< double > testVertices, int sizeVert=3) const
Finds for each vertex, the volume object containing it.
Definition: mesh.cpp:492
void OrientFaces()
Orients either surfaces or edges depending on the dimensionality of the object.
Definition: mesh.cpp:4948
Class for parameters of the grid generation.
Definition: parameters.hpp:167
std::string activegrid
The type of grid to use either "voxel" or "voronoi" .
Definition: parameters.hpp:176
std::array< realbounds, 3 > physdomain
Physical domain size for export.
Definition: parameters.hpp:174
std::array< realbounds, 3 > domain
Domain size in internal coordinates.
Definition: parameters.hpp:172
Class containing the input configuration these are files to load.
Definition: parameters.hpp:186
Class containing the output configuration these are files to store and where to store them.
Definition: parameters.hpp:204
Root class for all the parameters.
Definition: parameters.hpp:288
Parameters related to the Velocity calculation and VOS steps.
Definition: parameters.hpp:75
filltype< double > cstfill
Fill the VOS values with a constant value.
Definition: parameters.hpp:84
int solveralgorithm
Algorithm used by Eigen to solve the SQP system.
Definition: parameters.hpp:82
filltype< std::string > filefill
Fill the VOS values from file filefill.fill.
Definition: parameters.hpp:86
filltype< std::string > makefill
Fill the VOS values from a run time function accessible from makefill.fill.
Definition: parameters.hpp:89
Parameters controlling tuning parameters for the stepping of the restricted surface.
Definition: parameters.hpp:100
double snaxtimestep
maximum snake time step length
Definition: parameters.hpp:111
int initboundary
Initialisation boundary (either 0 (outer border), 1 (inner border))
Definition: parameters.hpp:116
int maxsteps
maximum number of steps
Definition: parameters.hpp:118
double multiarrivaltolerance
Distance along edge at which converging snaxels are considered arrived.
Definition: parameters.hpp:109
double snaxdiststep
maximum snaxel distance movement
Definition: parameters.hpp:113
double spawnposition
Position of spawn.
Definition: parameters.hpp:120
double distancebox
Distance at which to build the bounding box of the mesh.
Definition: parameters.hpp:149
double snakecoarseness
The coarseneness level of the snaking mesh that will be generated.
Definition: parameters.hpp:154
int vorosnakelayers
The number of layers making up the snaking mesh inside each VOS cell [6 6 6] is roughly equal to 2.
Definition: parameters.hpp:157
std::vector< double > inputpoints
Vector of input points, 4 datums per point.
Definition: parameters.hpp:147
std::array< int, 3 > gridsizesnake
Size of the Snaking grid on which the snake is defined.
Definition: parameters.hpp:135
std::array< int, 3 > gridsizebackground
Size of the Background grid on which the VOS is defined.
Definition: parameters.hpp:132
A structure containing the information about the polyscope display and the RSVS elements to display.
void addSurfaceProperties(std::string name, const mesh &surfaceMesh)
Adds properties of the surface of a snake to it's mesh as scalar quantities.
void show(size_t forFrames=SIZE_MAX)
Show the polyscope window.
void setInteractiveCallback(integrate::RSVSclass &RSVSobj)
Set polyscope's user callback to a lambda which allows control of the RSVSobj.
void addSnake(std::string name, const snake &snakeIn)
PLot a snake with it's velocity in the given polyscope window.
Definition: snake.hpp:83
double distanceTol
Distance tolerance.
Definition: tetgenrsvs.hpp:147
std::vector< double > edgelengths
Controls the edgelengths at regular intervals.
Definition: tetgenrsvs.hpp:145
std::array< double, 3 > lowerB
Lower domain bound.
Definition: tetgenrsvs.hpp:137
std::array< double, 3 > upperB
Upper domain bound.
Definition: tetgenrsvs.hpp:139
void clear()
Clears the contents of the triangulation making sure we can restart the process.
Custom filesystem header Faff about with filesystem depending on version To give a readable compile t...
Tools for the mathematical processing of meshes.
std::vector< double > CoordInVolume(const mesh &meshin)
Generate a vector of coordinates of points probably inside volumes.
Tools for the refinement and coarsening of meshes.
void CoarsenMesh(const mesh &meshchild, mesh &newparent, const std::vector< int > &elmMapping)
Parameters for the integrated 3DRSVS.
Provide tecplot file formating for mesh and snake outputs.
Provides the core restricted surface snake container.
Functions needed to evolve the r-surface snake.
Interface between the RSVS project and tetgen.
std::vector< int > RSVSVoronoiMesh(const std::vector< double > &vecPts, mesh &vosMesh, mesh &snakMesh, tetgen::apiparam &inparam)
Genrates Snaking and VOS RSVS meshes from the voronoi diagram of a set of points.
Definition: tetgenrsvs.cpp:876
void SnakeToSU2(const snake &snakein, const std::string &fileName, tetgen::apiparam &inparam)
Genrates an SU2 mesh file from a snake.
Generation of cartesian grids.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR_NOTHROW(M)
Generic rsvs warning.
Definition: warning.hpp:120
#define RSVS3D_ERROR_ARGUMENT(M)
Throw a invalid_argument.
Definition: warning.hpp:148