rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
integration_test.cpp
Go to the documentation of this file.
1 
7 #include <cmath>
8 #include <cstdlib>
9 #include <ctime>
10 #include <fstream>
11 #include <iomanip>
12 #include <iostream>
13 #include <memory>
14 #include <sstream>
15 #include <tuple>
16 
17 #include "RSVSalgorithm.hpp"
18 #include "RSVScalc.hpp"
19 #include "RSVSclass.hpp"
20 #include "RSVSintegration.hpp"
21 #include "RSVSmath.hpp"
22 #include "RSVSmath_automatic.hpp"
23 #include "main.hpp"
24 #include "matrixtools.hpp"
25 #include "meshrefinement.hpp"
26 #include "parameters.hpp"
27 #include "postprocessing.hpp"
28 #include "rsvsutils.hpp"
29 #include "snake.hpp"
30 #include "snakeengine.hpp"
31 #include "tetgenrsvs.hpp"
32 #include "triangulate.hpp"
33 #include "warning.hpp"
34 
35 using namespace integrate::test;
36 using namespace std;
37 
38 typedef std::tuple<double, Eigen::MatrixXd, double, double> processed_derivative;
39 
40 processed_derivative test_RSVScalcvsFD(integrate::RSVSclass &RSVSobj, bool SetUseSurfCentreDeriv, int testVert,
41  double fdStep, int constrFocus)
42 {
43 
44  std::tuple<double, Eigen::MatrixXd, double> testtuple;
45  auto calcObj = std::make_shared<RSVScalc>();
46  RSVSobj.calcObj = calcObj;
47  auto &sn = RSVSobj.rsvsSnake;
48  calcObj->SetUseSurfCentreDeriv(SetUseSurfCentreDeriv);
49  calcObj->CalculateTriangulation(RSVSobj.rsvsTri);
50  int dvNum = calcObj->dvMap.find(testVert);
51  auto analyticalDObj = calcObj->dObj;
52  auto analyticalDConstr = calcObj->dConstr;
53  auto constrPreFD = calcObj->constr;
54  auto objPreFd = calcObj->obj;
55  sn.snaxs[sn.snaxs.find(testVert)].d += fdStep;
56  sn.snaxs.PrepareForUse();
57  sn.UpdateCoord();
58 
59  if (SetUseSurfCentreDeriv)
60  {
61  RSVSobj.rsvsTri.CalcTriVertPos();
62  RSVSobj.rsvsTri.PrepareForUse();
63  }
64 
65  calcObj->CalculateTriangulation(RSVSobj.rsvsTri);
66  auto constrPostFD = calcObj->constr;
67  auto objPostFd = calcObj->obj;
68  auto fdDObj = (objPostFd - objPreFd) / fdStep;
69  auto fdDconstr = (constrPostFD - constrPreFD) / fdStep;
70 
71  double diffDObj = (analyticalDObj[dvNum] - fdDObj) / analyticalDObj[dvNum];
72  Eigen::VectorXd diffDConstr = (analyticalDConstr.block(0, dvNum, calcObj->numConstr(), 1) - fdDconstr).array() /
73  analyticalDConstr.block(0, dvNum, calcObj->numConstr(), 1).array();
74 
75  int nRows = diffDConstr.size();
76  for (int i = 0; i < nRows; ++i)
77  {
78  if (rsvs3d::utils::IsAproxEqual(0.0, analyticalDConstr(i, dvNum)))
79  {
80  diffDConstr[i] = 0.0;
81  }
82  }
83  sn.snaxs[sn.snaxs.find(testVert)].d -= fdStep;
84  sn.snaxs.PrepareForUse();
85  sn.UpdateCoord();
86  if (SetUseSurfCentreDeriv)
87  {
88  RSVSobj.rsvsTri.CalcTriVertPos();
89  RSVSobj.rsvsTri.PrepareForUse();
90  }
91  std::cout << "------------------------------------------" << std::endl
92  << "Analytical gradient vs Finite difference (" << fdStep << ")" << std::endl;
93  std::cout << "SetUseSurfCentreDeriv : " << SetUseSurfCentreDeriv << std::endl;
94  std::cout << "snax->d : " << sn.snaxs.isearch(testVert)->d << std::endl;
95  std::cout << "diffDObj: (ana-fd)/ana = delta " << std::endl
96  << analyticalDObj[dvNum] << " " << fdDObj << " = " << diffDObj << std::endl
97  << std::endl;
98  std::cout << "diffDConstr (ana-fd)/ana = delta: " << std::endl
99  << analyticalDConstr.block(0, dvNum, calcObj->numConstr(), 1).transpose() << std::endl
100  << std::endl
101  << fdDconstr.transpose() << std::endl
102  << std::endl
103  << diffDConstr.transpose() << std::endl;
104 
105  return {diffDObj, diffDConstr, analyticalDObj[dvNum], analyticalDConstr(constrFocus, dvNum)};
106 }
107 
108 void RunCommandFromString(integrate::RSVSclass &RSVSobj, std::vector<std::string> &commands)
109 {
110  std::stringstream strstream;
111  param::parameters paramconf;
112 
113  auto parseOut = parse::StringParser(commands, paramconf);
114 
115  if (parseOut.execFlow < 0)
116  {
117  RSVS3D_ERROR("Argument parsing returned a non-runable structure");
118  }
119  RSVSobj.paramconf = paramconf;
120 
121  /*Running of the core iteration process*/
122 
123  auto coutbuff = std::cout.rdbuf();
124  auto cerrbuff = std::cerr.rdbuf();
125  std::cout << "Start RSVS preparation" << std::endl;
126  integrate::Prepare(RSVSobj);
127 
128  std::cout << "Preparation finished - start iteration" << std::endl;
129  std::cout.rdbuf(strstream.rdbuf());
130  auto iterateInfo = integrate::execute::RSVSiterate(RSVSobj);
131  std::cout.rdbuf(coutbuff);
132  std::cout << "Iteration finished - start PostProcessing" << std::endl;
133  integrate::execute::PostProcessing(RSVSobj, iterateInfo.timeT, iterateInfo.nVoluZone, iterateInfo.stepNum);
134 
135  std::cout << "PostProcessing finished - start Exporting" << std::endl;
136  integrate::execute::Exporting(RSVSobj);
137 
138  std::cout << "Exporting finished - close." << std::endl;
139  std::cout.rdbuf(coutbuff);
140  std::cerr.rdbuf(cerrbuff);
141 }
142 
143 void StreamProcessedDerivative(processed_derivative &in, double fdStep, std::string modifier, int constrIntrest)
144 {
145  std::cout << fdStep << " (";
146  cout.unsetf(std::ios::fixed | std::ios::scientific);
147  std::cout << std::setw(3) << floor(log10(DBL_EPSILON / fdStep));
148  std::cout << std::scientific;
149  std::cout << ")"
150  << " - " << std::setw(10) << modifier << " centroid - obj (" << std::setw(std::cout.precision() + 7)
151  << std::get<2>(in) << "): " << std::setw(std::cout.precision() + 7) << std::get<0>(in) << " - constr ("
152  << std::setw(std::cout.precision() + 7) << std::get<3>(in) << "): ";
153  std::cout << std::setw(std::cout.precision() + 7) << std::get<1>(in)(constrIntrest, 0) << " | stats : ";
154  StreamStatistics(std::get<1>(in), std::cout);
155 }
156 
157 std::stringstream Test_CompareSnaxDeriv_FDANA(integrate::RSVSclass &RSVSobj, int testVert, int constrFocus = 0)
158 {
159 
160  std::vector<processed_derivative> derivDiffNoCentre, derivDiffCentre;
161  std::vector<double> fdSteps = {1e-5, 1e-6, 1e-7, 1e-8, 1e-9, 1e-10};
162 
163  std::stringstream strstream;
164  auto coutbuff = std::cout.rdbuf();
165  auto cerrbuff = std::cerr.rdbuf();
166 
167  std::cout.rdbuf(strstream.rdbuf());
168 
169  for (double fdStep : fdSteps)
170  {
171  derivDiffNoCentre.push_back(test_RSVScalcvsFD(RSVSobj, false, testVert, fdStep, constrFocus));
172  derivDiffCentre.push_back(test_RSVScalcvsFD(RSVSobj, true, testVert, fdStep, constrFocus));
173  }
174  std::cout.rdbuf(coutbuff);
175  std::cerr.rdbuf(cerrbuff);
176 
177  std::cout << "--------------------------------------------------" << std::endl
178  << "Summary of results: " << std::endl;
179  std::cout << "rsvsmath_automatic_eps_surf : " << rsvsmath_automatic_eps_surf << std::endl;
180  std::cout << std::endl;
181  std::cout << std::scientific;
182  RSVSobj.rsvsSnake.snaxs.isearch(testVert)->disp();
183  RSVSobj.rsvsSnake.snakeconn.verts.isearch(testVert)->disp();
184  for (int i = 0; i < int(fdSteps.size()); ++i)
185  {
186 
187  StreamProcessedDerivative(derivDiffNoCentre[i], fdSteps[i], "without", constrFocus);
188  StreamProcessedDerivative(derivDiffCentre[i], fdSteps[i], "with", constrFocus);
189  }
190  cout.unsetf(std::ios::fixed | std::ios::scientific);
191  return strstream;
192 }
193 
194 int integrate::test::CompareSurfCentreDerivatives()
195 {
196  // Test a snake
197  integrate::RSVSclass RSVSobj;
198  std::vector<std::string> commands;
199 
200  commands.push_back("Test_CompareSurfCentreDerivatives");
201  commands.push_back("-l");
202  commands.push_back("config/NURBStest.json");
203  commands.push_back("-p");
204  commands.push_back("/snak/maxsteps:50");
205  RunCommandFromString(RSVSobj, commands);
206 
207  /*Perform tests, compare */
208  // Choose a snaxel pass all it through the RSVScalc object
209  // double fdStep = 1e-6;
210  auto &sc = RSVSobj.rsvsSnake.snakeconn;
211  auto &sn = RSVSobj.rsvsSnake;
212  int testVert = rsvs3d::constants::__notfound;
213  int surfTest = 0;
214  int nSurf = sc.surfs.size();
215  for (int i = 0; i < nSurf; ++i)
216  {
217  if (sc.surfs(i)->edgeind.size() > 4)
218  {
219  surfTest = sc.surfs(i)->index;
220  auto testVerts = sc.surfs.isearch(surfTest)->vertind(sc);
221  for (auto isTestVert : testVerts)
222  {
223  auto dTest = sn.snaxs.isearch(isTestVert)->d;
224  if (dTest > 0.10 && dTest < 0.90)
225  {
226  // if(dTest>fdStep*10 && dTest< (1.0 - fdStep*10)){
227  testVert = isTestVert;
228  break;
229  }
230  }
231  if (testVert != rsvs3d::constants::__notfound)
232  {
233  break;
234  }
235  }
236  }
237  if (testVert == rsvs3d::constants::__notfound)
238  {
239  RSVS3D_ERROR("Index was supposed to be above 0");
240  }
241  double rsvsmath_automatic_eps_surfprev = rsvsmath_automatic_eps_surf;
242  rsvsmath_automatic_eps_surf = 0.0;
243  Test_CompareSnaxDeriv_FDANA(RSVSobj, testVert);
244 
245  rsvsmath_automatic_eps_surf = rsvsmath_automatic_eps_surfprev;
246  return 0;
247 }
248 
249 void CompareDerivativesSpikeStepNum(std::string numstr, bool useSurfCentreDeriv = true)
250 {
251  integrate::RSVSclass RSVSobj;
252  std::vector<std::string> commands;
253  auto calcObj = std::make_shared<RSVScalc>();
254  RSVSobj.calcObj = calcObj;
255  calcObj->SetUseSurfCentreDeriv(useSurfCentreDeriv);
256 
257  commands.push_back("CompareDerivativesSpike" + numstr);
258  commands.push_back("-l");
259  commands.push_back("config/522_fbullet.json");
260  commands.push_back("-p");
261  commands.push_back("/snak/maxsteps:" + numstr);
262  commands.push_back("-p");
263  commands.push_back("/files/ioout/logginglvl:5");
264  RunCommandFromString(RSVSobj, commands);
265 
266  /*Perform tests, compare */
267  // Choose a snaxel pass all it through the RSVScalc object
268  // double fdStep = 1e-6;
269  if (RSVSobj.rsvsSnake.snaxs.size() > 543)
270  {
271 
272  int testVert = RSVSobj.rsvsSnake.snaxs(543)->index;
273  std::stringstream sumarries;
274  auto coutbuff = std::cout.rdbuf(sumarries.rdbuf());
275  double rsvsmath_automatic_eps_surfprev = rsvsmath_automatic_eps_surf;
276  // rsvsmath_automatic_eps_surf = 0.0;
277  auto stream0 = Test_CompareSnaxDeriv_FDANA(RSVSobj, testVert, 2);
278  rsvsmath_automatic_eps_surf = 0.0;
279  auto streamEps = Test_CompareSnaxDeriv_FDANA(RSVSobj, testVert, 2);
280  rsvsmath_automatic_eps_surf = rsvsmath_automatic_eps_surfprev;
281 
282  std::cout.rdbuf(coutbuff);
283 
284  // std::cout << stream0.str();
285  // std::cout << streamEps.str();
286 
287  std::cout << sumarries.str();
288  std::cout << std::endl << "Step number: " << numstr << "+1" << std::endl;
289  std::cout << "DeltaDv: " << calcObj->deltaDV[calcObj->dvMap.find(testVert)] << std::endl;
290 
291  std::cout << std::endl << "Lagrangian multipliers:" << std::endl;
292  std::cout << calcObj->lagMult.transpose();
293  std::cout << std::endl << "-------------------------------------------" << std::endl;
294  }
295 }
296 
297 int integrate::test::CompareDerivativesSpike()
298 {
299  CompareDerivativesSpikeStepNum("94");
300  CompareDerivativesSpikeStepNum("95");
301  CompareDerivativesSpikeStepNum("96");
302  CompareDerivativesSpikeStepNum("97");
303  CompareDerivativesSpikeStepNum("98");
304  return 0;
305 }
306 int integrate::test::CompareDerivativesSpikeNoDPos()
307 {
308 
309  double rsvsmath_automatic_eps_surfprev = rsvsmath_automatic_eps_surf;
310 
311  CompareDerivativesSpikeStepNum("100", false);
312  CompareDerivativesSpikeStepNum("100", true);
313 
314  rsvsmath_automatic_eps_surf = 0.0;
315  CompareDerivativesSpikeStepNum("100", false);
316  CompareDerivativesSpikeStepNum("100", true);
317 
318  rsvsmath_automatic_eps_surf = 1e-6;
319  CompareDerivativesSpikeStepNum("100", false);
320  CompareDerivativesSpikeStepNum("100", true);
321 
322  rsvsmath_automatic_eps_surf = rsvsmath_automatic_eps_surfprev;
323  return 0;
324 }
325 
326 void GenerateDerivatives(bool useSurfCentreDeriv, double eps_overwrite, double spawn_step,
327  ostream &outPutDeriv = std::cout)
328 {
329  integrate::RSVSclass RSVSobj;
330  auto c_ptr = std::make_shared<RSVScalc>();
331  RSVSobj.calcObj = c_ptr;
332  std::vector<std::string> commands;
333  std::stringstream nameCommand, posCommand;
334  c_ptr->SetUseSurfCentreDeriv(useSurfCentreDeriv);
335  double rsvsmath_automatic_eps_surfprev = rsvsmath_automatic_eps_surf;
336 
337  rsvsmath_automatic_eps_surf = eps_overwrite;
338  nameCommand << "GenerateDerivatives " << std::endl
339  << "useSurfCentreDeriv " << useSurfCentreDeriv << std::endl
340  << "eps_overwrite " << eps_overwrite << std::endl
341  << "spawn_step " << spawn_step;
342 
343  commands.push_back(nameCommand.str());
344  commands.push_back("-l");
345  commands.push_back("config/restart_spike_issue.json");
346  commands.push_back("-p");
347  commands.push_back("/files/ioout/logginglvl:5");
348  commands.push_back("-p");
349  posCommand << "/snak/spawnposition:" << spawn_step;
350  commands.push_back(posCommand.str());
351  RunCommandFromString(RSVSobj, commands);
352  rsvsmath_automatic_eps_surf = rsvsmath_automatic_eps_surfprev;
353 
354  auto &c = *c_ptr;
355  outPutDeriv.precision(16);
356  outPutDeriv << nameCommand.str() << std::endl;
357  outPutDeriv << "dObj," << c.dObj.size() << std::endl;
358  PrintMatrixFile(c.dObj, outPutDeriv);
359  outPutDeriv << std::endl;
360  outPutDeriv << "dConstr," << c.dConstr.size() << std::endl;
361  PrintMatrixFile(c.dConstr, outPutDeriv);
362  outPutDeriv << std::endl;
363  outPutDeriv << "HObj," << c.HObj.size() << std::endl;
364  PrintMatrixFile(c.HObj, outPutDeriv);
365  outPutDeriv << std::endl;
366  outPutDeriv << "HConstr," << c.HConstr.size() << std::endl;
367  PrintMatrixFile(c.HConstr, outPutDeriv);
368  outPutDeriv << std::endl;
369  outPutDeriv << "deltaDV," << c.deltaDV.size() << std::endl;
370  PrintMatrixFile(c.deltaDV, outPutDeriv);
371  outPutDeriv << std::endl;
372 }
373 
374 int integrate::test::StudyDerivatives()
375 {
376 
377  // Load the spike test and do one step at different values of step size and
378  // rsvsmath_automatic_eps
379  int k = 0;
380  for (auto useSurfCentreDeriv : {true, false})
381  {
382  for (auto eps_overwrite : {0.0, 1e-15, 1e-14, 1e-12, 1e-10, 1e-8, 1e-6, 1e-4, 1e-3, 1e-2, 1e-1, 1e-0})
383  {
384  k++;
385  std::stringstream fileName;
386  fileName << "dbg/processed_derivative/derivative_" << k << ".dat";
387  ofstream outPutDeriv(fileName.str());
388  for (auto spawn_step : {0.0, 1e-15, 1e-14, 1e-12, 1e-10, 1e-8, 1e-6, 1e-4, 1e-3, 1e-2, 1e-1, 2e-1})
389  {
390  GenerateDerivatives(useSurfCentreDeriv, eps_overwrite, spawn_step, outPutDeriv);
391  }
392  }
393  }
394 
395  return 0;
396 }
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.
Performs Volume and Area calculations for the RSVS process.
Root class for all the parameters.
Definition: parameters.hpp:288
file containing the main functions and the command line parser.
Tools to support conversion, display and derivatives of Eigen matrices.
Tools for the refinement and coarsening of meshes.
Parameters for the integrated 3DRSVS.
Provide tecplot file formating for mesh and snake outputs.
Provides various utility functions for the RSVS operation.
Provides the core restricted surface snake container.
Functions needed to evolve the r-surface snake.
Interface between the RSVS project and tetgen.
Provides a triangulation for snake and meshes.
Provides the error and warning system used by the RSVS3D project.
#define RSVS3D_ERROR(M)
Throw generic rsvs errors.
Definition: warning.hpp:113