Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SurfaceMeshHOMesh.cpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // File: SurfaceMeshing.cpp
4 //
5 // For more information, please see: http://www.nektar.info/
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: surfacemeshing object methods.
33 //
34 ////////////////////////////////////////////////////////////////////////////////
35 
36 #include <list>
37 #include <algorithm>
41 
43 #include <LocalRegions/MatrixKey.h>
45 
46 using namespace std;
47 namespace Nektar
48 {
49 namespace NekMeshUtils
50 {
51 
52 set<pair<int, int> > ListOfFaceSpings(int nq)
53 {
54  map<pair<int, int>, int> nodeorder;
55  map<int, pair<int, int> > nodeorderRev;
56  pair<int, int> id;
57 
58  id.first = 0;
59  id.second = 0;
60  nodeorder[id] = 0;
61  nodeorderRev[0] = id;
62 
63  id.first = nq - 1;
64  id.second = 0;
65  nodeorder[id] = 1;
66  nodeorderRev[1] = id;
67 
68  id.first = 0;
69  id.second = nq - 1;
70  nodeorder[id] = 2;
71  nodeorderRev[2] = id;
72 
73  for (int i = 0; i < nq - 2; i++)
74  {
75  id.second = 0;
76  id.first = i + 1;
77  nodeorder[id] = i + 3;
78  nodeorderRev[i + 3] = id;
79  }
80  for (int i = 0; i < nq - 2; i++)
81  {
82  id.first = nq - 2 - i;
83  id.second = 1 + i;
84  nodeorder[id] = nq + 1 + i;
85  nodeorderRev[nq + 1 + i] = id;
86  }
87  for (int i = 0; i < nq - 2; i++)
88  {
89  id.first = 0;
90  id.second = nq - 2 - i;
91  nodeorder[id] = nq + nq - 1 + i;
92  nodeorderRev[nq + nq - 1 + i] = id;
93  }
94 
95  int i = 1;
96  int j = 1;
97  int limit = nq - 3;
98  for (int k = 0; k < (nq - 3) * (nq - 2) / 2; k++)
99  {
100  id.first = i;
101  id.second = j;
102  nodeorder[id] = 3 * (nq - 1) + k;
103  nodeorderRev[3 * (nq - 1) + k] = id;
104  i++;
105  if (i > limit)
106  {
107  limit--;
108  j++;
109  i = 1;
110  }
111  }
112 
113  map<int, vector<int> > nodetosix;
114 
115  for (int i = (nq + 1) * nq / 2 - (nq - 3) * (nq - 2) / 2;
116  i < (nq + 1) * nq / 2;
117  i++)
118  {
119  vector<int> ids;
120  int pr;
121 
122  pair<int, int> p = nodeorderRev[i];
123  p.first -= 1;
124  pr = nodeorder[p];
125 
126  ids.push_back(pr);
127 
128  p = nodeorderRev[i];
129  p.second -= 1;
130  pr = nodeorder[p];
131 
132  ids.push_back(pr);
133 
134  p = nodeorderRev[i];
135  p.first += 1;
136  pr = nodeorder[p];
137 
138  ids.push_back(pr);
139 
140  p = nodeorderRev[i];
141  p.second += 1;
142  pr = nodeorder[p];
143 
144  ids.push_back(pr);
145 
146  p = nodeorderRev[i];
147  p.first += 1;
148  p.second -= 1;
149  pr = nodeorder[p];
150 
151  ids.push_back(pr);
152 
153  p = nodeorderRev[i];
154  p.first -= 1;
155  p.second += 1;
156  pr = nodeorder[p];
157 
158  ids.push_back(pr);
159 
160  nodetosix[i] = ids;
161  }
162 
163  set<pair<int, int> > ret;
164  map<int, vector<int> >::iterator it;
165  for (it = nodetosix.begin(); it != nodetosix.end(); it++)
166  {
167  vector<int> ns = it->second;
168  for (int i = 0; i < ns.size(); i++)
169  {
170  pair<int, int> sp(min(it->first, ns[i]), max(it->first, ns[i]));
171  ret.insert(sp);
172  }
173  }
174 
175  return ret;
176 }
177 
178 map<pair<int, int>, NekDouble> weights(set<pair<int, int> > springs,
181 {
182  map<pair<int, int>, NekDouble> ret;
183 
184  // setup map from right angled reference triangle to equilateral reference
185  // triangle
186  DNekMat A(3, 3, 1.0);
187  A(0, 0) = -1.0;
188  A(1, 0) = -1.0;
189  A(0, 1) = 1.0;
190  A(1, 1) = -1.0;
191  A(0, 2) = 0.0;
192  A(1, 2) = -1.0 + sqrt(3.0);
193 
194  DNekMat B(3, 3, 1.0);
195  B(0, 0) = -1.0;
196  B(1, 0) = -1.0;
197  B(0, 1) = 1.0;
198  B(1, 1) = -1.0;
199  B(0, 2) = -1.0;
200  B(1, 2) = 1.0;
201 
202  B.Invert();
203 
204  DNekMat M = A * B;
205 
206  DNekMat C(3, u.num_elements(), 1.0);
207  for (int i = 0; i < u.num_elements(); i++)
208  {
209  C(0, i) = u[i];
210  C(1, i) = v[i];
211  }
212 
213  DNekMat pts = M * C;
214 
215  /*for(int i = 0; i < u.num_elements(); i++)
216  {
217  cout << pts(0,i) << " " << pts(1,i) << endl;
218  }
219  exit(-1);*/
220 
221  set<pair<int, int> >::iterator it;
222  for (it = springs.begin(); it != springs.end(); it++)
223  {
224  ret[(*it)] = sqrt((pts(0, (*it).first) - pts(0, (*it).second)) *
225  (pts(0, (*it).first) - pts(0, (*it).second)) +
226  (pts(1, (*it).first) - pts(1, (*it).second)) *
227  (pts(1, (*it).first) - pts(1, (*it).second)));
228 
229  if ((*it).first == 12 && (*it).second == 13)
230  ret[(*it)] *= 1.2;
231 
232  if ((*it).first == 12 && (*it).second == 14)
233  ret[(*it)] *= 1.2;
234 
235  if ((*it).first == 13 && (*it).second == 14)
236  ret[(*it)] *= 1.2;
237  }
238  return ret;
239 }
240 
242 {
243  if (m_mesh->m_verbose)
244  cout << endl << "\tHigh-Order Surface meshing" << endl;
245 
246  // this bit of code sets up information for the standard edge and face.
247  // and a mapping for node ordering for spring optimistaion
248 
249  LibUtilities::PointsKey ekey(m_mesh->m_nummode,
252 
253  LibUtilities::PointsManager()[ekey]->GetPoints(gll);
254 
255  LibUtilities::PointsKey pkey(m_mesh->m_nummode,
258 
259  int nq = m_mesh->m_nummode;
260 
261  LibUtilities::PointsManager()[pkey]->GetPoints(u, v);
262 
263  set<pair<int, int> > springs = ListOfFaceSpings(nq);
264  map<pair<int, int>, NekDouble> z = weights(springs, u, v);
265 
266  // because edges are listed twice need a method to not repeat over them
267  EdgeSet completedEdges;
268 
269  // loop over all the faces in the surface mesh, check all three edges for
270  // high order info, if nothing high-order the edge.
271 
272  for (int i = 0; i < m_mesh->m_element[2].size(); i++)
273  {
274  if (m_mesh->m_verbose)
275  {
277  i, m_mesh->m_element[2].size(), "\t\tSurface elements");
278  }
279 
280  if (m_mesh->m_element[2][i]->GetConf().m_e ==
282  {
283  // not setup for high-order quads yet
284  continue;
285  }
286 
287  int surf = m_mesh->m_element[2][i]->CADSurfId;
288  CADSurfSharedPtr s = m_cad->GetSurf(surf);
289 
290  FaceSharedPtr f = m_mesh->m_element[2][i]->GetFaceLink();
291  vector<EdgeSharedPtr> surfedges =
292  m_mesh->m_element[2][i]->GetEdgeList();
293 
294  vector<EdgeSharedPtr> edges = f->m_edgeList;
295  for (int j = 0; j < edges.size(); j++)
296  {
297  // test insert the edge into completedEdges
298  // if the edge already exists move on
299  // if not figure out its high-order information
300 
301  EdgeSet::iterator test = completedEdges.find(edges[j]);
302 
303  if (test != completedEdges.end())
304  {
305  continue;
306  }
307 
308  EdgeSharedPtr e = edges[j];
309 
310  // the edges in the element are different to those in the face
311  // the cad information is stored in the element edges which are not
312  // in the m_mesh->m_edgeSet group.
313  // need to link them together and copy the cad information to be
314  // able to identify how to make it high-order
315  bool foundsurfaceedge = false;
316  for (int k = 0; k < surfedges.size(); k++)
317  {
318  if (surfedges[k] == e)
319  {
320  e->onCurve = surfedges[k]->onCurve;
321  e->CADCurveId = surfedges[k]->CADCurveId;
322  e->CADCurve = surfedges[k]->CADCurve;
323  foundsurfaceedge = true;
324  }
325  }
326  ASSERTL0(foundsurfaceedge,
327  "cannot find corresponding surface edge");
328 
329  if (e->onCurve)
330  {
331  int cid = e->CADCurveId;
332  CADCurveSharedPtr c = e->CADCurve;
333  NekDouble tb = e->m_n1->GetCADCurveInfo(cid);
334  NekDouble te = e->m_n2->GetCADCurveInfo(cid);
335 
336  // distrobute points along curve as inital guess
337  Array<OneD, NekDouble> ti(m_mesh->m_nummode);
338  for (int k = 0; k < m_mesh->m_nummode; k++)
339  {
340  ti[k] =
341  tb * (1.0 - gll[k]) / 2.0 + te * (1.0 + gll[k]) / 2.0;
342  }
343 
344  Array<OneD, NekDouble> xi(nq - 2);
345  for (int k = 1; k < nq - 1; k++)
346  {
347  xi[k - 1] = ti[k];
348  }
349 
350  OptiEdgeSharedPtr opti =
352 
353  DNekMat B(
354  nq - 2, nq - 2, 0.0); // approximate hessian (I to start)
355  for (int k = 0; k < nq - 2; k++)
356  {
357  B(k, k) = 1.0;
358  }
359  DNekMat H(nq - 2,
360  nq - 2,
361  0.0); // approximate inverse hessian (I to start)
362  for (int k = 0; k < nq - 2; k++)
363  {
364  H(k, k) = 1.0;
365  }
366 
367  DNekMat J = opti->dF(xi);
368 
369  Array<OneD, NekDouble> bnds = c->Bounds();
370 
371  bool repeat = true;
372  int itct = 0;
373  while (repeat)
374  {
375  NekDouble Norm = 0;
376  for (int k = 0; k < nq - 2; k++)
377  {
378  Norm += J(k, 0) * J(k, 0) / (bnds[1] - bnds[0]) /
379  (bnds[1] - bnds[0]);
380  }
381  Norm = sqrt(Norm);
382 
383  if (Norm < 1E-5)
384  {
385  repeat = false;
386  break;
387  }
388  if (itct > 100)
389  {
390  cout << "failed to optimise on curve" << endl;
391  for (int k = 0; k < nq; k++)
392  {
393  ti[k] = tb * (1.0 - gll[k]) / 2.0 +
394  te * (1.0 + gll[k]) / 2.0;
395  }
396  exit(-1);
397  break;
398  }
399  itct++;
400 
401  if (!BGFSUpdate(opti, J, B, H))
402  {
403  cout << "BFGS reported no update, curve on "
404  << c->GetId() << endl;
405  break;
406  }
407  }
408  // need to pull the solution out of opti
409  ti = opti->GetSolution();
410 
411  vector<CADSurfSharedPtr> s = c->GetAdjSurf();
412 
413  ASSERTL0(s.size() == 2, "Number of common surfs should be 2");
414 
415  vector<NodeSharedPtr> honodes(m_mesh->m_nummode - 2);
416  for (int k = 1; k < m_mesh->m_nummode - 1; k++)
417  {
418  Array<OneD, NekDouble> loc = c->P(ti[k]);
419  NodeSharedPtr nn = boost::shared_ptr<Node>(
420  new Node(0, loc[0], loc[1], loc[2]));
421 
422  nn->SetCADCurve(cid, c, ti[k]);
423  Array<OneD, NekDouble> uv = s[0]->locuv(loc);
424  nn->SetCADSurf(s[0]->GetId(), s[0], uv);
425  uv = s[1]->locuv(loc);
426  nn->SetCADSurf(s[1]->GetId(), s[1], uv);
427  honodes[k - 1] = nn;
428  }
429 
430  e->m_edgeNodes = honodes;
431  e->m_curveType = LibUtilities::eGaussLobattoLegendre;
432  completedEdges.insert(e);
433  }
434  else
435  {
436  // edge is on surface and needs 2d optimisation
437  CADSurfSharedPtr s = m_cad->GetSurf(surf);
438  Array<OneD, NekDouble> uvb, uve;
439  uvb = e->m_n1->GetCADSurfInfo(surf);
440  uve = e->m_n2->GetCADSurfInfo(surf);
442  for (int k = 0; k < nq; k++)
443  {
445  uv[0] = uvb[0] * (1.0 - gll[k]) / 2.0 +
446  uve[0] * (1.0 + gll[k]) / 2.0;
447  uv[1] = uvb[1] * (1.0 - gll[k]) / 2.0 +
448  uve[1] * (1.0 + gll[k]) / 2.0;
449  uvi[k] = uv;
450  }
451 
452  Array<OneD, NekDouble> bnds = s->GetBounds();
453  Array<OneD, NekDouble> all(2 * nq);
454  for (int k = 0; k < nq; k++)
455  {
456  all[k * 2 + 0] = uvi[k][0];
457  all[k * 2 + 1] = uvi[k][1];
458  }
459 
460  Array<OneD, NekDouble> xi(2 * (nq - 2));
461  for (int k = 1; k < nq - 1; k++)
462  {
463  xi[(k - 1) * 2 + 0] = all[k * 2 + 0];
464  xi[(k - 1) * 2 + 1] = all[k * 2 + 1];
465  }
466 
467  OptiEdgeSharedPtr opti =
469 
470  DNekMat B(2 * (nq - 2),
471  2 * (nq - 2),
472  0.0); // approximate hessian (I to start)
473  for (int k = 0; k < 2 * (nq - 2); k++)
474  {
475  B(k, k) = 1.0;
476  }
477  DNekMat H(2 * (nq - 2),
478  2 * (nq - 2),
479  0.0); // approximate inverse hessian (I to start)
480  for (int k = 0; k < 2 * (nq - 2); k++)
481  {
482  H(k, k) = 1.0;
483  }
484 
485  DNekMat J = opti->dF(xi);
486 
487  bool repeat = true;
488  int itct = 0;
489  while (repeat)
490  {
491  NekDouble Norm = 0;
492  for (int k = 0; k < 2 * (nq - 2); k++)
493  {
494  if (k % 2 == 0)
495  {
496  Norm += J(k, 0) * J(k, 0) / (bnds[1] - bnds[0]) /
497  (bnds[1] - bnds[0]);
498  }
499  else
500  {
501  Norm += J(k, 0) * J(k, 0) / (bnds[3] - bnds[2]) /
502  (bnds[3] - bnds[2]);
503  }
504  }
505  Norm = sqrt(Norm);
506 
507  if (Norm < 1E-5)
508  {
509  repeat = false;
510  break;
511  }
512 
513  if (itct > 100)
514  {
515  cout << "failed to optimise on edge" << endl;
516  for (int k = 0; k < nq; k++)
517  {
519  uv[0] = uvb[0] * (1.0 - gll[k]) / 2.0 +
520  uve[0] * (1.0 + gll[k]) / 2.0;
521  uv[1] = uvb[1] * (1.0 - gll[k]) / 2.0 +
522  uve[1] * (1.0 + gll[k]) / 2.0;
523  uvi[k] = uv;
524  }
525  exit(-1);
526  break;
527  }
528  itct++;
529 
530  if (!BGFSUpdate(opti, J, B, H))
531  {
532  cout << "BFGS reported no update, edge on " << surf
533  << endl;
534  // exit(-1);
535  break;
536  }
537  }
538 
539  all = opti->GetSolution();
540 
541  // need to put all backinto uv
542  for (int k = 0; k < nq; k++)
543  {
544  uvi[k][0] = all[k * 2 + 0];
545  uvi[k][1] = all[k * 2 + 1];
546  }
547 
548  vector<NodeSharedPtr> honodes(nq - 2);
549  for (int k = 1; k < nq - 1; k++)
550  {
552  loc = s->P(uvi[k]);
553  NodeSharedPtr nn = boost::shared_ptr<Node>(
554  new Node(0, loc[0], loc[1], loc[2]));
555  nn->SetCADSurf(s->GetId(), s, uvi[k]);
556  honodes[k - 1] = nn;
557  }
558 
559  e->m_edgeNodes = honodes;
560  e->m_curveType = LibUtilities::eGaussLobattoLegendre;
561  completedEdges.insert(e);
562  }
563  }
564 
565  ASSERTL0(nq <= 5, "not setup for high-orders yet");
566 
567  /*vector<NodeSharedPtr> vertices = f->m_vertexList;
568 
569  SpatialDomains::Geometry2DSharedPtr geom = f->GetGeom(3);
570  geom->FillGeom();
571  StdRegions::StdExpansionSharedPtr xmap = geom->GetXmap();
572  Array<OneD, NekDouble> coeffs0 = geom->GetCoeffs(0);
573  Array<OneD, NekDouble> coeffs1 = geom->GetCoeffs(1);
574  Array<OneD, NekDouble> coeffs2 = geom->GetCoeffs(2);
575 
576  Array<OneD, NekDouble> xc(nq*nq);
577  Array<OneD, NekDouble> yc(nq*nq);
578  Array<OneD, NekDouble> zc(nq*nq);
579 
580  xmap->BwdTrans(coeffs0,xc);
581  xmap->BwdTrans(coeffs1,yc);
582  xmap->BwdTrans(coeffs2,zc);
583 
584 
585  //build an array of all uvs
586  Array<OneD, Array<OneD, NekDouble> > uvi(np);
587  int ctr = 0;
588  for(int j = 0; j < vertices.size(); j++)
589  {
590  uvi[ctr++] = vertices[j]->GetCADSurfInfo(surf);
591  }
592  for(int j = 0; j < edges.size(); j++)
593  {
594  vector<NodeSharedPtr> ns = edges[j]->m_edgeNodes;
595  if(!(edges[j]->m_n1 == vertices[j]))
596  {
597  reverse(ns.begin(),ns.end());
598  }
599  for(int k = 0; k < ns.size(); k++)
600  {
601  uvi[ctr++] = ns[k]->GetCADSurfInfo(surf);
602  }
603  }
604  for(int j = np-ni; j < np; j++)
605  {
606  Array<OneD, NekDouble> xp(2);
607  xp[0] = u[j];
608  xp[1] = v[j];
609 
610  Array<OneD, NekDouble> xyz(3);
611  xyz[0] = xmap->PhysEvaluate(xp, xc);
612  xyz[1] = xmap->PhysEvaluate(xp, yc);
613  xyz[2] = xmap->PhysEvaluate(xp, zc);
614 
615  Array<OneD, NekDouble> uv(2);
616  s->ProjectTo(xyz,uv);
617  uvi[ctr++] = uv;
618  }
619 
620  OptiFaceSharedPtr opti = MemoryManager<OptiFace>::
621  AllocateSharedPtr(uvi, z, springs, s);
622 
623  DNekMat B(2*ni,2*ni,0.0); //approximate hessian (I to start)
624  for(int k = 0; k < 2*ni; k++)
625  {
626  B(k,k) = 1.0;
627  }
628  DNekMat H(2*ni,2*ni,0.0); //approximate inverse hessian (I to start)
629  for(int k = 0; k < 2*ni; k++)
630  {
631  H(k,k) = 1.0;
632  }
633 
634  Array<OneD,NekDouble> xi(ni*2);
635  for(int k = np - ni; k < np; k++)
636  {
637  xi[(k-np+ni)*2+0] = uvi[k][0];
638  xi[(k-np+ni)*2+1] = uvi[k][1];
639  }
640 
641  DNekMat J = opti->dF(xi);
642 
643  bool repeat = true;
644  int itct = 0;
645  while(repeat)
646  {
647  NekDouble Norm = 0;
648  for(int k = 0; k < nq - 2; k++)
649  {
650  Norm += J(k,0)*J(k,0);
651  }
652  Norm = sqrt(Norm);
653 
654  if(Norm < 1E-8)
655  {
656  repeat = false;
657  break;
658  }
659  if(itct > 100)
660  {
661  cout << "failed to optimise on face " << s->GetId() << endl;
662  exit(-1);
663  break;
664  }
665  itct++;
666  cout << "Norm " << Norm << endl;
667 
668  BGFSUpdate(opti, J, B, H); //all will be updated
669  }
670 
671  uvi = opti->GetSolution();
672 
673  vector<NodeSharedPtr> honodes;
674  for(int j = np - ni; j < np; j++)
675  {
676  Array<OneD, NekDouble> loc;
677  loc = s->P(uvi[j]);
678  NodeSharedPtr nn = boost::shared_ptr<Node>(new
679  Node(0,loc[0],loc[1],loc[2]));
680  nn->SetCADSurf(surf, s, uvi[j]);
681  honodes.push_back(nn);
682  }
683 
684  f->m_faceNodes = honodes;
685  f->m_curveType = LibUtilities::eNodalTriFekete;*/
686  }
687 
688  if (m_mesh->m_verbose)
689  cout << endl;
690 }
691 }
692 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:161
boost::shared_ptr< OptiEdge > OptiEdgeSharedPtr
General purpose memory allocation routines with the ability to allocate from thread specific memory p...
STL namespace.
Represents a point in the domain.
Definition: Node.h:60
map< pair< int, int >, NekDouble > weights(set< pair< int, int > > springs, Array< OneD, NekDouble > u, Array< OneD, NekDouble > v)
set< pair< int, int > > ListOfFaceSpings(int nq)
boost::shared_ptr< Node > NodeSharedPtr
Definition: Node.h:50
PointsManagerT & PointsManager(void)
Defines a specification for a set of points.
Definition: Points.h:58
double NekDouble
2D Nodal Fekete Points on a Triangle
Definition: PointsType.h:69
boost::shared_ptr< Edge > EdgeSharedPtr
Shared pointer to an edge.
Definition: Edge.h:196
boost::shared_ptr< CADSurf > CADSurfSharedPtr
Definition: CADSurf.h:217
StandardMatrixTag boost::call_traits< LhsDataType >::const_reference rhs typedef NekMatrix< LhsDataType, StandardMatrixTag >::iterator iterator
bool BGFSUpdate(OptiObjSharedPtr opti, DNekMat &J, DNekMat &B, DNekMat &H)
Definition: BGFS-B.cpp:50
boost::unordered_set< EdgeSharedPtr, EdgeHash > EdgeSet
Definition: Edge.h:222
boost::shared_ptr< Face > FaceSharedPtr
Shared pointer to a face.
Definition: Face.h:378
HOTriangle< NodeSharedPtr > HOSurf
Definition: Triangle.h:215
void PrintProgressbar(const int position, const int goal, const string message)
Prints a progressbar.
Definition: Progressbar.hpp:70
1D Gauss-Lobatto-Legendre quadrature points
Definition: PointsType.h:50
boost::shared_ptr< CADCurve > CADCurveSharedPtr
Definition: CADCurve.h:168