22 #include "RSVSmath_automatic.hpp"
35 using namespace integrate::test;
38 typedef std::tuple<double, Eigen::MatrixXd, double, double> processed_derivative;
40 processed_derivative test_RSVScalcvsFD(
integrate::RSVSclass &RSVSobj,
bool SetUseSurfCentreDeriv,
int testVert,
41 double fdStep,
int constrFocus)
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();
59 if (SetUseSurfCentreDeriv)
61 RSVSobj.rsvsTri.CalcTriVertPos();
62 RSVSobj.rsvsTri.PrepareForUse();
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;
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();
75 int nRows = diffDConstr.size();
76 for (
int i = 0; i < nRows; ++i)
78 if (rsvs3d::utils::IsAproxEqual(0.0, analyticalDConstr(i, dvNum)))
83 sn.snaxs[sn.snaxs.find(testVert)].d -= fdStep;
84 sn.snaxs.PrepareForUse();
86 if (SetUseSurfCentreDeriv)
88 RSVSobj.rsvsTri.CalcTriVertPos();
89 RSVSobj.rsvsTri.PrepareForUse();
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
98 std::cout <<
"diffDConstr (ana-fd)/ana = delta: " << std::endl
99 << analyticalDConstr.block(0, dvNum, calcObj->numConstr(), 1).transpose() << std::endl
101 << fdDconstr.transpose() << std::endl
103 << diffDConstr.transpose() << std::endl;
105 return {diffDObj, diffDConstr, analyticalDObj[dvNum], analyticalDConstr(constrFocus, dvNum)};
110 std::stringstream strstream;
113 auto parseOut = parse::StringParser(commands, paramconf);
115 if (parseOut.execFlow < 0)
117 RSVS3D_ERROR(
"Argument parsing returned a non-runable structure");
119 RSVSobj.paramconf = paramconf;
123 auto coutbuff = std::cout.rdbuf();
124 auto cerrbuff = std::cerr.rdbuf();
125 std::cout <<
"Start RSVS preparation" << std::endl;
126 integrate::Prepare(RSVSobj);
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);
135 std::cout <<
"PostProcessing finished - start Exporting" << std::endl;
136 integrate::execute::Exporting(RSVSobj);
138 std::cout <<
"Exporting finished - close." << std::endl;
139 std::cout.rdbuf(coutbuff);
140 std::cerr.rdbuf(cerrbuff);
143 void StreamProcessedDerivative(processed_derivative &in,
double fdStep, std::string modifier,
int constrIntrest)
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;
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);
157 std::stringstream Test_CompareSnaxDeriv_FDANA(
integrate::RSVSclass &RSVSobj,
int testVert,
int constrFocus = 0)
160 std::vector<processed_derivative> derivDiffNoCentre, derivDiffCentre;
161 std::vector<double> fdSteps = {1e-5, 1e-6, 1e-7, 1e-8, 1e-9, 1e-10};
163 std::stringstream strstream;
164 auto coutbuff = std::cout.rdbuf();
165 auto cerrbuff = std::cerr.rdbuf();
167 std::cout.rdbuf(strstream.rdbuf());
169 for (
double fdStep : fdSteps)
171 derivDiffNoCentre.push_back(test_RSVScalcvsFD(RSVSobj,
false, testVert, fdStep, constrFocus));
172 derivDiffCentre.push_back(test_RSVScalcvsFD(RSVSobj,
true, testVert, fdStep, constrFocus));
174 std::cout.rdbuf(coutbuff);
175 std::cerr.rdbuf(cerrbuff);
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)
187 StreamProcessedDerivative(derivDiffNoCentre[i], fdSteps[i],
"without", constrFocus);
188 StreamProcessedDerivative(derivDiffCentre[i], fdSteps[i],
"with", constrFocus);
190 cout.unsetf(std::ios::fixed | std::ios::scientific);
194 int integrate::test::CompareSurfCentreDerivatives()
198 std::vector<std::string> commands;
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);
210 auto &sc = RSVSobj.rsvsSnake.snakeconn;
211 auto &sn = RSVSobj.rsvsSnake;
212 int testVert = rsvs3d::constants::__notfound;
214 int nSurf = sc.surfs.size();
215 for (
int i = 0; i < nSurf; ++i)
217 if (sc.surfs(i)->edgeind.size() > 4)
219 surfTest = sc.surfs(i)->index;
220 auto testVerts = sc.surfs.isearch(surfTest)->vertind(sc);
221 for (
auto isTestVert : testVerts)
223 auto dTest = sn.snaxs.isearch(isTestVert)->d;
224 if (dTest > 0.10 && dTest < 0.90)
227 testVert = isTestVert;
231 if (testVert != rsvs3d::constants::__notfound)
237 if (testVert == rsvs3d::constants::__notfound)
241 double rsvsmath_automatic_eps_surfprev = rsvsmath_automatic_eps_surf;
242 rsvsmath_automatic_eps_surf = 0.0;
243 Test_CompareSnaxDeriv_FDANA(RSVSobj, testVert);
245 rsvsmath_automatic_eps_surf = rsvsmath_automatic_eps_surfprev;
249 void CompareDerivativesSpikeStepNum(std::string numstr,
bool useSurfCentreDeriv =
true)
252 std::vector<std::string> commands;
253 auto calcObj = std::make_shared<RSVScalc>();
254 RSVSobj.calcObj = calcObj;
255 calcObj->SetUseSurfCentreDeriv(useSurfCentreDeriv);
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);
269 if (RSVSobj.rsvsSnake.snaxs.size() > 543)
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;
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;
282 std::cout.rdbuf(coutbuff);
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;
291 std::cout << std::endl <<
"Lagrangian multipliers:" << std::endl;
292 std::cout << calcObj->lagMult.transpose();
293 std::cout << std::endl <<
"-------------------------------------------" << std::endl;
297 int integrate::test::CompareDerivativesSpike()
299 CompareDerivativesSpikeStepNum(
"94");
300 CompareDerivativesSpikeStepNum(
"95");
301 CompareDerivativesSpikeStepNum(
"96");
302 CompareDerivativesSpikeStepNum(
"97");
303 CompareDerivativesSpikeStepNum(
"98");
306 int integrate::test::CompareDerivativesSpikeNoDPos()
309 double rsvsmath_automatic_eps_surfprev = rsvsmath_automatic_eps_surf;
311 CompareDerivativesSpikeStepNum(
"100",
false);
312 CompareDerivativesSpikeStepNum(
"100",
true);
314 rsvsmath_automatic_eps_surf = 0.0;
315 CompareDerivativesSpikeStepNum(
"100",
false);
316 CompareDerivativesSpikeStepNum(
"100",
true);
318 rsvsmath_automatic_eps_surf = 1e-6;
319 CompareDerivativesSpikeStepNum(
"100",
false);
320 CompareDerivativesSpikeStepNum(
"100",
true);
322 rsvsmath_automatic_eps_surf = rsvsmath_automatic_eps_surfprev;
326 void GenerateDerivatives(
bool useSurfCentreDeriv,
double eps_overwrite,
double spawn_step,
327 ostream &outPutDeriv = std::cout)
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;
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;
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;
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;
374 int integrate::test::StudyDerivatives()
380 for (
auto useSurfCentreDeriv : {
true,
false})
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})
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})
390 GenerateDerivatives(useSurfCentreDeriv, eps_overwrite, spawn_step, outPutDeriv);
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.
file containing the main functions and the command line parser.
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.