rsvs3D  0.0.0
Codes for the c++ implementation of the 3D RSVS
RSVScalctools.cpp
1 #include "RSVScalctools.hpp"
2 
3 #include <Eigen>
4 #include <fstream>
5 #include <vector>
6 
7 #include "RSVScalc.hpp"
8 #include "RSVSmath.hpp"
9 #include "arraystructures.hpp"
10 #include "matrixtools.hpp"
11 #include "rsvsutils.hpp"
12 #include "triangulate.hpp"
13 
14 using namespace std;
15 using namespace Eigen;
16 using namespace rsvs3d::constants;
17 
19 {
20  grid::coordlist veccoord;
21  veccoord.reserve(3);
22 
23  int ni = 3;
24  for (int ii = 0; ii < ni; ++ii)
25  {
26  if (triIn.pointtype[ii] == meshtypes::mesh)
27  {
28  veccoord.push_back(&(triRSVS.meshDep->verts.isearch(triIn.pointind[ii])->coord));
29  }
30  else if (triIn.pointtype[ii] == meshtypes::snake)
31  {
32  veccoord.push_back(&(triRSVS.snakeDep->snakeconn.verts.isearch(triIn.pointind[ii])->coord));
33  }
34  else if (triIn.pointtype[ii] == meshtypes::triangulation)
35  {
36  veccoord.push_back((triRSVS.trivert.isearch(triIn.pointind[ii])->coord.retPtr()));
37  }
38  }
39 
40  return veccoord;
41 }
42 
44  const HashedVector<int, int> &objDvMap, bool useSurfCentreDeriv)
45 {
46  HashedVector<int, int> dvListMap;
47  vector<int> vertsSurf;
48  vector<int> &dvList = dvListMap.vec;
49 
50  int ni = 3;
51  for (int ii = 0; ii < ni; ++ii)
52  {
53  vertsSurf.clear();
54  if (triIn.pointtype[ii] == meshtypes::snake && objDvMap.find(triIn.pointind[ii]) != __notfound)
55  {
56  dvList.push_back(triIn.pointind[ii]);
57  }
58  else if (triIn.pointtype[ii] == meshtypes::triangulation && useSurfCentreDeriv)
59  {
60  switch (triRSVS.trivert.isearch(triIn.pointind[ii])->parentType)
61  {
62  case meshtypes::triangulation: {
63  // If parent surf is a trisurf
64  auto surfCurr = triRSVS.trisurf.isearch(triRSVS.trivert.isearch(triIn.pointind[ii])->parentsurf);
65  int nj = surfCurr->indvert.size();
66  for (int jj = 0; jj < nj; ++jj)
67  {
68  if (surfCurr->typevert[jj] == meshtypes::snake)
69  {
70  if (objDvMap.find(surfCurr->indvert[jj]) != __notfound)
71  {
72  dvList.push_back(surfCurr->indvert[jj]);
73  }
74  }
75  }
76  }
77  break;
78  case meshtypes::snake: {
79  // If parent surf is a snakesurf
80  auto surfCurr =
81  triRSVS.snakeDep->snakeconn.surfs.isearch(triRSVS.trivert.isearch(triIn.pointind[ii])->parentsurf);
82  vertsSurf = surfCurr->OrderedVerts(&(triRSVS.snakeDep->snakeconn));
83  int nj = vertsSurf.size();
84  for (int jj = 0; jj < nj; ++jj)
85  {
86  if (objDvMap.find(vertsSurf[jj]) != __notfound)
87  {
88  dvList.push_back(vertsSurf[jj]);
89  }
90  }
91  }
92  break;
93  }
94  }
95  }
96 
97  sort(dvListMap.vec);
98  unique(dvListMap.vec);
99  dvListMap.GenerateHash();
100 
101  return (dvListMap);
102 }
103 
110 void TrianglePositionDerivatives(const triangle &triIn, const triangulation &triRSVS,
111  const HashedVector<int, int> &dvListMap, MatrixXd &dPos, MatrixXd &HPos,
112  bool useSurfCentreDeriv, bool useSurfCentreHessian)
113 {
114  std::vector<int> vertsSurf;
115  int nDvAct = dvListMap.vec.size();
116  bool triggerPrint = false, triggerActive = false;
117  auto ifisnan0 = [&](double in) -> double { return isnan(in) ? 0.0 : in; };
118  // auto ifisapprox0 = [&](double in) -> double {return
119  // rsvs3d::utils::IsAproxEqual(in,0.0)?0.0:in;};
120  auto cleanup = [&](double in) -> double { return ifisnan0((in)); };
121 
122  static std::ofstream streamout;
123  if (triggerActive && !streamout.is_open())
124  {
125  streamout.open("dbg/deriv_pos.txt", std::ios::app);
126  std::cout << "Debug stream opened";
127  }
128  // Positional Derivatives
129 
130  // HERE -> function to calculate SurfCentroid (dc/dd)^T Hm (dc/dd)
131  HPos.setZero(nDvAct, nDvAct * 9);
132  dPos.setZero(9, nDvAct);
133  int ni = 3;
134  for (int ii = 0; ii < ni; ++ii)
135  {
136  vertsSurf.clear();
137  if (triIn.pointtype[ii] == meshtypes::snake && dvListMap.find(triIn.pointind[ii]) != __notfound)
138  {
139  auto tempSnax = triRSVS.snakeDep->snaxs.isearch(triIn.pointind[ii]);
140  auto fromVert = triRSVS.meshDep->verts.isearch(tempSnax->fromvert);
141  auto toVert = triRSVS.meshDep->verts.isearch(tempSnax->tovert);
142  int dvSub = dvListMap.find(triIn.pointind[ii]);
143  for (int jj = 0; jj < 3; ++jj)
144  {
145  dPos(ii * 3 + jj, dvSub) += (toVert->coord[jj] - fromVert->coord[jj]);
146  }
147  }
148  else if (triIn.pointtype[ii] == meshtypes::triangulation && useSurfCentreDeriv)
149  {
150  switch (triRSVS.trivert.isearch(triIn.pointind[ii])->parentType)
151  {
152  case meshtypes::triangulation: {
153  auto surfCurr = triRSVS.trisurf.isearch(triRSVS.trivert.isearch(triIn.pointind[ii])->parentsurf);
154  auto surfCentre =
155  SurfaceCentroid_TriangleSurf(*surfCurr, *(triRSVS.meshDep), triRSVS.snakeDep->snakeconn);
156  surfCentre.Calc();
157  auto jacCentre = surfCentre.jac_ptr();
158  auto hesCentre = surfCentre.hes_ptr();
159  int count = surfCurr->indvert.size();
160  for (int j = 0; j < count; ++j)
161  {
162  int dvSub = dvListMap.find(surfCurr->indvert[j]);
163  if (dvSub != __notfound && surfCurr->typevert[j] == meshtypes::snake)
164  {
165  auto currSnax = triRSVS.snakeDep->snaxs.isearch(surfCurr->indvert[j]);
166  auto fromVert = triRSVS.meshDep->verts.isearch(currSnax->fromvert);
167  auto toVert = triRSVS.meshDep->verts.isearch(currSnax->tovert);
168  for (int k = 0; k < 3; ++k)
169  {
170  for (int l = 0; l < 3; ++l)
171  {
172  dPos(ii * 3 + k, dvSub) +=
173  cleanup(jacCentre[k][j + count * l] * (toVert->coord[l] - fromVert->coord[l]))
174  // * (1.0+(double(rand()) / RAND_MAX)*1e-4)
175  ;
176  }
177  }
178  }
179  }
180  }
181  break;
182  case meshtypes::snake: {
183  auto surfCurr =
184  triRSVS.snakeDep->snakeconn.surfs.isearch(triRSVS.trivert.isearch(triIn.pointind[ii])->parentsurf);
185  auto surfCentre = SurfaceCentroid_SnakeSurf(*surfCurr, triRSVS.snakeDep->snakeconn);
186  surfCentre.Calc();
187  auto jacCentre = surfCentre.jac_ptr();
188  auto hesCentre = surfCentre.hes_ptr();
189  ConnVertFromConnEdge(triRSVS.snakeDep->snakeconn, surfCurr->edgeind, vertsSurf);
190  // Check that the triangle and the surface
191  size_t count = vertsSurf.size();
192  for (size_t j = 0; j < count; ++j)
193  {
194  int dvSub = dvListMap.find(vertsSurf[j]);
195  auto currSnax = triRSVS.snakeDep->snaxs.isearch(vertsSurf[j]);
196  auto fromVert = triRSVS.meshDep->verts.isearch(currSnax->fromvert);
197  auto toVert = triRSVS.meshDep->verts.isearch(currSnax->tovert);
198 
199  if (dvSub != __notfound)
200  {
201  for (size_t k = 0; k < 3; ++k)
202  {
203  for (size_t l = 0; l < 3; ++l)
204  {
205  dPos(ii * 3 + k, dvSub) +=
206  cleanup(jacCentre[k][j + count * l] * (toVert->coord[l] - fromVert->coord[l]))
207  // * (1.0+(double(rand()) / RAND_MAX)*1e-4)
208  ;
209  }
210  }
211  }
212  }
213  // Fill the three layers of HPos which correspond to
214  // this vertex.
215  // hesCentre
216  if (useSurfCentreHessian)
217  {
218  MatrixXd dPosd(count * 3, count);
219  dPosd.setZero(count * 3, count);
220  for (size_t j = 0; j < count; ++j)
221  {
222  auto currSnax = triRSVS.snakeDep->snaxs.isearch(vertsSurf[j]);
223  auto fromVert = triRSVS.meshDep->verts.isearch(currSnax->fromvert);
224  auto toVert = triRSVS.meshDep->verts.isearch(currSnax->tovert);
225  for (size_t k = 0; k < 3; ++k)
226 
227  {
228  dPosd(j + k * count, j) += (toVert->coord[k] - fromVert->coord[k]);
229  }
230  }
231  MatrixXd HVal(count * 3, count * 3 * 3), HPosTemp(count, count * 3);
232  ArrayVec2MatrixXd(hesCentre, HVal);
233  for (size_t j = 0; j < 3; ++j)
234  {
235  HPosTemp.block(0, j * count, count, count) =
236  dPosd.transpose() * HVal.block(0, j * count * 3, count * 3, count * 3) * dPosd;
237  }
238  for (size_t j = 0; j < count; ++j)
239  {
240  int dvSub = dvListMap.find(vertsSurf[j]);
241  if (dvSub != __notfound)
242  {
243  for (size_t j2 = 0; j2 < count; ++j2)
244  {
245  int dvSub2 = dvListMap.find(vertsSurf[j2]);
246  if (dvSub2 != __notfound)
247  {
248  for (size_t k = 0; k < 3; ++k)
249  {
250  HPos(dvSub, dvSub2 + (ii * 3 + k) * nDvAct) +=
251  cleanup(HPosTemp(j, j2 + k * count));
252  }
253  }
254  }
255  }
256  }
257  if (triggerActive)
258  {
259  triggerPrint = true;
260  }
261  if (triggerPrint)
262  {
263  streamout << "triangle " << triIn.index << " parent: surf : " << triIn.parentsurf
264  << " parent: type : " << triIn.parenttype << " pnt-centroid: " << ii << std::endl;
265  streamout << "pointind" << std::endl;
266  PrintVector(triIn.pointind, streamout);
267  streamout << "" << std::endl;
268  streamout << "pointtype" << std::endl;
269  PrintVector(triIn.pointtype, streamout);
270  streamout << "" << std::endl;
271  streamout << "dPosd:" << std::endl;
272  PrintMatrixFile(dPosd, streamout);
273  }
274  }
275  }
276  break;
277  }
278  }
279  }
280  if (triggerPrint)
281  {
282  streamout << "HPos:" << std::endl;
283  PrintMatrixFile(HPos, streamout);
284  streamout << "dPos:" << std::endl;
285  PrintMatrixFile(dPos, streamout);
286  }
287 }
288 
289 void AssignConstraintDerivativesFullMath(RSVScalc &calc, const triangle &triIn, const HashedVector<int, int> &dvListMap,
290  const MatrixXd &dConstrPart, const MatrixXd &HConstrPart, int constrPos,
291  int cellTarg)
292 {
293  int nDvAct = dvListMap.vec.size();
294  int ii = cellTarg;
295  for (int kk = 0; kk < nDvAct; ++kk)
296  {
297  calc.dConstr(constrPos, calc.dvMap.find(dvListMap.vec[kk])) +=
298  triIn.connec.constrinfluence[ii] * dConstrPart(0, kk);
299  calc.dvCallConstr(calc.dvMap.find(dvListMap.vec[kk]), 0)++;
300  for (int ll = 0; ll < nDvAct; ++ll)
301  {
302  // TODO cross product with lagrangian
303  calc.HConstr(calc.dvMap.find(dvListMap.vec[ll]), calc.dvMap.find(dvListMap.vec[kk])) +=
304  triIn.connec.constrinfluence[ii] * HConstrPart(ll, kk) * calc.lagMult[constrPos]
305  // /calc.constrTarg[constrPos]
306  ;
307  }
308  }
309 }
310 
311 void AssignConstraintDerivativesSparseMath(RSVScalc &calc, const triangle &triIn,
312  const HashedVector<int, int> &dvListMap, const MatrixXd &dConstrPart,
313  const MatrixXd &HConstrPart, int constrPos, int cellTarg)
314 {
315  int nDvAct = dvListMap.vec.size();
316  int ii = cellTarg;
317 
318  for (int kk = 0; kk < nDvAct; ++kk)
319  {
320  if (!rsvs3d::utils::IsAproxEqual(dConstrPart(0, kk), 0.0))
321  {
322  calc.dConstr_sparse.coeffRef(constrPos, calc.dvMap.find(dvListMap.vec[kk])) +=
323  triIn.connec.constrinfluence[ii] * dConstrPart(0, kk);
324  }
325  calc.dvCallConstr(calc.dvMap.find(dvListMap.vec[kk]), 0)++;
326  for (int ll = 0; ll < nDvAct; ++ll)
327  {
328  double HconstrLag = HConstrPart(ll, kk) * calc.lagMult[constrPos];
329  if (!rsvs3d::utils::IsAproxEqual(HconstrLag, 0.0))
330  {
331  // TODO cross product with lagrangian
332  calc.HConstr_sparse.coeffRef(calc.dvMap.find(dvListMap.vec[ll]), calc.dvMap.find(dvListMap.vec[kk])) +=
333  triIn.connec.constrinfluence[ii] * HconstrLag;
334  }
335  }
336  }
337 }
Provides the infrastructure for calculation of the RSVS equations.
Provides internal tools for RSVS calc.
HashedVector< int, int > TriangleActiveDesignVariables(const triangle &triIn, const triangulation &triRSVS, const HashedVector< int, int > &objDvMap, bool useSurfCentreDeriv=true)
Get the active design variables defined by a triangle object.
void TrianglePositionDerivatives(const triangle &triIn, const triangulation &triRSVS, const HashedVector< int, int > &dvListMap, Eigen::MatrixXd &dPos, Eigen::MatrixXd &HPos, bool useSurfCentreDeriv=true, bool useSurfCentreHessian=false)
Calculate the positional derivatives of a triangle object.
grid::coordlist TrianglePointerCoordinates(const triangle &triIn, const triangulation &triRSVS)
Get all the coordinates needed to define a triangle.
Performs Volume and Area calculations for the RSVS process.
Provide std::vector container with hashed index mapping.
Class to handle the RSVS calculation.
Definition: RSVScalc.hpp:130
Eigen::MatrixXd dConstr
Constraint Jacobian, size: [nConstr, nDv].
Definition: RSVScalc.hpp:162
Eigen::MatrixXd HConstr
Constraint Hessian, size: [nDv, nDv].
Definition: RSVScalc.hpp:165
Eigen::VectorXd lagMult
Lagrangian multiplier, size: [nConstr, 1].
Definition: RSVScalc.hpp:179
HashedVector< int, int > dvMap
Maps the snake indices to the position in the design variable vector.
Definition: RSVScalc.hpp:202
Tools to support conversion, display and derivatives of Eigen matrices.
std::vector< const std::vector< double > * > coordlist
Defines a list of coordinates.
Definition: mesh.hpp:87
Provides various utility functions for the RSVS operation.
Provides a triangulation for snake and meshes.