gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
gmshLevelset.cpp
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 //
6 // Contributor(s):
7 // Gaetan Bricteux
8 //
9 
10 #include <queue>
11 #include <stack>
12 #include <cmath>
13 #include "gmshLevelset.h"
14 #include "fullMatrix.h"
15 #include "GModel.h"
16 #include "OS.h"
17 #include "MElement.h"
18 #include "Numeric.h"
19 #include "cartesian.h"
20 #include "GmshConfig.h"
21 #include "mathEvaluator.h"
22 
23 #if defined(HAVE_ANN)
24 #include "ANN/ANN.h"
25 #endif
26 
27 std::set<gLevelset *, gLevelsetLessThan> gLevelset::all_;
28 int gLevelset::maxTag_ = 0;
29 
31  const gLevelset *l2) const
32 {
33  return l1->getTag() < l2->getTag();
34 }
35 
37 {
38  gLevelset l(tag);
39  auto it = all_.find(&l);
40  if(it == all_.end()) return nullptr;
41  return *it;
42 }
43 
44 void gLevelset::add(gLevelset *l) { all_.insert(l); }
45 
46 void insertActiveCells(double x, double y, double z, double rmax,
48 {
49  int id1 = box.getCellContainingPoint(x - rmax, y - rmax, z - rmax);
50  int id2 = box.getCellContainingPoint(x + rmax, y + rmax, z + rmax);
51  int i1, j1, k1;
52  box.getCellIJK(id1, i1, j1, k1);
53  int i2, j2, k2;
54  box.getCellIJK(id2, i2, j2, k2);
55  for(int i = i1; i <= i2; i++)
56  for(int j = j1; j <= j2; j++)
57  for(int k = k1; k <= k2; k++)
58  box.insertActiveCell(box.getCellIndex(i, j, k));
59 }
60 
61 void fillPointCloud(GEdge *ge, double sampling, std::vector<SPoint3> &points)
62 {
63  Range<double> t_bounds = ge->parBounds(0);
64  double t_min = t_bounds.low();
65  double t_max = t_bounds.high();
66  double length = ge->length(t_min, t_max, 20);
67  int N = length / sampling;
68  for(int i = 0; i < N; i++) {
69  double t = t_min + (double)i / (double)(N - 1) * (t_max - t_min);
70  GPoint p = ge->point(t);
71  points.push_back(SPoint3(p.x(), p.y(), p.z()));
72  }
73 }
74 
76 {
77  cartesianBox<double> *child = parent->getChildBox();
78  if(!child) return 0;
79  int I = parent->getNxi();
80  int J = parent->getNeta();
81  int K = parent->getNzeta();
82  for(int i = 0; i < I; i++)
83  for(int j = 0; j < J; j++)
84  for(int k = 0; k < K; k++) {
85  // remove children if they do not entirely fill parent, or if
86  // there is no parent on the boundary
87  int idx[8] = {child->getCellIndex(2 * i, 2 * j, 2 * k),
88  child->getCellIndex(2 * i, 2 * j, 2 * k + 1),
89  child->getCellIndex(2 * i, 2 * j + 1, 2 * k),
90  child->getCellIndex(2 * i, 2 * j + 1, 2 * k + 1),
91  child->getCellIndex(2 * i + 1, 2 * j, 2 * k),
92  child->getCellIndex(2 * i + 1, 2 * j, 2 * k + 1),
93  child->getCellIndex(2 * i + 1, 2 * j + 1, 2 * k),
94  child->getCellIndex(2 * i + 1, 2 * j + 1, 2 * k + 1)};
95  bool exist[8], atLeastOne = false, butNotAll = false;
96  for(int ii = 0; ii < 8; ii++) {
97  exist[ii] = child->activeCellExists(idx[ii]);
98  if(exist[ii]) atLeastOne = true;
99  if(!exist[ii]) butNotAll = true;
100  }
101  if(atLeastOne &&
102  (butNotAll ||
103  (i != 0 &&
104  !parent->activeCellExists(parent->getCellIndex(i - 1, j, k))) ||
105  (i != I - 1 &&
106  !parent->activeCellExists(parent->getCellIndex(i + 1, j, k))) ||
107  (j != 0 &&
108  !parent->activeCellExists(parent->getCellIndex(i, j - 1, k))) ||
109  (j != J - 1 &&
110  !parent->activeCellExists(parent->getCellIndex(i, j + 1, k))) ||
111  (k != 0 &&
112  !parent->activeCellExists(parent->getCellIndex(i, j, k - 1))) ||
113  (k != K - 1 &&
114  !parent->activeCellExists(parent->getCellIndex(i, j, k + 1)))))
115  for(int ii = 0; ii < 8; ii++) child->eraseActiveCell(idx[ii]);
116  }
117  return removeBadChildCells(child);
118 }
119 
121 {
122  if(!box->getChildBox()) return;
123  for(int i = 0; i < box->getNxi(); i++)
124  for(int j = 0; j < box->getNeta(); j++)
125  for(int k = 0; k < box->getNzeta(); k++) {
126  if(box->activeCellExists(box->getCellIndex(i, j, k))) {
127  cartesianBox<double> *parent = box, *child;
128  int ii = i, jj = j, kk = k;
129  while((child = parent->getChildBox())) {
130  ii *= 2;
131  jj *= 2;
132  kk *= 2;
133  if(child->activeCellExists(child->getCellIndex(ii, jj, kk))) {
134  box->eraseActiveCell(box->getCellIndex(i, j, k));
135  break;
136  }
137  parent = child;
138  }
139  }
140  }
141  removeParentCellsWithChildren(box->getChildBox());
142 }
143 
145 {
146  std::vector<SPoint3> nodes;
147  std::vector<int> indices;
148  for(auto it = box.nodalValuesBegin(); it != box.nodalValuesEnd(); ++it) {
149  nodes.push_back(box.getNodeCoordinates(it->first));
150  indices.push_back(it->first);
151  }
152  // Msg::Info(" %d nodes in the grid at level %d", (int)nodes.size(),
153  // box.getLevel());
154  std::vector<double> dist, localdist;
155  std::vector<SPoint3> dummy;
156  for(auto fit = gm->firstFace(); fit != gm->lastFace(); fit++) {
157  if((*fit)->geomType() == GEntity::DiscreteSurface) {
158  for(std::size_t k = 0; k < (*fit)->getNumMeshElements(); k++) {
159  std::vector<double> iDistances;
160  std::vector<SPoint3> iClosePts;
161  std::vector<double> iDistancesE;
162  MElement *e = (*fit)->getMeshElement(k);
163  if(e->getType() == TYPE_TRI) {
164  MVertex *v1 = e->getVertex(0);
165  MVertex *v2 = e->getVertex(1);
166  MVertex *v3 = e->getVertex(2);
167  SPoint3 p1(v1->x(), v1->y(), v1->z());
168  SPoint3 p2(v2->x(), v2->y(), v2->z());
169  SPoint3 p3(v3->x(), v3->y(), v3->z());
170  // sign plus if in the direction of the normal
171  signedDistancesPointsTriangle(localdist, dummy, nodes, p2, p1, p3);
172  }
173  if(dist.empty())
174  dist = localdist;
175  else {
176  for(std::size_t j = 0; j < localdist.size(); j++) {
177  dist[j] =
178  (fabs(dist[j]) < fabs(localdist[j])) ? dist[j] : localdist[j];
179  }
180  }
181  }
182  }
183  else {
184  // we should use the STL here
185  Msg::Info("Levelset computation on CAD surface not implemented");
186  }
187  }
188 
189  for(std::size_t j = 0; j < dist.size(); j++)
190  box.setNodalValue(indices[j], dist[j]);
191 
192  if(box.getChildBox()) computeLevelset(gm, *box.getChildBox());
193 }
194 
195 inline double det3(double d11, double d12, double d13, double d21, double d22,
196  double d23, double d31, double d32, double d33)
197 {
198  return d11 * (d22 * d33 - d23 * d32) - d21 * (d12 * d33 - d13 * d32) +
199  d31 * (d12 * d23 - d13 * d22);
200 }
201 
202 inline void norm(const double *vec, double *norm)
203 {
204  double n = sqrt(vec[0] * vec[0] + vec[1] * vec[1] + vec[2] * vec[2]);
205  norm[0] = vec[0] / n;
206  norm[1] = vec[1] / n;
207  norm[2] = vec[2] / n;
208 }
209 
210 inline void cross(const double *pt0, const double *pt1, const double *pt2,
211  double *cross)
212 {
213  double v1[3] = {pt1[0] - pt0[0], pt1[1] - pt0[1], pt1[2] - pt0[2]};
214  double v2[3] = {pt2[0] - pt0[0], pt2[1] - pt0[1], pt2[2] - pt0[2]};
215  cross[0] = v1[1] * v2[2] - v2[1] * v1[2];
216  cross[1] = v2[0] * v1[2] - v1[0] * v2[2];
217  cross[2] = v1[0] * v2[1] - v2[0] * v1[1];
218 }
219 
220 inline bool isPlanar(const double *pt1, const double *pt2, const double *pt3,
221  const double *pt4)
222 {
223  double c1[3];
224  cross(pt1, pt2, pt3, c1);
225  double c2[3];
226  cross(pt1, pt2, pt4, c2);
227  double n1[3];
228  norm(c1, n1);
229  double n2[3];
230  norm(c2, n2);
231  return (n1[0] == n2[0] && n1[1] == n2[1] && n1[2] == n2[2]);
232 }
233 
234 inline double evalRadialFnDer(int p, int index, double dx, double dy, double dz,
235  double ep)
236 {
237  double r2 = dx * dx + dy * dy + dz * dz; // r^2
238  switch(index) {
239  case 0: // GA
240  switch(p) {
241  case 0: return exp(-ep * ep * r2);
242  case 1: return -2 * ep * ep * dx * exp(-ep * ep * r2); // _x
243  case 2: return -2 * ep * ep * dy * exp(-ep * ep * r2); // _y
244  case 3: return -2 * ep * ep * dz * exp(-ep * ep * r2); // _z
245  }
246  case 1: // MQ
247  switch(p) {
248  case 0: return sqrt(1 + ep * ep * r2);
249  case 1: return ep * ep * dx / sqrt(1 + ep * ep * r2);
250  case 2: return ep * ep * dy / sqrt(1 + ep * ep * r2);
251  case 3: return ep * ep * dz / sqrt(1 + ep * ep * r2);
252  }
253  }
254  return 0.;
255 }
256 
258 {
259  FILE *xyz = Fopen("myNodes.pos", "w");
260  if(xyz) {
261  fprintf(xyz, "View \"\"{\n");
262  for(int itv = 1; itv != myNodes.size1(); ++itv) {
263  fprintf(xyz, "SP(%g,%g,%g){%g};\n", myNodes(itv, 0), myNodes(itv, 1),
264  myNodes(itv, 2), surf(itv, 0));
265  }
266  fprintf(xyz, "};\n");
267  fclose(xyz);
268  }
269 }
270 
271 // extrude a list of the primitive levelsets with a "Level-order traversal
272 // sequence"
273 void gLevelset::getPrimitives(std::vector<gLevelset *> &gLsPrimitives)
274 {
275  std::queue<gLevelset *> Q;
276  Q.push(this);
277  while(!Q.empty()) {
278  gLevelset *p = Q.front();
279  std::vector<gLevelset *> pp;
280  pp = p->getChildren();
281  if(pp.empty()) gLsPrimitives.push_back(p);
282  Q.pop();
283  if(!pp.empty()) {
284  for(int i = 0; i < (int)pp.size(); i++) Q.push(pp[i]);
285  }
286  }
287 }
288 
289 // extrude a list of the primitive levelsets with a "post-order traversal
290 // sequence"
291 void gLevelset::getPrimitivesPO(std::vector<gLevelset *> &gLsPrimitives)
292 {
293  std::stack<gLevelset *> S;
294  std::stack<gLevelset *> Sc; // levelset checked
295  S.push(this);
296  while(!S.empty()) {
297  gLevelset *p = S.top();
298  std::vector<gLevelset *> pp;
299  pp = p->getChildren();
300  if(pp.empty()) {
301  gLsPrimitives.push_back(p);
302  S.pop();
303  }
304  else {
305  if(Sc.empty() || p != Sc.top()) {
306  for(int i = 1; i < (int)pp.size(); i++) Sc.push(p);
307  for(int i = (int)pp.size() - 1; i >= 0; i--) {
308  S.push(pp[i]);
309  if(i > 1) S.push(p);
310  }
311  }
312  else { // levelset has been checked
313  S.pop();
314  Sc.pop();
315  }
316  }
317  }
318 }
319 
320 // return a list with the levelsets in a "Reverse Polish Notation"
321 void gLevelset::getRPN(std::vector<gLevelset *> &gLsRPN)
322 {
323  std::stack<gLevelset *> S;
324  std::stack<gLevelset *> Sc; // levelset checked
325  S.push(this);
326  while(!S.empty()) {
327  gLevelset *p = S.top();
328  std::vector<gLevelset *> pp;
329  pp = p->getChildren();
330  if(pp.empty()) {
331  gLsRPN.push_back(p);
332  S.pop();
333  }
334  else {
335  if(Sc.empty() || p != Sc.top()) {
336  for(int i = 1; i < (int)pp.size(); i++) Sc.push(p);
337  for(int i = (int)pp.size() - 1; i >= 0; i--) {
338  S.push(pp[i]);
339  if(i > 1) S.push(p);
340  }
341  }
342  else { // levelset has been checked
343  S.pop();
344  Sc.pop();
345  gLsRPN.push_back(p);
346  }
347  }
348  }
349 }
350 
352 
353 gLevelsetSphere::gLevelsetSphere(const double &x, const double &y,
354  const double &z, const double &R, int tag)
355  : gLevelsetPrimitive(tag), xc(x), yc(y), zc(z), r(R)
356 {
357  _hasDerivatives = true;
358 }
359 
360 void gLevelsetSphere::gradient(double x, double y, double z, double &dfdx,
361  double &dfdy, double &dfdz) const
362 {
363  const double xx = x - xc, yy = y - yc, zz = z - zc,
364  dist = sqrt(xx * xx + yy * yy + zz * zz);
365 
366  dfdx = xx / dist;
367  dfdy = yy / dist;
368  dfdz = zz / dist;
369 }
370 
371 void gLevelsetSphere::hessian(double x, double y, double z, double &dfdxx,
372  double &dfdxy, double &dfdxz, double &dfdyx,
373  double &dfdyy, double &dfdyz, double &dfdzx,
374  double &dfdzy, double &dfdzz) const
375 {
376  const double xx = x - xc, yy = y - yc, zz = z - zc;
377  const double distSq = xx * xx + yy * yy, fact = 1. / (distSq * sqrt(distSq));
378 
379  dfdxx = (zz * zz + yy * yy) * fact;
380  dfdxy = -xx * yy * fact;
381  dfdxz = -xx * zz * fact;
382  dfdyx = dfdxy;
383  dfdyy = (xx * xx + zz * zz) * fact;
384  dfdyz = -yy * zz * fact;
385  dfdzx = dfdxz;
386  dfdzy = dfdyz;
387  dfdzz = (xx * xx + yy * yy) * fact;
388 }
389 
390 gLevelsetPlane::gLevelsetPlane(const std::vector<double> &pt,
391  const std::vector<double> &norm, int tag)
392  : gLevelsetPrimitive(tag)
393 {
394  a = norm[0];
395  b = norm[1];
396  c = norm[2];
397  d = -a * pt[0] - b * pt[1] - c * pt[2];
398 }
399 
400 gLevelsetPlane::gLevelsetPlane(const double *pt, const double *norm, int tag)
401  : gLevelsetPrimitive(tag)
402 {
403  a = norm[0];
404  b = norm[1];
405  c = norm[2];
406  d = -a * pt[0] - b * pt[1] - c * pt[2];
407 }
408 
409 gLevelsetPlane::gLevelsetPlane(const double *pt1, const double *pt2,
410  const double *pt3, int tag)
411  : gLevelsetPrimitive(tag)
412 {
413  a = det3(1., pt1[1], pt1[2], 1., pt2[1], pt2[2], 1., pt3[1], pt3[2]);
414  b = det3(pt1[0], 1., pt1[2], pt2[0], 1., pt2[2], pt3[0], 1., pt3[2]);
415  c = det3(pt1[0], pt1[1], 1., pt2[0], pt2[1], 1., pt3[0], pt3[1], 1.);
416  d = -det3(pt1[0], pt1[1], pt1[2], pt2[0], pt2[1], pt2[2], pt3[0], pt3[1],
417  pt3[2]);
418 }
419 
421  : gLevelsetPrimitive(lv)
422 {
423  a = lv.a;
424  b = lv.b;
425  c = lv.c;
426  d = lv.d;
427 }
428 
429 // level set defined by points (RBF interpolation)
432  const fullMatrix<double> &nodes1,
433  const fullMatrix<double> &nodes2) const
434 {
435  int m = nodes2.size1();
436  int n = nodes1.size1();
437  fullMatrix<double> rbfMat(m, n);
438 
439  double eps = 0.5 / delta;
440  for(int i = 0; i < m; i++) {
441  for(int j = 0; j < n; j++) {
442  double dx = nodes2(i, 0) - nodes1(j, 0);
443  double dy = nodes2(i, 1) - nodes1(j, 1);
444  double dz = nodes2(i, 2) - nodes1(j, 2);
445  rbfMat(i, j) = evalRadialFnDer(p, index, dx, dy, dz, eps);
446  }
447  }
448  return rbfMat;
449 }
450 
451 void gLevelsetPoints::RbfOp(int p, int index, const fullMatrix<double> &cntrs,
452  const fullMatrix<double> &nodes,
453  fullMatrix<double> &D, bool isLocal) const
454 {
455  fullMatrix<double> rbfMatB = generateRbfMat(p, index, cntrs, nodes);
456 
457  fullMatrix<double> rbfInvA;
458  if(isLocal) {
459  rbfInvA = generateRbfMat(0, index, cntrs, cntrs);
460  rbfInvA.invertInPlace();
461  }
462  else {
463  rbfInvA = matAInv;
464  }
465 
466  D.resize(nodes.size1(), cntrs.size1());
467  D.gemm(rbfMatB, rbfInvA, 1.0, 0.0);
468 }
469 
470 void gLevelsetPoints::evalRbfDer(int p, int index,
471  const fullMatrix<double> &cntrs,
472  const fullMatrix<double> &nodes,
473  const fullMatrix<double> &fValues,
474  fullMatrix<double> &fApprox,
475  bool isLocal) const
476 {
477  fApprox.resize(nodes.size1(), fValues.size2());
479  RbfOp(p, index, cntrs, nodes, D, isLocal);
480  fApprox.gemm(D, fValues, 1.0, 0.0);
481 }
482 
484  fullMatrix<double> &level_set_nodes,
485  fullMatrix<double> &level_set_funvals)
486 {
487  int numNodes = cntrs.size1();
488  int nTot = 3 * numNodes;
489  double normFactor;
490  level_set_nodes.resize(nTot, 3);
491  level_set_funvals.resize(nTot, 1);
492  fullMatrix<double> ONES(numNodes + 1, 1), sx(numNodes, 1), sy(numNodes, 1);
493  fullMatrix<double> sz(numNodes, 1), norms(numNodes, 3),
494  cntrsPlus(numNodes + 1, 3);
495 
496  // Computes the normal vectors to the surface at each node
497  double dist_min = 1.e6;
498  double dist_max = 1.e-6;
499  for(int i = 0; i < numNodes; ++i) {
500  ONES(i, 0) = 1.0;
501  cntrsPlus(i, 0) = cntrs(i, 0);
502  cntrsPlus(i, 1) = cntrs(i, 1);
503  cntrsPlus(i, 2) = cntrs(i, 2);
504  for(int j = i + 1; j < numNodes; j++) {
505  double dist =
506  sqrt((cntrs(i, 0) - cntrs(j, 0)) * (cntrs(i, 0) - cntrs(j, 0)) +
507  (cntrs(i, 1) - cntrs(j, 1)) * (cntrs(i, 1) - cntrs(j, 1)) +
508  (cntrs(i, 2) - cntrs(j, 2)) * (cntrs(i, 2) - cntrs(j, 2)));
509  if(dist < dist_min) dist_min = dist;
510  if(dist > dist_max) dist_max = dist;
511  }
512  }
513  ONES(numNodes, 0) = -1.0;
514  cntrsPlus(numNodes, 0) = cntrs(0, 0) + dist_max;
515  cntrsPlus(numNodes, 1) = cntrs(0, 1) + dist_max;
516  cntrsPlus(numNodes, 2) = cntrs(0, 2) + dist_max;
517 
518  delta = 0.23 * dist_min;
519  evalRbfDer(1, 1, cntrsPlus, cntrs, ONES, sx, true);
520  evalRbfDer(2, 1, cntrsPlus, cntrs, ONES, sy, true);
521  evalRbfDer(3, 1, cntrsPlus, cntrs, ONES, sz, true);
522  for(int i = 0; i < numNodes; ++i) {
523  normFactor =
524  sqrt(sx(i, 0) * sx(i, 0) + sy(i, 0) * sy(i, 0) + sz(i, 0) * sz(i, 0));
525  sx(i, 0) = sx(i, 0) / normFactor;
526  sy(i, 0) = sy(i, 0) / normFactor;
527  sz(i, 0) = sz(i, 0) / normFactor;
528  norms(i, 0) = sx(i, 0);
529  norms(i, 1) = sy(i, 0);
530  norms(i, 2) = sz(i, 0);
531  }
532 
533  for(int i = 0; i < numNodes; ++i) {
534  for(int j = 0; j < 3; ++j) {
535  level_set_nodes(i, j) = cntrs(i, j);
536  level_set_nodes(i + numNodes, j) = cntrs(i, j) - delta * norms(i, j);
537  level_set_nodes(i + 2 * numNodes, j) = cntrs(i, j) + delta * norms(i, j);
538  }
539  level_set_funvals(i, 0) = 0.0;
540  level_set_funvals(i + numNodes, 0) = -1;
541  level_set_funvals(i + 2 * numNodes, 0) = 1;
542  }
543 }
544 
546  : gLevelsetPrimitive(tag)
547 {
548  int nbNodes = 3 * centers.size1();
549 
550  setup_level_set(centers, points, surf);
552 
553  // build invA matrix for 3*n points
554  int indexRBF = 1;
555  matAInv.resize(nbNodes, nbNodes);
556  matAInv = generateRbfMat(0, indexRBF, points, points);
558 }
559 
561  : gLevelsetPrimitive(lv)
562 {
563  points = lv.points;
564 }
565 
566 double gLevelsetPoints::operator()(double x, double y, double z) const
567 {
568  if(mapP.empty())
569  Msg::Info("Levelset Points : call computeLS() before calling operator()\n");
570 
571  SPoint3 sp(x, y, z);
572  auto it = mapP.find(sp);
573  if(it != mapP.end()) return it->second;
574  printf("Levelset Points : Point not found\n");
575  return 0;
576 
577  // fullMatrix<double> xyz_eval(1, 3), surf_eval(1,1);
578  // xyz_eval(0,0) = x;
579  // xyz_eval(0,1) = y;
580  // xyz_eval(0,2) = z;
581  // evalRbfDer(0, 1, points, xyz_eval, surf, surf_eval);
582  // return surf_eval(0,0);
583 }
584 
585 void gLevelsetPoints::computeLS(std::vector<MVertex *> &vert)
586 {
587  fullMatrix<double> xyz_eval(vert.size(), 3), surf_eval(vert.size(), 1);
588  for(std::size_t i = 0; i < vert.size(); i++) {
589  xyz_eval(i, 0) = vert[i]->x();
590  xyz_eval(i, 1) = vert[i]->y();
591  xyz_eval(i, 2) = vert[i]->z();
592  }
593  evalRbfDer(0, 1, points, xyz_eval, surf, surf_eval);
594  for(std::size_t i = 0; i < vert.size(); i++) {
595  mapP[SPoint3(vert[i]->x(), vert[i]->y(), vert[i]->z())] = surf_eval(i, 0);
596  }
597 }
598 
599 /*
600  assume a quadric
601  x^T A x + b^T x + c = 0
602 
603  typically, we add a rotation x -> R x
604  x^T (R^T A R) x + b^T R x + c = 0
605 
606  and a translation x -> x - t
607  x^T A x + [b^T - 2 A t] x + [c - b^T t + t^T A t ] = 0
608 */
609 
611  : gLevelsetPrimitive(lv)
612 {
613  for(int i = 0; i < 3; i++) {
614  B[i] = lv.B[i];
615  for(int j = 0; j < 3; j++) A[i][j] = lv.A[i][j];
616  }
617  C = lv.C;
618 }
619 
620 void gLevelsetQuadric::Ax(const double x[3], double res[3], double fact)
621 {
622  for(int i = 0; i < 3; i++) {
623  res[i] = 0.;
624  for(int j = 0; j < 3; j++) { res[i] += A[i][j] * x[j] * fact; }
625  }
626 }
627 
628 void gLevelsetQuadric::xAx(const double x[3], double &res, double fact)
629 {
630  res = fact * (A[0][0] * x[0] * x[0] + A[1][1] * x[1] * x[1] +
631  A[2][2] * x[2] * x[2] + A[1][0] * x[1] * x[0] * 2. +
632  A[2][0] * x[2] * x[0] * 2. + A[1][2] * x[1] * x[2] * 2.);
633 }
634 
635 void gLevelsetQuadric::translate(const double transl[3])
636 {
637  double b;
638  xAx(transl, b, 1.0);
639  C += (-B[0] * transl[0] - B[1] * transl[1] - B[2] * transl[2] + b);
640 
641  double x[3];
642  Ax(transl, x, 2.0);
643  B[0] += -x[0];
644  B[1] += -x[1];
645  B[2] += -x[2];
646 }
647 
648 void gLevelsetQuadric::rotate(const double rotate[3][3])
649 {
650  double a11 = 0., a12 = 0., a13 = 0., a22 = 0., a23 = 0., a33 = 0.;
651  double b1 = 0., b2 = 0., b3 = 0.;
652  for(int i = 0; i < 3; i++) {
653  b1 += B[i] * rotate[i][0];
654  b2 += B[i] * rotate[i][1];
655  b3 += B[i] * rotate[i][2];
656  for(int j = 0; j < 3; j++) {
657  a11 += rotate[i][0] * A[i][j] * rotate[j][0];
658  a12 += rotate[i][0] * A[i][j] * rotate[j][1];
659  a13 += rotate[i][0] * A[i][j] * rotate[j][2];
660  a22 += rotate[i][1] * A[i][j] * rotate[j][1];
661  a23 += rotate[i][1] * A[i][j] * rotate[j][2];
662  a33 += rotate[i][2] * A[i][j] * rotate[j][2];
663  }
664  }
665  A[0][0] = a11;
666  A[0][1] = A[1][0] = a12;
667  A[0][2] = A[2][0] = a13;
668  A[1][1] = a22;
669  A[1][2] = A[2][1] = a23;
670  A[2][2] = a33;
671  B[0] = b1;
672  B[1] = b2;
673  B[2] = b3;
674 }
675 
676 // computes the rotation matrix of the rotation of the vector (0,0,1) to dir
678  double t[3][3])
679 {
680  double norm = sqrt(dir[0] * dir[0] + dir[1] * dir[1]);
681  double n[3] = {1., 0., 0.};
682  double ct = 1., st = 0.;
683  if(norm != 0.) {
684  double theta = atan(norm / dir[2]);
685  n[0] = dir[1] / norm;
686  n[1] = -dir[0] / norm;
687  ct = cos(theta);
688  st = sin(theta);
689  }
690  t[0][0] = n[0] * n[0] * (1. - ct) + ct;
691  t[0][1] = n[0] * n[1] * (1. - ct) - n[2] * st;
692  t[0][2] = n[0] * n[2] * (1. - ct) + n[1] * st;
693  t[1][0] = n[1] * n[0] * (1. - ct) + n[2] * st;
694  t[1][1] = n[1] * n[1] * (1. - ct) + ct;
695  t[1][2] = n[1] * n[2] * (1. - ct) - n[0] * st;
696  t[2][0] = n[2] * n[0] * (1. - ct) - n[1] * st;
697  t[2][1] = n[2] * n[1] * (1. - ct) + n[0] * st;
698  t[2][2] = n[2] * n[2] * (1. - ct) + ct;
699 }
700 
701 void gLevelsetQuadric::computeRotationMatrix(const double dir1[3],
702  const double dir2[3],
703  double t[3][3])
704 {
705  double norm = sqrt((dir1[1] * dir2[2] - dir1[2] * dir2[1]) *
706  (dir1[1] * dir2[2] - dir1[2] * dir2[1]) +
707  (dir1[2] * dir2[0] - dir1[0] * dir2[2]) *
708  (dir1[2] * dir2[0] - dir1[0] * dir2[2]) +
709  (dir1[0] * dir2[1] - dir1[1] * dir2[0]) *
710  (dir1[0] * dir2[1] - dir1[1] * dir2[0]));
711  double n[3] = {1., 0., 0.};
712  double ct = 1., st = 0.;
713  if(norm != 0.) {
714  st = norm / ((dir1[0] * dir1[0] + dir1[1] * dir1[1] + dir1[2] * dir1[2]) *
715  (dir2[0] * dir2[0] + dir2[1] * dir2[1] + dir2[2] * dir2[2]));
716  n[0] = (dir1[1] * dir2[2] - dir1[2] * dir2[1]) / norm;
717  n[1] = (dir1[2] * dir2[0] - dir1[0] * dir2[2]) / norm;
718  n[2] = (dir1[0] * dir2[1] - dir1[1] * dir2[0]) / norm;
719  ct = cos(asin(st));
720  }
721  t[0][0] = n[0] * n[0] * (1. - ct) + ct;
722  t[0][1] = n[0] * n[1] * (1. - ct) - n[2] * st;
723  t[0][2] = n[0] * n[2] * (1. - ct) + n[1] * st;
724  t[1][0] = n[1] * n[0] * (1. - ct) + n[2] * st;
725  t[1][1] = n[1] * n[1] * (1. - ct) + ct;
726  t[1][2] = n[1] * n[2] * (1. - ct) - n[0] * st;
727  t[2][0] = n[2] * n[0] * (1. - ct) - n[1] * st;
728  t[2][1] = n[2] * n[1] * (1. - ct) + n[0] * st;
729  t[2][2] = n[2] * n[2] * (1. - ct) + ct;
730 }
731 
733 {
734  for(int i = 0; i < 3; i++) {
735  B[i] = 0.;
736  for(int j = 0; j < 3; j++) A[i][j] = 0.;
737  }
738  C = 0.;
739 }
740 
741 double gLevelsetQuadric::operator()(double x, double y, double z) const
742 {
743  return (A[0][0] * x * x + 2. * A[0][1] * x * y + 2. * A[0][2] * x * z +
744  A[1][1] * y * y + 2. * A[1][2] * y * z + A[2][2] * z * z + B[0] * x +
745  B[1] * y + B[2] * z + C);
746 }
747 
748 gLevelsetShamrock::gLevelsetShamrock(double _xmid, double _ymid, double _zmid,
749  double _a, double _b, int _c, int tag)
750  : gLevelsetPrimitive(tag), xmid(_xmid), a(_a), b(_b), c(_c)
751 {
752  // creating the iso-zero
753  double angle = 0.;
754  double r;
755  while(angle <= 2. * M_PI) {
756  r = a + b * sin(c * angle);
757  iso_x.push_back(r * sin(angle) + xmid);
758  iso_y.push_back(r * cos(angle) + xmid);
759  angle += 2. * M_PI / 1000.;
760  }
761 }
762 
763 double gLevelsetShamrock::operator()(double x, double y, double z) const
764 {
765  // computing distance to pre-defined (sampled) iso-zero
766  double dx, dy, xi, yi, d;
767  dx = x - iso_x[0];
768  dy = y - iso_y[0];
769  double distance = sqrt(dx * dx + dy * dy);
770  auto itx = iso_x.begin();
771  auto itxen = iso_x.end();
772  auto ity = iso_y.begin();
773  auto itminx = iso_x.begin();
774  auto itminy = iso_y.begin();
775  itx++;
776  ity++;
777  for(; itx != itxen; itx++, ity++) {
778  xi = *itx;
779  yi = *ity;
780  dx = x - xi;
781  dy = y - yi;
782  d = sqrt(dx * dx + dy * dy);
783  if(distance > d) {
784  distance = d;
785  itminx = itx;
786  itminy = ity;
787  }
788  }
789  // still need to find the LS sign... using vectorial prod with tangent vector
790  // if not, the LS gradient is discontinuous on iso-zero... oups !
791  SVector3 t, p;
792  p(0) = (*itminx) - x;
793  p(1) = (*itminy) - y;
794  if(itminx == (itxen - 1)) {
795  t(0) = iso_x[0] - (*itminx);
796  t(1) = iso_y[0] - (*itminy);
797  }
798  else {
799  t(0) = (*(itminx + 1)) - (*itminx);
800  t(1) = (*(itminy + 1)) - (*itminy);
801  }
802  double vectprod = (p(0) * t(1) - p(1) * t(0));
803  double sign = (vectprod < 0.) ? -1. : 1.;
804 
805  return sign * distance;
806 }
807 
808 gLevelsetPopcorn::gLevelsetPopcorn(double myxc, double myyc, double myzc,
809  double myr0, double myA, double mysigma,
810  int tag)
811  : gLevelsetPrimitive(tag)
812 {
813  A = myA;
814  sigma = mysigma;
815  r0 = myr0;
816  xc = myxc;
817  yc = myyc;
818  zc = myzc;
819 }
820 
821 double gLevelsetPopcorn::operator()(double x, double y, double z) const
822 {
823  double s2 = sigma * sigma;
824  double r =
825  sqrt((x - xc) * (x - xc) + (y - yc) * (y - yc) + (z - zc) * (z - zc));
826  // printf("z=%g zc=%g r=%g \n", z, zc, r);
827  double val = r - r0;
828  for(int k = 0; k < 5; k++) {
829  double xk = r0 / sqrt(5.0) * (2. * cos(2 * k * M_PI / 5.0));
830  double yk = r0 / sqrt(5.0) * (2. * sin(2 * k * M_PI / 5.0));
831  double zk = r0 / sqrt(5.0);
832  val -=
833  A * exp(-((x - xc - xk) * (x - xc - xk) + (y - yc - yk) * (y - yc - yk) +
834  (z - zc - zk) * (z - zc - zk)) /
835  s2);
836  }
837  for(int k = 5; k < 10; k++) {
838  double xk = r0 / sqrt(5.0) * (2. * cos((2. * (k - 5.) - 1.) * M_PI / 5.0));
839  double yk = r0 / sqrt(5.0) * (2. * sin((2. * (k - 5.) - 1.) * M_PI / 5.0));
840  double zk = -r0 / sqrt(5.0);
841  val -=
842  A * exp(-((x - xc - xk) * (x - xc - xk) + (y - yc - yk) * (y - yc - yk) +
843  (z - zc - zk) * (z - zc - zk)) /
844  s2);
845  }
846  val -= A * exp(-((x - xc) * (x - xc) + (y - yc) * (y - yc) +
847  (z - zc - r0) * (z - zc - r0)) /
848  s2);
849  val -= A * exp(-((x - xc) * (x - xc) + (y - yc) * (y - yc) +
850  (z - zc + r0) * (z - zc + r0)) /
851  s2);
852  return val;
853 }
854 
855 gLevelsetMathEval::gLevelsetMathEval(const std::string &f, int tag)
856  : gLevelsetPrimitive(tag)
857 {
858  std::vector<std::string> expressions(1, f);
859  std::vector<std::string> variables(3);
860  variables[0] = "x";
861  variables[1] = "y";
862  variables[2] = "z";
863  _expr = new mathEvaluator(expressions, variables);
864 }
865 
867 {
868  if(_expr) delete _expr;
869 }
870 
871 double gLevelsetMathEval::operator()(double x, double y, double z) const
872 {
873  std::vector<double> values(3), res(1);
874  values[0] = x;
875  values[1] = y;
876  values[2] = z;
877  if(_expr->eval(values, res)) return res[0];
878  return 1.;
879 }
880 
881 gLevelsetMathEvalAll::gLevelsetMathEvalAll(std::vector<std::string> expressions,
882  int tag)
883  : gLevelsetPrimitive(tag)
884 {
885  _hasDerivatives = true;
886  std::vector<std::string> variables(3);
887  variables[0] = "x";
888  variables[1] = "y";
889  variables[2] = "z";
890  _expr = new mathEvaluator(expressions, variables);
891 }
892 
894 {
895  if(_expr) delete _expr;
896 }
897 
898 double gLevelsetMathEvalAll::operator()(double x, double y, double z) const
899 {
900  std::vector<double> values(3), res(13);
901  values[0] = x;
902  values[1] = y;
903  values[2] = z;
904  if(_expr->eval(values, res)) return res[0];
905  return 1.;
906 }
907 
908 void gLevelsetMathEvalAll::gradient(double x, double y, double z, double &dfdx,
909  double &dfdy, double &dfdz) const
910 {
911  std::vector<double> values(3), res(13);
912  values[0] = x;
913  values[1] = y;
914  values[2] = z;
915  if(_expr->eval(values, res)) {
916  dfdx = res[1];
917  dfdy = res[2];
918  dfdz = res[3];
919  }
920 }
921 
922 void gLevelsetMathEvalAll::hessian(double x, double y, double z, double &dfdxx,
923  double &dfdxy, double &dfdxz, double &dfdyx,
924  double &dfdyy, double &dfdyz, double &dfdzx,
925  double &dfdzy, double &dfdzz) const
926 {
927  std::vector<double> values(3), res(13);
928  values[0] = x;
929  values[1] = y;
930  values[2] = z;
931  if(_expr->eval(values, res)) {
932  dfdxx = res[4];
933  dfdxy = res[5];
934  dfdxz = res[6];
935  dfdyx = res[7];
936  dfdyy = res[8];
937  dfdyz = res[9];
938  dfdzx = res[10];
939  dfdzy = res[11];
940  dfdzz = res[12];
941  }
942 }
943 
944 #if defined(HAVE_ANN)
945 gLevelsetDistMesh::gLevelsetDistMesh(GModel *gm, const std::string &physical,
946  int nbClose, int tag)
947  : gLevelsetPrimitive(tag), _nbClose(nbClose)
948 {
949  std::map<int, std::vector<GEntity *> > groups[4];
950  gm->getPhysicalGroups(groups);
951  for(auto it = gm->firstPhysicalName(); it != gm->lastPhysicalName(); ++it) {
952  if(it->second == physical) {
953  _entities = groups[it->first.first][it->first.second];
954  }
955  }
956  if(_entities.size() == 0) {
957  Msg::Error(
958  "distanceToMesh: the physical name '%s' does not exist in the GModel",
959  physical.c_str());
960  }
961 
962  // setup
963  std::set<MVertex *> _all;
964  for(std::size_t i = 0; i < _entities.size(); i++) {
965  for(std::size_t k = 0; k < _entities[i]->getNumMeshElements(); k++) {
966  MElement *e = _entities[i]->getMeshElement(k);
967  for(std::size_t j = 0; j < e->getNumVertices(); j++) {
968  MVertex *v = _entities[i]->getMeshElement(k)->getVertex(j);
969  _all.insert(v);
970  _v2e.insert(std::make_pair(v, e));
971  }
972  }
973  }
974  ANNpointArray nodes;
975  nodes = annAllocPts(_all.size(), 3);
976  auto itp = _all.begin();
977  int ind = 0;
978  while(itp != _all.end()) {
979  MVertex *pt = *itp;
980  nodes[ind][0] = pt->x();
981  nodes[ind][1] = pt->y();
982  nodes[ind][2] = pt->z();
983  _vertices.push_back(pt);
984  itp++;
985  ind++;
986  }
987  _kdtree = new ANNkd_tree(nodes, _all.size(), 3);
988 }
989 
990 gLevelsetDistMesh::~gLevelsetDistMesh()
991 {
992  if(_kdtree) {
993  ANNpointArray nodes = _kdtree->thePoints();
994  annDeallocPts(nodes);
995  delete _kdtree;
996  }
997 }
998 
999 double gLevelsetDistMesh::operator()(double x, double y, double z) const
1000 {
1001  std::vector<ANNidx> index(_nbClose);
1002  std::vector<ANNdist> dist(_nbClose);
1003  double point[3] = {x, y, z};
1004  SPoint3 pt(x, y, z);
1005  _kdtree->annkSearch(point, _nbClose, &index[0],
1006  &dist[0]); // squared distances
1007  std::set<MElement *> elements;
1008  int dimE = 1;
1009  for(int i = 0; i < _nbClose; i++) {
1010  int iVertex = index[i];
1011  MVertex *v = _vertices[iVertex];
1012  for(auto itm = _v2e.lower_bound(v); itm != _v2e.upper_bound(v); ++itm) {
1013  elements.insert(itm->second);
1014  dimE = itm->second->getDim();
1015  }
1016  }
1017  double minDistance = 1.e22;
1019  std::vector<MElement *> closestElements;
1020  for(auto it = elements.begin(); it != elements.end(); ++it) {
1021  double distance = 0.;
1022  MVertex *v1 = (*it)->getVertex(0);
1023  MVertex *v2 = (*it)->getVertex(1);
1024  SPoint3 p1(v1->x(), v1->y(), v1->z());
1025  SPoint3 p2(v2->x(), v2->y(), v2->z());
1026  SPoint3 closePt;
1027  if(dimE == 1) {
1028  signedDistancePointLine(p1, p2, pt, distance, closePt); // !! > 0
1029  }
1030  else if(dimE == 2) {
1031  MVertex *v3 = (*it)->getVertex(2);
1032  SPoint3 p3(v3->x(), v3->y(), v3->z());
1033  if(p1 == p2 || p1 == p3 || p2 == p3)
1034  distance = 1.e22;
1035  else
1036  signedDistancePointTriangle(p1, p2, p3, pt, distance, closePt);
1037  }
1038  else {
1039  Msg::Error("Cannot compute a distance to an entity of dimension %d\n",
1040  dimE);
1041  }
1042  if(dimE == 1 && fabs(distance) < fabs(minDistance)) {
1043  minDistance = distance;
1044  }
1045  else if(dimE == 2) {
1046  if(fabs(distance) - fabs(minDistance) < 1.e-9) {
1047  closestElements.push_back(*it);
1048  }
1049  else if(fabs(distance) < fabs(minDistance)) {
1050  closestPoint = closePt;
1051  minDistance = distance;
1052  closestElements.clear();
1053  closestElements.push_back(*it);
1054  }
1055  }
1056  }
1057  if(closestElements.size() > 1) {
1058  SVector3 vd(closestPoint, pt);
1059  SVector3 meanNorm(0., 0., 0.); // angle weighted mean normal
1060  if(closestElements.size() == 2) { // closestPoint on edge
1061  meanNorm = closestElements[0]->getFace(0).normal() +
1062  closestElements[1]->getFace(0).normal();
1063  }
1064  else { // closestPoint on vertex
1065  for(std::size_t i = 0; i < closestElements.size(); i++) {
1066  double alpha = 0.;
1067  SPoint3 p1;
1068  bool found = false;
1069  for(int j = 0; j < closestElements[i]->getNumEdges(); j++) {
1070  SPoint3 ep0 = closestElements[i]->getEdge(j).getVertex(0)->point();
1071  SPoint3 ep1 = closestElements[i]->getEdge(j).getVertex(1)->point();
1072  if(closestPoint == ep0) {
1073  if(!found) {
1074  p1 = ep1;
1075  found = true;
1076  }
1077  else {
1078  alpha =
1080  break;
1081  }
1082  }
1083  if(closestPoint == ep1) {
1084  if(!found) {
1085  p1 = ep0;
1086  found = true;
1087  }
1088  else {
1089  alpha =
1091  break;
1092  }
1093  }
1094  }
1095  meanNorm = meanNorm + alpha * closestElements[i]->getFace(0).normal();
1096  }
1097  }
1098  double dotDN = dot(vd, closestElements[0]->getFace(0).normal());
1099  double dotDE = dot(vd, meanNorm);
1100  if(dotDN * dotDE < 0.) minDistance *= -1.;
1101  }
1102 
1103  return -1.0 * minDistance;
1104 }
1105 #endif
1106 
1107 #if defined(HAVE_POST)
1108 gLevelsetPostView::gLevelsetPostView(int index, int tag)
1109  : gLevelsetPrimitive(tag), _viewIndex(index)
1110 {
1111  if(_viewIndex >= 0 && _viewIndex < (int)PView::list.size()) {
1112  PView *view = PView::list[_viewIndex];
1113  _octree = new OctreePost(view);
1114  }
1115  else {
1116  Msg::Error("Unknown View[%d] in PostView levelset", _viewIndex);
1117  _octree = nullptr;
1118  }
1119 }
1120 
1121 double gLevelsetPostView::operator()(double x, double y, double z) const
1122 {
1123  if(!_octree) return 1.;
1124  double val = 1.;
1125  _octree->searchScalar(x, y, z, &val, 0);
1126  return val;
1127 }
1128 #endif
1129 
1130 gLevelsetGenCylinder::gLevelsetGenCylinder(const double *pt, const double *dir,
1131  const double &R, int tag)
1132  : gLevelsetQuadric(tag)
1133 {
1134  A[0][0] = 1.;
1135  A[1][1] = 1.;
1136  C = -R * R;
1137  double rot[3][3];
1138  computeRotationMatrix(dir, rot);
1139  rotate(rot);
1140  translate(pt);
1141 }
1142 
1144  : gLevelsetQuadric(lv)
1145 {
1146 }
1147 
1148 gLevelsetEllipsoid::gLevelsetEllipsoid(const double *pt, const double *dir,
1149  const double &a, const double &b,
1150  const double &c, int tag)
1151  : gLevelsetQuadric(tag)
1152 {
1153  A[0][0] = 1. / (a * a);
1154  A[1][1] = 1. / (b * b);
1155  A[2][2] = 1. / (c * c);
1156  C = -1.;
1157  double rot[3][3];
1158  computeRotationMatrix(dir, rot);
1159  rotate(rot);
1160  translate(pt);
1161 }
1162 
1164  : gLevelsetQuadric(lv)
1165 {
1166 }
1167 
1168 gLevelsetCone::gLevelsetCone(const double *pt, const double *dir,
1169  const double &angle, int tag)
1170  : gLevelsetQuadric(tag)
1171 {
1172  A[0][0] = 1.;
1173  A[1][1] = 1.;
1174  A[2][2] = -tan(angle) * tan(angle);
1175  double rot[3][3];
1176  computeRotationMatrix(dir, rot);
1177  rotate(rot);
1178  translate(pt);
1179 }
1180 
1182 
1184  const double *pt, const double *dir, const double &x2, const double &y2,
1185  const double &z2, const double &z, const double &c, int tag)
1186  : gLevelsetQuadric(tag)
1187 {
1188  A[0][0] = x2;
1189  A[1][1] = y2;
1190  A[2][2] = z2;
1191  B[2] = z;
1192  C = c;
1193  double rot[3][3];
1194  computeRotationMatrix(dir, rot);
1195  rotate(rot);
1196  translate(pt);
1197 }
1198 
1200  const gLevelsetGeneralQuadric &lv)
1201  : gLevelsetQuadric(lv)
1202 {
1203 }
1204 
1206 {
1207  std::vector<gLevelset *> _children = lv.getChildren();
1208  unsigned siz = _children.size();
1209  children.resize(siz);
1210  for(unsigned i = 0; i < siz; ++i) children[i] = _children[i]->clone();
1211 }
1212 
1213 gLevelsetYarn::gLevelsetYarn(int dim, int phys, double minA, double majA,
1214  int type, int tag)
1215  : gLevelsetPrimitive(tag) //, minorAxis(minA), majorAxis(majA), typeLs(type)
1216 {
1217  std::map<int, std::vector<GEntity *> > groups;
1218  GModel::current()->getPhysicalGroups(dim, groups);
1219  entities = groups[phys];
1220  if(!entities.size())
1221  printf("No physical %d found for levelset yarn!\n", phys);
1222 }
1223 
1224 double gLevelsetYarn::operator()(double x, double y, double z) const
1225 {
1226  double dist = 0.0;
1227  for(std::size_t i = 0; i < entities.size(); i++) {
1228  GEntity *g = entities[i];
1229  for(std::size_t j = 0; j < g->getNumMeshElements(); j++) {
1230  MElement *e = g->getMeshElement(j);
1231  MVertex *v1 = e->getVertex(0);
1232  MVertex *v2 = e->getVertex(1);
1233  SPoint3 p1(v1->x(), v1->y(), v1->z());
1234  SPoint3 p2(v2->x(), v2->y(), v2->z());
1235  /*if(e->getType() == TYPE_LIN){
1236  signedDistancesPointsEllipseLine(iDistances, iDistancesE, iIsInYarn,
1237  iClosePts, pts, p1, p2, majorAxis, minorAxis, majorAxis, minorAxis,
1238  typeLs);
1239  }
1240  else if(e->getType() == TYPE_TRI){
1241  MVertex *v3 = e->getVertex(2);
1242  SPoint3 p3(v3->x(),v3->y(),v3->z());
1243  signedDistancesPointsTriangle(iDistances, iClosePts, pts, p1, p2, p3);
1244  }*/
1245  }
1246  }
1247  return dist;
1248 }
1249 
1251  : gLevelset(lv)
1252 {
1253  Ls = lv.Ls->clone();
1254 }
1255 
1256 gLevelsetBox::gLevelsetBox(const double *pt, const double *dir1,
1257  const double *dir2, const double *dir3,
1258  const double &a, const double &b, const double &c,
1259  int tag)
1260  : gLevelsetImproved()
1261 {
1262  double dir1m[3] = {-dir1[0], -dir1[1], -dir1[2]};
1263  double dir2m[3] = {-dir2[0], -dir2[1], -dir2[2]};
1264  double dir3m[3] = {-dir3[0], -dir3[1], -dir3[2]};
1265  double n1[3];
1266  norm(dir1, n1);
1267  double n2[3];
1268  norm(dir2, n2);
1269  double n3[3];
1270  norm(dir3, n3);
1271  double pt2[3] = {pt[0] + a * n1[0] + b * n2[0] + c * n3[0],
1272  pt[1] + a * n1[1] + b * n2[1] + c * n3[1],
1273  pt[2] + a * n1[2] + b * n2[2] + c * n3[2]};
1274  std::vector<gLevelset *> p;
1275  p.push_back(new gLevelsetPlane(pt2, dir3, tag++));
1276  p.push_back(new gLevelsetPlane(pt, dir3m, tag++));
1277  p.push_back(new gLevelsetPlane(pt, dir2m, tag++));
1278  p.push_back(new gLevelsetPlane(pt2, dir2, tag++));
1279  p.push_back(new gLevelsetPlane(pt2, dir1, tag++));
1280  p.push_back(new gLevelsetPlane(pt, dir1m, tag));
1281  Ls = new gLevelsetIntersection(p);
1282 }
1283 
1284 gLevelsetBox::gLevelsetBox(const double *pt1, const double *pt2,
1285  const double *pt3, const double *pt4,
1286  const double *pt5, const double *pt6,
1287  const double *pt7, const double *pt8, int tag)
1288  : gLevelsetImproved()
1289 {
1290  if(!isPlanar(pt1, pt2, pt3, pt4) || !isPlanar(pt5, pt6, pt7, pt8) ||
1291  !isPlanar(pt1, pt2, pt5, pt6) || !isPlanar(pt3, pt4, pt7, pt8) ||
1292  !isPlanar(pt1, pt4, pt5, pt8) || !isPlanar(pt2, pt3, pt6, pt7))
1293  printf(
1294  "WARNING : faces of the box are not planar! %d, %d, %d, %d, %d, %d\n",
1295  isPlanar(pt1, pt2, pt3, pt4), isPlanar(pt5, pt6, pt7, pt8),
1296  isPlanar(pt1, pt2, pt5, pt6), isPlanar(pt3, pt4, pt7, pt8),
1297  isPlanar(pt1, pt4, pt5, pt8), isPlanar(pt2, pt3, pt6, pt7));
1298  std::vector<gLevelset *> p;
1299  p.push_back(new gLevelsetPlane(pt5, pt6, pt8, tag++));
1300  p.push_back(new gLevelsetPlane(pt1, pt4, pt2, tag++));
1301  p.push_back(new gLevelsetPlane(pt1, pt2, pt5, tag++));
1302  p.push_back(new gLevelsetPlane(pt3, pt4, pt7, tag++));
1303  p.push_back(new gLevelsetPlane(pt2, pt3, pt6, tag++));
1304  p.push_back(new gLevelsetPlane(pt1, pt5, pt4, tag));
1305  Ls = new gLevelsetIntersection(p);
1306 }
1307 
1309 
1310 gLevelsetCylinder::gLevelsetCylinder(const std::vector<double> &pt,
1311  const std::vector<double> &dir,
1312  const double &R, const double &H, int tag)
1313  : gLevelsetImproved()
1314 {
1315  double pt1[3] = {pt[0], pt[1], pt[2]};
1316  double dir1[3] = {dir[0], dir[1], dir[2]};
1317  double dir2[3] = {-dir1[0], -dir1[1], -dir1[2]};
1318  double n[3];
1319  norm(dir1, n);
1320  double pt2[3] = {pt1[0] + H * n[0], pt1[1] + H * n[1], pt1[2] + H * n[2]};
1321  std::vector<gLevelset *> p;
1322  p.push_back(new gLevelsetGenCylinder(pt1, dir1, R, tag++));
1323  p.push_back(new gLevelsetPlane(pt1, dir2, tag++));
1324  p.push_back(new gLevelsetPlane(pt2, dir1, tag));
1325  Ls = new gLevelsetIntersection(p);
1326 }
1327 
1328 gLevelsetCylinder::gLevelsetCylinder(const double *pt, const double *dir,
1329  const double &R, const double &H, int tag)
1330  : gLevelsetImproved()
1331 {
1332  double dir2[3] = {-dir[0], -dir[1], -dir[2]};
1333  double n[3];
1334  norm(dir, n);
1335  double pt2[3] = {pt[0] + H * n[0], pt[1] + H * n[1], pt[2] + H * n[2]};
1336  std::vector<gLevelset *> p;
1337  p.push_back(new gLevelsetGenCylinder(pt, dir, R, tag++));
1338  p.push_back(new gLevelsetPlane(pt, dir2, tag++));
1339  p.push_back(new gLevelsetPlane(pt2, dir, tag));
1340  Ls = new gLevelsetIntersection(p);
1341 }
1342 
1343 gLevelsetCylinder::gLevelsetCylinder(const double *pt, const double *dir,
1344  const double &R, const double &r,
1345  const double &H, int tag)
1346  : gLevelsetImproved()
1347 {
1348  double dir2[3] = {-dir[0], -dir[1], -dir[2]};
1349  double n[3];
1350  norm(dir, n);
1351  double pt2[3] = {pt[0] + H * n[0], pt[1] + H * n[1], pt[2] + H * n[2]};
1352  std::vector<gLevelset *> p1;
1353  p1.push_back(new gLevelsetGenCylinder(pt, dir, R, tag++));
1354  p1.push_back(new gLevelsetPlane(pt, dir2, tag++));
1355  p1.push_back(new gLevelsetPlane(pt2, dir, tag++));
1356  std::vector<gLevelset *> p2;
1357  p2.push_back(new gLevelsetIntersection(p1));
1358  p2.push_back(new gLevelsetGenCylinder(pt, dir, r, tag));
1359  Ls = new gLevelsetCut(p2);
1360 }
1361 
1363  : gLevelsetImproved(lv)
1364 {
1365 }
1366 
1367 gLevelsetConrod::gLevelsetConrod(const double *pt, const double *dir1,
1368  const double *dir2, const double &H1,
1369  const double &H2, const double &H3,
1370  const double &R1, const double &r1,
1371  const double &R2, const double &r2,
1372  const double &L1, const double &L2,
1373  const double &E, int tag)
1374  : gLevelsetImproved()
1375 {
1376  double n1[3];
1377  norm(dir1, n1);
1378  double n2[3];
1379  norm(dir2, n2);
1380  double pt1[3] = {pt[0] - n2[0] * H1 / 2., pt[1] - n2[1] * H1 / 2.,
1381  pt[2] - n2[2] * H1 / 2.};
1382  double pt2[3] = {pt[0] + n1[0] * E - n2[0] * H2 / 2.,
1383  pt[1] + n1[1] * E - n2[1] * H2 / 2.,
1384  pt[2] + n1[2] * E - n2[2] * H2 / 2.};
1385  double dir3[3];
1386  cross(pt1, pt2, pt, dir3);
1387  double n3[3];
1388  norm(dir3, n3);
1389  double pt31[3] = {pt[0] - n2[0] * H3 / 2. + n3[0] * L1 / 2.,
1390  pt[1] - n2[1] * H3 / 2. + n3[1] * L1 / 2.,
1391  pt[2] - n2[2] * H3 / 2. + n3[2] * L1 / 2.};
1392  double pt32[3] = {pt31[0] - n3[0] * L1, pt31[1] - n3[1] * L1,
1393  pt31[2] - n3[2] * L1};
1394  double pt33[3] = {pt32[0] + n2[0] * H3, pt32[1] + n2[1] * H3,
1395  pt32[2] + n2[2] * H3};
1396  double pt34[3] = {pt33[0] + n3[0] * L1, pt33[1] + n3[1] * L1,
1397  pt33[2] + n3[2] * L1};
1398  double pt35[3] = {pt[0] + n1[0] * E - n2[0] * H3 / 2. + n3[0] * L2 / 2.,
1399  pt[1] + n1[1] * E - n2[1] * H3 / 2. + n3[1] * L2 / 2.,
1400  pt[2] + n1[2] * E - n2[2] * H3 / 2. + n3[2] * L2 / 2.};
1401  double pt36[3] = {pt35[0] - n3[0] * L2, pt35[1] - n3[1] * L2,
1402  pt35[2] - n3[2] * L2};
1403  double pt37[3] = {pt36[0] + n2[0] * H3, pt36[1] + n2[1] * H3,
1404  pt36[2] + n2[2] * H3};
1405  double pt38[3] = {pt37[0] + n3[0] * L2, pt37[1] + n3[1] * L2,
1406  pt37[2] + n3[2] * L2};
1407  std::vector<gLevelset *> p1;
1408  p1.push_back(
1409  new gLevelsetBox(pt31, pt32, pt33, pt34, pt35, pt36, pt37, pt38, tag));
1410  p1.push_back(new gLevelsetCylinder(pt1, dir2, R1, H1, tag + 6));
1411  p1.push_back(new gLevelsetCylinder(pt2, dir2, R2, H2, tag + 9));
1412  std::vector<gLevelset *> p2;
1413  p2.push_back(new gLevelsetUnion(p1));
1414  p2.push_back(new gLevelsetGenCylinder(pt1, dir2, r1, tag + 12));
1415  p2.push_back(new gLevelsetGenCylinder(pt2, dir2, r2, tag + 13));
1416  Ls = new gLevelsetCut(p2);
1417 }
1418 
1420  : gLevelsetImproved(lv)
1421 {
1422 }
1423 
1424 // Level-set for NACA0012 airfoil, last coeff. modified for zero-thickness
1425 // trailing edge cf. http://en.wikipedia.org/wiki/NACA_airfoil
1426 gLevelsetNACA00::gLevelsetNACA00(double x0, double y0, double c, double t)
1427  : _x0(x0), _y0(y0), _c(c), _t(t)
1428 {
1429  _hasDerivatives = true;
1430 }
1431 
1432 void gLevelsetNACA00::getClosestBndPoint(double x, double y, double z,
1433  double &xb, double &yb,
1434  double &curvRad, bool &in) const
1435 {
1436  static const int maxIter = 100;
1437  static const double tol = 1.e-10;
1438 
1439  const double tolr = tol / _c; // Tolerance (scaled bu chord)
1440  in = false; // Whether the point is inside the airfoil
1441 
1442  // Point translated according to airfoil origin and symmetry
1443  const double xt = x - _x0, yt = fabs(y - _y0);
1444 
1445  if(xt - _c > 1.21125 * _t * yt) {
1446  // Behind line normal to airfoil at trailing edge, closest boundary point is
1447  // trailing edge...
1448  xb = _x0 + _c;
1449  yb = _y0;
1450  curvRad = 0.;
1451  }
1452  else { // ...otherwise Newton-Raphson to find closest boundary point
1453  const double fact = 5. * _t * _c;
1454  double xtb = std::max(xt, tolr), ytb;
1455  double dyb, ddyb;
1456  for(int it = 0; it < maxIter; it++) {
1457  const double xbr = xtb / _c, sxbr = sqrt(xbr), xbr32 = xbr * sxbr,
1458  xbr2 = xbr * xbr, xbr3 = xbr2 * xbr, xbr4 = xbr2 * xbr2;
1459  ytb = fact * (0.2969 * sxbr - 0.1260 * xbr - 0.3516 * xbr2 +
1460  0.2843 * xbr3 - 0.1036 * xbr4);
1461  dyb = fact *
1462  (0.14845 / sxbr - 0.4144 * xbr3 + 0.8529 * xbr2 - 0.7032 * xbr -
1463  0.126) /
1464  _c;
1465  ddyb = fact *
1466  (-0.074225 / xbr32 - 1.2432 * xbr2 + 1.7058 * xbr - 0.7032) /
1467  (_c * _c);
1468  const double xx = xt - xtb, yy = yt - ytb;
1469  in = (xt > 0) && (yy < 0);
1470  const double dDistSq = -2. * (xx + dyb * yy);
1471  const double ddDistSq = 2. * (1. - ddyb * yy + dyb * dyb);
1472  const double mIncr = dDistSq / ddDistSq;
1473  if(fabs(mIncr) < tolr)
1474  break;
1475  else
1476  xtb -= mIncr;
1477  if(xtb < tolr) xtb = tolr;
1478  if(xtb > _c - tolr) xtb = _c - tolr;
1479  }
1480  xb = _x0 + xtb;
1481  yb = (y >= _y0) ? _y0 + ytb : _y0 - ytb;
1482  const double norm = sqrt(1. + dyb * dyb);
1483  curvRad = norm * norm * norm / fabs(ddyb);
1484  }
1485 }
1486 
1487 double gLevelsetNACA00::operator()(double x, double y, double z) const
1488 {
1489  double xb, yb, curvRadb;
1490  bool in;
1491 
1492  getClosestBndPoint(x, y, z, xb, yb, curvRadb, in);
1493  const double xx = x - xb, yy = y - yb, distSq = xx * xx + yy * yy;
1494 
1495  return in ? -sqrt(distSq) : sqrt(distSq);
1496 }
1497 
1498 void gLevelsetNACA00::gradient(double x, double y, double z, double &dfdx,
1499  double &dfdy, double &dfdz) const
1500 {
1501  double xb, yb, curvRadb;
1502  bool in;
1503 
1504  getClosestBndPoint(x, y, z, xb, yb, curvRadb, in);
1505  const double xx = x - xb, yy = y - yb, distSq = xx * xx + yy * yy;
1506  const double dist = in ? -sqrt(distSq) : sqrt(distSq);
1507 
1508  dfdx = xx / dist;
1509  dfdy = yy / dist;
1510  dfdz = 0.;
1511 }
1512 
1513 void gLevelsetNACA00::hessian(double x, double y, double z, double &dfdxx,
1514  double &dfdxy, double &dfdxz, double &dfdyx,
1515  double &dfdyy, double &dfdyz, double &dfdzx,
1516  double &dfdzy, double &dfdzz) const
1517 {
1518  double xb, yb, curvRadb;
1519  bool in;
1520 
1521  getClosestBndPoint(x, y, z, xb, yb, curvRadb, in);
1522 
1523  const double xx = x - xb, yy = y - yb, distSq = xx * xx + yy * yy;
1524  const double dist = in ? -sqrt(distSq) : sqrt(distSq);
1525  const double curvRad = curvRadb + dist,
1526  fact = 1. / (curvRad * curvRad * curvRad);
1527 
1528  dfdxx = yy * yy * fact;
1529  dfdxy = -xx * yy * fact;
1530  dfdxz = 0.;
1531  dfdyx = dfdxy;
1532  dfdyy = xx * xx * fact;
1533  dfdyz = 0.;
1534  dfdzx = 0.;
1535  dfdzy = 0.;
1536  dfdzz = 0.;
1537 }
gLevelsetPoints::evalRbfDer
void evalRbfDer(int p, int index, const fullMatrix< double > &cntrs, const fullMatrix< double > &nodes, const fullMatrix< double > &fValues, fullMatrix< double > &fApprox, bool isLocal=false) const
Definition: gmshLevelset.cpp:470
gLevelsetMathEvalAll::_expr
mathEvaluator * _expr
Definition: gmshLevelset.h:352
insertActiveCells
void insertActiveCells(double x, double y, double z, double rmax, cartesianBox< double > &box)
Definition: gmshLevelset.cpp:46
D
#define D
Definition: DefaultOptions.h:24
gLevelsetMathEvalAll::hessian
void hessian(double x, double y, double z, double &dfdxx, double &dfdxy, double &dfdxz, double &dfdyx, double &dfdyy, double &dfdyz, double &dfdzx, double &dfdzy, double &dfdzz) const
Definition: gmshLevelset.cpp:922
gLevelset::getTag
virtual int getTag() const
Definition: gmshLevelset.h:109
gLevelsetQuadric::computeRotationMatrix
void computeRotationMatrix(const double dir[3], double t[3][3])
Definition: gmshLevelset.cpp:677
gLevelsetPrimitive
Definition: gmshLevelset.h:143
PView
Definition: PView.h:27
gLevelsetNACA00::hessian
void hessian(double x, double y, double z, double &dfdxx, double &dfdxy, double &dfdxz, double &dfdyx, double &dfdyy, double &dfdyz, double &dfdzx, double &dfdzy, double &dfdzz) const
Definition: gmshLevelset.cpp:1513
gLevelsetMathEval::_expr
mathEvaluator * _expr
Definition: gmshLevelset.h:342
gLevelsetCylinder::gLevelsetCylinder
gLevelsetCylinder(const std::vector< double > &pt, const std::vector< double > &dir, const double &R, const double &H, int tag=0)
Definition: gmshLevelset.cpp:1310
gLevelsetShamrock::iso_x
std::vector< double > iso_x
Definition: gmshLevelset.h:331
gLevelsetGeneralQuadric::gLevelsetGeneralQuadric
gLevelsetGeneralQuadric(const double *pt, const double *dir, const double &x2, const double &y2, const double &z2, const double &z, const double &c, int tag=0)
Definition: gmshLevelset.cpp:1183
dot
double dot(const SVector3 &a, const SMetric3 &m, const SVector3 &b)
Definition: STensor3.h:71
gLevelsetPopcorn::r0
double r0
Definition: gmshLevelset.h:313
mathEvaluator
Definition: mathEvaluator.h:37
removeBadChildCells
int removeBadChildCells(cartesianBox< double > *parent)
Definition: gmshLevelset.cpp:75
gLevelset::getPrimitives
void getPrimitives(std::vector< gLevelset * > &primitives)
Definition: gmshLevelset.cpp:273
gLevelsetNACA00::_t
double _t
Definition: gmshLevelset.h:413
GPoint::y
double y() const
Definition: GPoint.h:22
gLevelsetPoints::delta
double delta
Definition: gmshLevelset.h:222
distance
double distance(MVertex *v1, MVertex *v2)
Definition: MVertex.h:245
gLevelset::gLevelset
gLevelset(int tag=0)
Definition: gmshLevelset.h:76
mathEvaluator.h
gLevelsetPoints::computeLS
void computeLS(std::vector< MVertex * > &vert)
Definition: gmshLevelset.cpp:585
Msg::Info
static void Info(const char *fmt,...)
Definition: GmshMessage.cpp:587
gLevelsetSphere::hessian
void hessian(double x, double y, double z, double &dfdxx, double &dfdxy, double &dfdxz, double &dfdyx, double &dfdyy, double &dfdyz, double &dfdzx, double &dfdzy, double &dfdzz) const
Definition: gmshLevelset.cpp:371
angle
double angle(const SVector3 &a, const SVector3 &b)
Definition: SVector3.h:157
OS.h
gLevelsetNACA00::gLevelsetNACA00
gLevelsetNACA00(double x0, double y0, double c, double t)
Definition: gmshLevelset.cpp:1426
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
MVertex
Definition: MVertex.h:24
gLevelsetPlane::b
double b
Definition: gmshLevelset.h:189
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
MVertex::z
double z() const
Definition: MVertex.h:62
box
Definition: gl2gif.cpp:311
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
gLevelsetPoints::operator()
virtual double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:566
simpleFunction< double >::_hasDerivatives
bool _hasDerivatives
Definition: simpleFunction.h:17
mathEvaluator::eval
bool eval(const std::vector< double > &values, std::vector< double > &res)
Definition: mathEvaluator.h:47
gLevelsetQuadric::gLevelsetQuadric
gLevelsetQuadric(int tag=0)
Definition: gmshLevelset.h:263
Range::high
T high() const
Definition: Range.h:20
OctreePost
Definition: BoundaryLayers.cpp:23
SVector3
Definition: SVector3.h:16
TYPE_TRI
#define TYPE_TRI
Definition: GmshDefines.h:66
gLevelsetMathEval::operator()
double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:871
gLevelsetSphere::zc
double zc
Definition: gmshLevelset.h:165
gLevelsetConrod::gLevelsetConrod
gLevelsetConrod(const double *pt, const double *dir1, const double *dir2, const double &H1, const double &H2, const double &H3, const double &R1, const double &r1, const double &R2, const double &r2, const double &L1, const double &L2, const double &E, int tag=0)
Definition: gmshLevelset.cpp:1367
gLevelsetUnion
Definition: gmshLevelset.h:539
gLevelsetEllipsoid::gLevelsetEllipsoid
gLevelsetEllipsoid(const double *pt, const double *dir, const double &a, const double &b, const double &c, int tag=0)
Definition: gmshLevelset.cpp:1148
gLevelsetTools
Definition: gmshLevelset.h:447
gLevelsetQuadric::Ax
void Ax(const double x[3], double res[3], double fact=1.0)
Definition: gmshLevelset.cpp:620
cross
void cross(const double *pt0, const double *pt1, const double *pt2, double *cross)
Definition: gmshLevelset.cpp:210
gLevelsetLessThan::operator()
bool operator()(const gLevelset *l1, const gLevelset *l2) const
Definition: gmshLevelset.cpp:30
GEdge::length
double length() const
Definition: GEdge.h:170
gLevelsetPopcorn::zc
double zc
Definition: gmshLevelset.h:314
gLevelsetEllipsoid
Definition: gmshLevelset.h:279
gLevelsetMathEval::~gLevelsetMathEval
~gLevelsetMathEval()
Definition: gmshLevelset.cpp:866
cartesianBox::eraseActiveCell
void eraseActiveCell(int t)
Definition: cartesian.h:286
fillPointCloud
void fillPointCloud(GEdge *ge, double sampling, std::vector< SPoint3 > &points)
Definition: gmshLevelset.cpp:61
removeParentCellsWithChildren
void removeParentCellsWithChildren(cartesianBox< double > *box)
Definition: gmshLevelset.cpp:120
GEntity
Definition: GEntity.h:31
GPoint
Definition: GPoint.h:13
GModel::firstPhysicalName
piter firstPhysicalName()
Definition: GModel.h:458
cartesianBox::getChildBox
cartesianBox< scalar > * getChildBox()
Definition: cartesian.h:148
signedDistancesPointsTriangle
void signedDistancesPointsTriangle(std::vector< double > &distances, std::vector< SPoint3 > &closePts, const std::vector< SPoint3 > &pts, const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p3)
Definition: Numeric.cpp:822
MElement::getNumVertices
virtual std::size_t getNumVertices() const =0
cartesianBox::getNeta
int getNeta()
Definition: cartesian.h:146
gLevelsetPoints::setup_level_set
void setup_level_set(const fullMatrix< double > &cntrs, fullMatrix< double > &level_set_nodes, fullMatrix< double > &level_set_funvals)
Definition: gmshLevelset.cpp:483
gLevelsetPopcorn::operator()
double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:821
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
gLevelsetPopcorn::xc
double xc
Definition: gmshLevelset.h:314
gLevelsetPoints
Definition: gmshLevelset.h:217
gLevelsetPopcorn::sigma
double sigma
Definition: gmshLevelset.h:312
gLevelsetImproved
Definition: gmshLevelset.h:595
GPoint::z
double z() const
Definition: GPoint.h:23
cartesianBox::getNzeta
int getNzeta()
Definition: cartesian.h:147
MElement::getVertex
virtual const MVertex * getVertex(int num) const =0
gLevelsetPoints::points
fullMatrix< double > points
Definition: gmshLevelset.h:219
fullMatrix< double >
gLevelsetNACA00::_x0
double _x0
Definition: gmshLevelset.h:413
GModel::getPhysicalGroups
void getPhysicalGroups(std::map< int, std::vector< GEntity * > > groups[4]) const
Definition: GModel.cpp:837
gLevelsetShamrock::a
double a
Definition: gmshLevelset.h:329
GModel::lastFace
fiter lastFace()
Definition: GModel.h:359
gLevelsetQuadric::init
void init()
Definition: gmshLevelset.cpp:732
gLevelsetGenCylinder::gLevelsetGenCylinder
gLevelsetGenCylinder(const double *pt, const double *dir, const double &R, int tag=0)
Definition: gmshLevelset.cpp:1130
gLevelsetQuadric::xAx
void xAx(const double x[3], double &res, double fact=1.0)
Definition: gmshLevelset.cpp:628
gLevelsetImproved::Ls
gLevelset * Ls
Definition: gmshLevelset.h:597
gLevelsetShamrock::iso_y
std::vector< double > iso_y
Definition: gmshLevelset.h:331
Range
Definition: Range.h:10
gLevelsetNACA00::getClosestBndPoint
void getClosestBndPoint(const double x, const double y, const double z, double &xb, double &yb, double &curvRad, bool &in) const
Definition: gmshLevelset.cpp:1432
MElement::getType
virtual int getType() const =0
signedDistancePointTriangle
void signedDistancePointTriangle(const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p3, const SPoint3 &p, double &d, SPoint3 &closePt)
Definition: Numeric.cpp:758
gLevelset
Definition: gmshLevelset.h:64
gLevelset::clone
virtual gLevelset * clone() const
Definition: gmshLevelset.h:87
gLevelsetGenCylinder
Definition: gmshLevelset.h:270
gLevelsetNACA00::_y0
double _y0
Definition: gmshLevelset.h:413
GEntity::getNumMeshElements
virtual std::size_t getNumMeshElements() const
Definition: GEntity.h:348
gLevelsetMathEvalAll::operator()
double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:898
rotate
void rotate(const Quaternion &omega, XYZ axe)
Definition: Camera.cpp:398
gLevelsetConrod
Definition: gmshLevelset.h:677
gLevelsetMathEvalAll::gLevelsetMathEvalAll
gLevelsetMathEvalAll(std::vector< std::string > f, int tag=0)
Definition: gmshLevelset.cpp:881
gLevelsetShamrock::c
int c
Definition: gmshLevelset.h:330
gLevelset::find
static gLevelset * find(int tag)
Definition: gmshLevelset.cpp:36
norm
void norm(const double *vec, double *norm)
Definition: gmshLevelset.cpp:202
Numeric.h
gLevelset::maxTag_
static int maxTag_
Definition: gmshLevelset.h:71
GModel
Definition: GModel.h:44
gLevelsetCut
Definition: gmshLevelset.h:522
gLevelsetPoints::generateRbfMat
fullMatrix< double > generateRbfMat(int p, int index, const fullMatrix< double > &nodes1, const fullMatrix< double > &nodes2) const
Definition: gmshLevelset.cpp:431
gLevelsetQuadric::B
double B[3]
Definition: gmshLevelset.h:252
computeLevelset
void computeLevelset(GModel *gm, cartesianBox< double > &box)
Definition: gmshLevelset.cpp:144
gLevelsetPoints::matAInv
fullMatrix< double > matAInv
Definition: gmshLevelset.h:221
GModel::firstFace
fiter firstFace()
Definition: GModel.h:355
fullMatrix::invertInPlace
bool invertInPlace()
Definition: fullMatrix.h:662
signedDistancePointLine
void signedDistancePointLine(const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p, double &d, SPoint3 &closePt)
Definition: Numeric.cpp:908
gLevelsetSphere::yc
double yc
Definition: gmshLevelset.h:165
gLevelsetShamrock::operator()
double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:763
gLevelset::H
double H(const double &x, const double &y, const double &z) const
Definition: gmshLevelset.h:113
gLevelsetQuadric::A
double A[3][3]
Definition: gmshLevelset.h:252
gLevelsetCylinder
Definition: gmshLevelset.h:647
MElement
Definition: MElement.h:30
gLevelsetPoints::RbfOp
void RbfOp(int p, int index, const fullMatrix< double > &cntrs, const fullMatrix< double > &nodes, fullMatrix< double > &D, bool isLocal=false) const
Definition: gmshLevelset.cpp:451
gLevelsetPlane::a
double a
Definition: gmshLevelset.h:189
gLevelset::tag_
int tag_
Definition: gmshLevelset.h:69
gLevelsetSphere::gradient
void gradient(double x, double y, double z, double &dfdx, double &dfdy, double &dfdz) const
Definition: gmshLevelset.cpp:360
gLevelsetMathEval::gLevelsetMathEval
gLevelsetMathEval(const std::string &f, int tag=0)
Definition: gmshLevelset.cpp:855
cartesian.h
gLevelsetNACA00::gradient
void gradient(double x, double y, double z, double &dfdx, double &dfdy, double &dfdz) const
Definition: gmshLevelset.cpp:1498
gLevelsetShamrock::xmid
double xmid
Definition: gmshLevelset.h:329
fullMatrix::gemm
void gemm(const fullMatrix< scalar > &a, const fullMatrix< scalar > &b, scalar alpha=1., scalar beta=1., bool transposeA=false, bool transposeB=false)
Definition: fullMatrix.h:580
gLevelset::getPrimitivesPO
void getPrimitivesPO(std::vector< gLevelset * > &primitives)
Definition: gmshLevelset.cpp:291
S
#define S
Definition: DefaultOptions.h:21
fullMatrix::size2
int size2() const
Definition: fullMatrix.h:275
GEntity::DiscreteSurface
@ DiscreteSurface
Definition: GEntity.h:117
length
double length(Quaternion &q)
Definition: Camera.cpp:346
gLevelset::getChildren
virtual std::vector< gLevelset * > getChildren() const
Definition: gmshLevelset.h:101
cartesianBox
Definition: cartesian.h:33
b1
const double b1
Definition: GaussQuadratureHex.cpp:14
gLevelsetQuadric
Definition: gmshLevelset.h:250
gLevelsetQuadric::operator()
double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:741
printNodes
void printNodes(fullMatrix< double > &myNodes, fullMatrix< double > &surf)
Definition: gmshLevelset.cpp:257
GEntity::getMeshElement
virtual MElement * getMeshElement(std::size_t index) const
Definition: GEntity.h:363
gLevelsetBox::gLevelsetBox
gLevelsetBox(const double *pt, const double *dir1, const double *dir2, const double *dir3, const double &a, const double &b, const double &c, int tag=0)
Definition: gmshLevelset.cpp:1256
GEdge::parBounds
virtual Range< double > parBounds(int i) const =0
gLevelset::getRPN
void getRPN(std::vector< gLevelset * > &gLsRPN)
Definition: gmshLevelset.cpp:321
fullMatrix::size1
int size1() const
Definition: fullMatrix.h:274
gLevelsetGeneralQuadric
Definition: gmshLevelset.h:297
gLevelsetPlane
Definition: gmshLevelset.h:187
z
const double z
Definition: GaussQuadratureQuad.cpp:56
GModel::lastPhysicalName
piter lastPhysicalName()
Definition: GModel.h:459
gLevelsetPoints::mapP
std::map< SPoint3, double > mapP
Definition: gmshLevelset.h:223
evalRadialFnDer
double evalRadialFnDer(int p, int index, double dx, double dy, double dz, double ep)
Definition: gmshLevelset.cpp:234
GEdge::point
virtual GPoint point(double p) const =0
MElement.h
gLevelsetMathEvalAll::gradient
void gradient(double x, double y, double z, double &dfdx, double &dfdy, double &dfdz) const
Definition: gmshLevelset.cpp:908
gLevelsetTools::getChildren
std::vector< gLevelset * > getChildren() const
Definition: gmshLevelset.h:476
gLevelsetShamrock::gLevelsetShamrock
gLevelsetShamrock(double xmid, double ymid, double zmid, double a, double b, int c=3, int tag=0)
Definition: gmshLevelset.cpp:748
GEdge
Definition: GEdge.h:26
gLevelsetMathEvalAll::~gLevelsetMathEvalAll
~gLevelsetMathEvalAll()
Definition: gmshLevelset.cpp:893
gLevelsetQuadric::C
double C
Definition: gmshLevelset.h:252
gLevelsetCone
Definition: gmshLevelset.h:288
cartesianBox::getCellIndex
int getCellIndex(int i, int j, int k) const
Definition: cartesian.h:291
gLevelsetQuadric::translate
void translate(const double transl[3])
Definition: gmshLevelset.cpp:635
gLevelsetPopcorn::gLevelsetPopcorn
gLevelsetPopcorn(double xc, double yc, double zc, double r0, double A, double sigma, int tag=0)
Definition: gmshLevelset.cpp:808
cartesianBox::activeCellExists
bool activeCellExists(int t)
Definition: cartesian.h:287
gLevelsetYarn::operator()
double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:1224
gLevelsetPlane::gLevelsetPlane
gLevelsetPlane(const double _a, const double _b, const double _c, const double _d, int tag=0)
Definition: gmshLevelset.h:193
gLevelsetSphere::gLevelsetSphere
gLevelsetSphere(const double &x, const double &y, const double &z, const double &R, int tag=0)
Definition: gmshLevelset.cpp:353
gLevelsetPopcorn::A
double A
Definition: gmshLevelset.h:311
gLevelsetTools::gLevelsetTools
gLevelsetTools(int tag=0)
Definition: gmshLevelset.h:452
gLevelsetPopcorn::yc
double yc
Definition: gmshLevelset.h:314
GModel.h
gLevelsetNACA00::operator()
double operator()(double x, double y, double z) const
Definition: gmshLevelset.cpp:1487
MVertex::y
double y() const
Definition: MVertex.h:61
gLevelsetPlane::c
double c
Definition: gmshLevelset.h:189
gLevelsetPoints::surf
fullMatrix< double > surf
Definition: gmshLevelset.h:220
Range::low
T low() const
Definition: Range.h:18
gLevelsetTools::children
std::vector< gLevelset * > children
Definition: gmshLevelset.h:449
fullMatrix::resize
bool resize(int r, int c, bool resetValue=true)
Definition: fullMatrix.h:307
gLevelsetSphere::xc
double xc
Definition: gmshLevelset.h:165
PView::list
static std::vector< PView * > list
Definition: PView.h:112
gLevelsetPlane::d
double d
Definition: gmshLevelset.h:189
gLevelsetImproved::gLevelsetImproved
gLevelsetImproved(int tag=0)
Definition: gmshLevelset.h:600
gLevelset::add
static void add(gLevelset *l)
Definition: gmshLevelset.cpp:44
gLevelsetYarn::entities
std::vector< GEntity * > entities
Definition: gmshLevelset.h:435
gLevelset::all_
static std::set< gLevelset *, gLevelsetLessThan > all_
Definition: gmshLevelset.h:73
GPoint::x
double x() const
Definition: GPoint.h:21
c1
const double c1
Definition: GaussQuadratureHex.cpp:16
gLevelsetCone::gLevelsetCone
gLevelsetCone(const double *pt, const double *dir, const double &angle, int tag=0)
Definition: gmshLevelset.cpp:1168
isPlanar
bool isPlanar(const double *pt1, const double *pt2, const double *pt3, const double *pt4)
Definition: gmshLevelset.cpp:220
gLevelsetBox
Definition: gmshLevelset.h:612
det3
double det3(double d11, double d12, double d13, double d21, double d22, double d23, double d31, double d32, double d33)
Definition: gmshLevelset.cpp:195
gLevelsetYarn::gLevelsetYarn
gLevelsetYarn(int dim, int phys, double minA, double majA, int type, int tag=0)
Definition: gmshLevelset.cpp:1213
gmshLevelset.h
closestPoint
double closestPoint(const std::vector< SPoint3 > &P, const SPoint3 &p, SPoint3 &result)
Definition: hausdorffDistance.cpp:50
fullMatrix.h
gLevelsetQuadric::rotate
void rotate(const double rotate[3][3])
Definition: gmshLevelset.cpp:648
cartesianBox::getNxi
int getNxi()
Definition: cartesian.h:145
gLevelsetNACA00::_c
double _c
Definition: gmshLevelset.h:413
GModel::current
static GModel * current(int index=-1)
Definition: GModel.cpp:136
gLevelsetPoints::gLevelsetPoints
gLevelsetPoints(fullMatrix< double > &_centers, int tag=0)
Definition: gmshLevelset.cpp:545
MVertex::x
double x() const
Definition: MVertex.h:60
gLevelsetShamrock::b
double b
Definition: gmshLevelset.h:329
gLevelsetIntersection
Definition: gmshLevelset.h:557