tetmesh_faceted_surfaces.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 //LIC//
8 //LIC// This library is free software; you can redistribute it and/or
9 //LIC// modify it under the terms of the GNU Lesser General Public
10 //LIC// License as published by the Free Software Foundation; either
11 //LIC// version 2.1 of the License, or (at your option) any later version.
12 //LIC//
13 //LIC// This library is distributed in the hope that it will be useful,
14 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 //LIC// Lesser General Public License for more details.
17 //LIC//
18 //LIC// You should have received a copy of the GNU Lesser General Public
19 //LIC// License along with this library; if not, write to the Free Software
20 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 //LIC// 02110-1301 USA.
22 //LIC//
23 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 //LIC//
25 //LIC//====================================================================
26 
27 
28 //Include guard to prevent multiple inclusions of the header
29 #ifndef OOMPH_TETMESH_FACETED_SURFACES_HEADER
30 #define OOMPH_TETMESH_FACETED_SURFACES_HEADER
31 
32 // Config header generated by autoconfig
33 #ifdef HAVE_CONFIG_H
34  #include <oomph-lib-config.h>
35 #endif
36 
37 
38 namespace oomph
39 {
40 
41 //================================================================
43 //================================================================
44 namespace HelperForSortingVectorOfPairsOfVertexPtAndDouble
45 {
47  bool less_than_based_on_double(std::pair<TetMeshVertex*,double> i,
48  std::pair<TetMeshVertex*,double> j)
49  {
50  return (i.second<j.second);
51  }
52 
53 }
54 
55 
59 
60 
61 
62 //=============================================================================
64 //=============================================================================
66 {
67 
68 
69 public:
70 
74  CubicTetMeshFacetedSurface(const double& box_half_width,
75  const double& box_half_length,
76  const unsigned& one_based_boundary_id_offset=0)
77  {
78  unsigned one_based_region_id=0;
79  Vector<double> offset(3,0.0);
80  build_it(one_based_region_id,
81  box_half_width,
82  box_half_length,
83  offset,
84  one_based_boundary_id_offset);
85  }
86 
90  CubicTetMeshFacetedSurface(const double& box_half_width,
91  const double& box_half_length,
92  const Vector<double>& offset,
93  const unsigned& one_based_boundary_id_offset=0)
94  {
95  unsigned one_based_region_id=0;
96  build_it(one_based_region_id,
97  box_half_width,
98  box_half_length,
99  offset,
100  one_based_boundary_id_offset);
101  }
107  CubicTetMeshFacetedSurface(const unsigned& one_based_region_id,
108  const double& box_half_width,
109  const double& box_half_length,
110  const unsigned& one_based_boundary_id_offset=0)
111  {
112  Vector<double> offset(3,0.0);
113  build_it(one_based_region_id,
114  box_half_width,
115  box_half_length,
116  offset,
117  one_based_boundary_id_offset);
118  }
119 
125  CubicTetMeshFacetedSurface(const unsigned& one_based_region_id,
126  const double& box_half_width,
127  const double& box_half_length,
128  const Vector<double>& offset,
129  const unsigned& one_based_boundary_id_offset=0)
130  {
131  build_it(one_based_region_id,
132  box_half_width,
133  box_half_length,
134  offset,
135  one_based_boundary_id_offset);
136  }
137 
138 
139 private:
140 
142  void build_it(const unsigned& one_based_region_id,
143  const double& box_half_width,
144  const double& box_half_length,
145  const Vector<double>& offset,
146  const unsigned& one_based_boundary_id_offset)
147  {
148  // Make vertices
149  unsigned n_vertex=8;
150  Vertex_pt.resize(n_vertex);
151  Vector<double> box_point(3);
152 
153  box_point[0] = offset[0]-box_half_width;
154  box_point[1] = offset[1]-box_half_width;
155  box_point[2] = offset[2]-box_half_length;
156  Vertex_pt[0]=new TetMeshVertex(box_point);
157 
158  box_point[0] = offset[0]-box_half_width;
159  box_point[1] = offset[1]+box_half_width;
160  box_point[2] = offset[2]-box_half_length;
161  Vertex_pt[1]=new TetMeshVertex(box_point);
162 
163  box_point[0] = offset[0]-box_half_width;
164  box_point[1] = offset[1]+box_half_width;
165  box_point[2] = offset[2]+box_half_length;
166  Vertex_pt[2]=new TetMeshVertex(box_point);
167 
168  box_point[0] = offset[0]-box_half_width;
169  box_point[1] = offset[1]-box_half_width;
170  box_point[2] = offset[2]+box_half_length;
171  Vertex_pt[3]=new TetMeshVertex(box_point);
172 
173  box_point[0] = offset[0]+box_half_width;
174  box_point[1] = offset[1]-box_half_width;
175  box_point[2] = offset[2]-box_half_length;
176  Vertex_pt[4]=new TetMeshVertex(box_point);
177 
178  box_point[0] = offset[0]+box_half_width;
179  box_point[1] = offset[1]+box_half_width;
180  box_point[2] = offset[2]-box_half_length;
181  Vertex_pt[5]=new TetMeshVertex(box_point);
182 
183  box_point[0] = offset[0]+box_half_width;
184  box_point[1] = offset[1]+box_half_width;
185  box_point[2] = offset[2]+box_half_length;
186  Vertex_pt[6]=new TetMeshVertex(box_point);
187 
188  box_point[0] = offset[0]+box_half_width;
189  box_point[1] = offset[1]-box_half_width;
190  box_point[2] = offset[2]+box_half_length;
191  Vertex_pt[7]=new TetMeshVertex(box_point);
192 
193 
194  // Make facets
195  unsigned n_facet=6;
196  Facet_pt.resize(n_facet);
197 
198  unsigned n_vertex_on_facet=4;
199  Facet_pt[0]=new TetMeshFacet(n_vertex_on_facet);
200  unsigned one_based_boundary_id=1+one_based_boundary_id_offset;
201  Facet_pt[0]->set_one_based_boundary_id(one_based_boundary_id);
202  Facet_pt[0]->set_vertex_pt(0,Vertex_pt[0]);
203  Facet_pt[0]->set_vertex_pt(1,Vertex_pt[4]);
204  Facet_pt[0]->set_vertex_pt(2,Vertex_pt[7]);
205  Facet_pt[0]->set_vertex_pt(3,Vertex_pt[3]);
206 
207  Facet_pt[1]=new TetMeshFacet(n_vertex_on_facet);
208  one_based_boundary_id=2+one_based_boundary_id_offset;
209  Facet_pt[1]->set_one_based_boundary_id(one_based_boundary_id);
210  Facet_pt[1]->set_vertex_pt(0,Vertex_pt[4]);
211  Facet_pt[1]->set_vertex_pt(1,Vertex_pt[5]);
212  Facet_pt[1]->set_vertex_pt(2,Vertex_pt[6]);
213  Facet_pt[1]->set_vertex_pt(3,Vertex_pt[7]);
214 
215  // top
216  Facet_pt[2]=new TetMeshFacet(n_vertex_on_facet);
217  one_based_boundary_id=3+one_based_boundary_id_offset;
218  Facet_pt[2]->set_one_based_boundary_id(one_based_boundary_id);
219  Facet_pt[2]->set_vertex_pt(0,Vertex_pt[3]);
220  Facet_pt[2]->set_vertex_pt(1,Vertex_pt[7]);
221  Facet_pt[2]->set_vertex_pt(2,Vertex_pt[6]);
222  Facet_pt[2]->set_vertex_pt(3,Vertex_pt[2]);
223 
224  Facet_pt[3]=new TetMeshFacet(n_vertex_on_facet);
225  one_based_boundary_id=4+one_based_boundary_id_offset;
226  Facet_pt[3]->set_one_based_boundary_id(one_based_boundary_id);
227  Facet_pt[3]->set_vertex_pt(0,Vertex_pt[6]);
228  Facet_pt[3]->set_vertex_pt(1,Vertex_pt[5]);
229  Facet_pt[3]->set_vertex_pt(2,Vertex_pt[1]);
230  Facet_pt[3]->set_vertex_pt(3,Vertex_pt[2]);
231 
232  Facet_pt[4]=new TetMeshFacet(n_vertex_on_facet);
233  one_based_boundary_id=5+one_based_boundary_id_offset;
234  Facet_pt[4]->set_one_based_boundary_id(one_based_boundary_id);
235  Facet_pt[4]->set_vertex_pt(0,Vertex_pt[3]);
236  Facet_pt[4]->set_vertex_pt(1,Vertex_pt[2]);
237  Facet_pt[4]->set_vertex_pt(2,Vertex_pt[1]);
238  Facet_pt[4]->set_vertex_pt(3,Vertex_pt[0]);
239 
240  // bottom
241  Facet_pt[5]=new TetMeshFacet(n_vertex_on_facet);
242  one_based_boundary_id=6+one_based_boundary_id_offset;
243  Facet_pt[5]->set_one_based_boundary_id(one_based_boundary_id);
244  Facet_pt[5]->set_vertex_pt(0,Vertex_pt[5]);
245  Facet_pt[5]->set_vertex_pt(1,Vertex_pt[1]);
246  Facet_pt[5]->set_vertex_pt(2,Vertex_pt[0]);
247  Facet_pt[5]->set_vertex_pt(3,Vertex_pt[4]);
248 
249 
250  // Specify the adjacent region that is bounded by these facets
251  for (unsigned f=0;f<6;f++)
252  {
253  Facet_pt[f]->set_one_based_adjacent_region_id(one_based_region_id);
254  }
255 
256  // Is it a genuine region?
257  if (one_based_region_id>0)
258  {
259  set_region_for_tetgen(one_based_region_id-1,offset);
260  }
261  // Otherwise declare it to be a hole
262  else
263  {
264  set_hole_for_tetgen(offset);
266  }
267 
268  }
269 
270 };
271 
272 
273 
277 
278 
279 
280 //=============================================================================
282 //=============================================================================
284 {
285 
286 
287 public:
288 
289 
292  RectangularTetMeshFacetedSurface(const double& half_x_width,
293  const double& half_y_length,
294  const Vector<double>& offset,
295  const unsigned& one_based_boundary_id)
296  {
297  build_it(half_x_width,
298  half_y_length,
299  offset,
300  one_based_boundary_id);
301  }
302 
303 
304 
305 private:
306 
308  void build_it(const double& half_x_width,
309  const double& half_y_length,
310  const Vector<double>& offset,
311  const unsigned& one_based_boundary_id)
312  {
313  // Make vertices
314  unsigned n_vertex=4;
315  Vertex_pt.resize(n_vertex);
316  Vector<double> box_point(3);
317 
318  box_point[0] = offset[0]-half_x_width;
319  box_point[1] = offset[1]-half_y_length;
320  box_point[2] = offset[2];
321  Vertex_pt[0]=new TetMeshVertex(box_point);
322 
323  box_point[0] = offset[0]+half_x_width;
324  box_point[1] = offset[1]-half_y_length;
325  box_point[2] = offset[2];
326  Vertex_pt[1]=new TetMeshVertex(box_point);
327 
328  box_point[0] = offset[0]+half_x_width;
329  box_point[1] = offset[1]+half_y_length;
330  box_point[2] = offset[2];
331  Vertex_pt[2]=new TetMeshVertex(box_point);
332 
333  box_point[0] = offset[0]-half_x_width;
334  box_point[1] = offset[1]+half_y_length;
335  box_point[2] = offset[2];
336  Vertex_pt[3]=new TetMeshVertex(box_point);
337 
338 
339  // Make facets
340  unsigned n_facet=1;
341  Facet_pt.resize(n_facet);
342 
343  unsigned n_vertex_on_facet=4;
344  Facet_pt[0]=new TetMeshFacet(n_vertex_on_facet);
345  Facet_pt[0]->set_one_based_boundary_id(one_based_boundary_id);
346  Facet_pt[0]->set_vertex_pt(0,Vertex_pt[0]);
347  Facet_pt[0]->set_vertex_pt(1,Vertex_pt[1]);
348  Facet_pt[0]->set_vertex_pt(2,Vertex_pt[2]);
349  Facet_pt[0]->set_vertex_pt(3,Vertex_pt[3]);
350 
351  }
352 
353 };
354 
355 
359 
360 
361 
362 //================================================================
364 //================================================================
366 {
367 
368 
369 public:
370 
379  disk_parametrised_by_nonsingular_coordinates_pt,
380  const unsigned& half_nsegment,
381  const unsigned& first_one_based_boundary_id_for_disk,
382  unsigned& last_one_based_boundary_id_for_disk)
383 
384  {
386  disk_parametrised_by_nonsingular_coordinates_pt;
387 
388  // Provide storage for pointers to the two parts of the curvilinear boundary
389  Vector<TriangleMeshCurveSection*> outer_curvilinear_boundary_pt(2);
390 
391  // First bit
392  GeomObject* outer_boundary_ellipse0_pt=
393  disk_parametrised_by_nonsingular_coordinates_pt->
394  boundary_parametrising_geom_object_pt(0);
395  double zeta_start=disk_parametrised_by_nonsingular_coordinates_pt->
396  zeta_boundary_start(0);
397  double zeta_end=disk_parametrised_by_nonsingular_coordinates_pt->
398  zeta_boundary_end(0);
399  unsigned nsegment=half_nsegment;
400  unsigned boundary_id=0;
401  outer_curvilinear_boundary_pt[0]=new TriangleMeshCurviLine(
402  outer_boundary_ellipse0_pt,zeta_start,zeta_end,nsegment,boundary_id);
403 
404  // Second bit
405  GeomObject* outer_boundary_ellipse1_pt=
406  disk_parametrised_by_nonsingular_coordinates_pt->
407  boundary_parametrising_geom_object_pt(1);
408  zeta_start=disk_parametrised_by_nonsingular_coordinates_pt->
409  zeta_boundary_start(1);
410  zeta_end=disk_parametrised_by_nonsingular_coordinates_pt->
411  zeta_boundary_end(1);
412  nsegment=half_nsegment;
413  boundary_id=1;
414  outer_curvilinear_boundary_pt[1]=new TriangleMeshCurviLine(
415  outer_boundary_ellipse1_pt,zeta_start,zeta_end,nsegment,boundary_id);
416 
417  // Combine to curvilinear boundary and define the
418  // outer boundary
419  TriangleMeshClosedCurve* closed_curve_pt=
420  new TriangleMeshClosedCurve(outer_curvilinear_boundary_pt);
421 
422  // Use the TriangleMeshParameters object for helping on the manage of the
423  // TriangleMesh parameters
424  TriangleMeshParameters triangle_mesh_parameters(closed_curve_pt);
425 
426  // Do we have an annnular internal boundary?
427  if (disk_parametrised_by_nonsingular_coordinates_pt->nboundary()==4)
428  {
429 
430  // Provide storage for pointers to the two parts of the curvilinear boundary
431  Vector<TriangleMeshCurveSection*> inner_curvilinear_boundary_pt(2);
432 
433  // First bit
434  GeomObject* inner_boundary_ellipse0_pt=
435  disk_parametrised_by_nonsingular_coordinates_pt->
436  boundary_parametrising_geom_object_pt(2);
437  double zeta_start=disk_parametrised_by_nonsingular_coordinates_pt->
438  zeta_boundary_start(2);
439  double zeta_end=disk_parametrised_by_nonsingular_coordinates_pt->
440  zeta_boundary_end(2);
441  unsigned nsegment=half_nsegment;
442  unsigned boundary_id=2;
443  inner_curvilinear_boundary_pt[0]=new TriangleMeshCurviLine(
444  inner_boundary_ellipse0_pt,zeta_start,zeta_end,nsegment,boundary_id);
445 
446  // Second bit
447  GeomObject* inner_boundary_ellipse1_pt=
448  disk_parametrised_by_nonsingular_coordinates_pt->
449  boundary_parametrising_geom_object_pt(3);
450  zeta_start=disk_parametrised_by_nonsingular_coordinates_pt->
451  zeta_boundary_start(3);
452  zeta_end=disk_parametrised_by_nonsingular_coordinates_pt->
453  zeta_boundary_end(3);
454  nsegment=half_nsegment;
455  boundary_id=3;
456  inner_curvilinear_boundary_pt[1]=new TriangleMeshCurviLine(
457  inner_boundary_ellipse1_pt,zeta_start,zeta_end,nsegment,boundary_id);
458 
459  // Combine to curvilinear boundary and define the
460  // inner boundary
461  TriangleMeshClosedCurve* inner_curve_pt=
462  new TriangleMeshClosedCurve(inner_curvilinear_boundary_pt);
463 
464 
465  Vector<TriangleMeshClosedCurve *> inner_boundaries_pt(1);
466  inner_boundaries_pt[0]=inner_curve_pt;
467 
468  // Specify the internal closed boundaries
469  triangle_mesh_parameters.internal_closed_curve_pt() = inner_boundaries_pt;
470 
471 
472 
473  // Let's get a map of region coordinates (if any!)
474  std::map<unsigned, Vector<double> > zeta_in_region_map=
475  disk_parametrised_by_nonsingular_coordinates_pt->zeta_in_region();
476  for (std::map<unsigned, Vector<double> >::iterator it=
477  zeta_in_region_map.begin();it!=zeta_in_region_map.end();it++)
478  {
479  // Pass information about the defined regions
480  unsigned r=(*it).first;
481  Vector<double> region_coords=(*it).second;
482  triangle_mesh_parameters.add_region_coordinates(r,region_coords);
483  }
484 
485  }
486 
487  // Specify the element area so that it matches the boundary discretisation
488  double uniform_element_area=sqrt(3.0)/4.0*
489  pow(2.0*MathematicalConstants::Pi/(2.0*double(half_nsegment)),2);
490  triangle_mesh_parameters.element_area() = uniform_element_area;
491 
492  // Create the mesh
493  Tri_mesh_pt = new
494  TriangleMesh<TPoissonElement<2,2> >(triangle_mesh_parameters);
495 
496  // Loop over all boundary elements and rotate their nodes so that
497  // the first two nodes are on the boundary
498  std::map<FiniteElement*,bool> is_on_boundary;
499  for (unsigned b=0;b<2;b++)
500  {
501  unsigned nel=Tri_mesh_pt->nboundary_element(b);
502  for (unsigned e=0;e<nel;e++)
503  {
504  FiniteElement* el_pt=Tri_mesh_pt->boundary_element_pt(b,e);
505  unsigned count=0;
506  for (unsigned j=0;j<3;j++)
507  {
508  Node* nod_pt=el_pt->node_pt(j);
509  if (nod_pt->is_on_boundary()) count++;
510  }
511  if (count==2)
512  {
513  is_on_boundary[el_pt]=true;
514  if ((el_pt->node_pt(0)->is_on_boundary())&&
515  (el_pt->node_pt(1)->is_on_boundary()))
516  {
517  // fine
518  }
519  else
520  {
521  // Reorder nodes so that the first two nodes are on the boundary
522  Node* nod0_pt=el_pt->node_pt(0);
523  Node* nod1_pt=el_pt->node_pt(1);
524  Node* nod2_pt=el_pt->node_pt(2);
525  if (!el_pt->node_pt(0)->is_on_boundary())
526  {
527  el_pt->node_pt(0)=nod1_pt;
528  el_pt->node_pt(1)=nod2_pt;
529  el_pt->node_pt(2)=nod0_pt;
530  }
531  else if (!el_pt->node_pt(1)->is_on_boundary())
532  {
533  el_pt->node_pt(0)=nod2_pt;
534  el_pt->node_pt(1)=nod0_pt;
535  el_pt->node_pt(2)=nod1_pt;
536  }
537  else
538  {
539  std::ostringstream error_message;
540  error_message << "This doesn't make sense!";
541  throw OomphLibError(error_message.str(),
544  }
545  }
546  }
547  else
548  {
549  std::ostringstream error_message;
550  error_message <<
551  "Boundary simplex element doesn't have two nodes on boundary!";
552  throw OomphLibError(error_message.str(),
555  }
556  }
557  }
558 
559 
560  // Now loop over all nodes and turn them into vertices
561  unsigned nnod=Tri_mesh_pt->nnode();
562  Vertex_pt.resize(nnod);
563  for (unsigned j=0;j<nnod;j++)
564  {
565  Node* nod_pt=Tri_mesh_pt->node_pt(j);
566  Vector<double> sheet_point(3,0.0);
567  Vector<double> zeta(nod_pt->position());
569  Vertex_pt[j]=new TetMeshVertex(sheet_point);
570  Vertex_pt[j]->set_zeta_in_geom_object(zeta);
572  }
573 
574 
575  // Quick count to see how many elements/facets are on the boundary
577  unsigned nel=Tri_mesh_pt->nelement();
578  for (unsigned e=0;e<nel;e++)
579  {
580  FiniteElement* el_pt=Tri_mesh_pt->finite_element_pt(e);
581  if (is_on_boundary[el_pt])
582  {
584  }
585  }
586 
587  // Angles of right/left node on boundary (for snapping)
588  Left_boundary_coordinate.resize(nel,0.0);
589  Right_boundary_coordinate.resize(nel,0.0);
590  Boundary_id.resize(nel,0.0);
591 
592  // Now loop over all elements
593  Nfacet=nel;
594  Facet_pt.resize(Nfacet);
595  Facet_is_on_boundary.resize(Nfacet,false);
596  unsigned n_vertex_on_facet=3;
597  for (unsigned e=0;e<nel;e++)
598  {
599  FiniteElement* el_pt=Tri_mesh_pt->finite_element_pt(e);
600  if (is_on_boundary[el_pt])
601  {
602  Node* left_node_pt=el_pt->node_pt(0);
603  Node* right_node_pt=el_pt->node_pt(1);
604  Vector<double> boundary_zeta(1);
605  if (left_node_pt->is_on_boundary(0)&&
606  right_node_pt->is_on_boundary(0))
607  {
608  unsigned b=0;
609  left_node_pt->get_coordinates_on_boundary(b,boundary_zeta);
610  Left_boundary_coordinate[e]=boundary_zeta[0];
611  right_node_pt->get_coordinates_on_boundary(b,boundary_zeta);
612  Right_boundary_coordinate[e]=boundary_zeta[0];
613  Boundary_id[e]=b;
614  }
615  else if (left_node_pt->is_on_boundary(1)&&
616  right_node_pt->is_on_boundary(1))
617  {
618  unsigned b=1;
619  left_node_pt->get_coordinates_on_boundary(b,boundary_zeta);
620  Left_boundary_coordinate[e]=boundary_zeta[0];
621  right_node_pt->get_coordinates_on_boundary(b,boundary_zeta);
622  Right_boundary_coordinate[e]=boundary_zeta[0];
623  Boundary_id[e]=b;
624  }
625  else
626  {
627  std::ostringstream error_message;
628  error_message << "never get here!";
629  throw OomphLibError(error_message.str(),
632  }
633  Facet_is_on_boundary[e]=true;
634  }
635  Facet_pt[e]=new TetMeshFacet(n_vertex_on_facet);
636  unsigned one_based_boundary_id=first_one_based_boundary_id_for_disk+e;
637  Facet_pt[e]->set_one_based_boundary_id(one_based_boundary_id);
638  last_one_based_boundary_id_for_disk=one_based_boundary_id;
639  for (unsigned j=0;j<3;j++)
640  {
641  Facet_pt[e]->set_vertex_pt(j,Equivalent_vertex_pt[el_pt->node_pt(j)]);
642  }
643  }
644  }
645 
646 
649  {
650  delete Tri_mesh_pt;
651  Tri_mesh_pt=0;
652  }
653 
659  void boundary_zeta01(const unsigned& facet_id,
660  const double& zeta_boundary,
662  {
663  if (Facet_is_on_boundary[facet_id])
664  {
665  double phi0=Left_boundary_coordinate[facet_id];
666  double phi1=Right_boundary_coordinate[facet_id];
667  double phi=phi0+(phi1-phi0)*zeta_boundary;
668 
669  unsigned b=Boundary_id[facet_id];
670  double zeta_bound=phi;
672  zeta_bound,
673  zeta);
674  }
675  else
676  {
677  Vector<double> zeta0=Facet_pt[facet_id]->
679  Vector<double> zeta1=Facet_pt[facet_id]->
681  zeta[0]=zeta0[0]+(zeta1[0]-zeta0[0])*zeta_boundary;
682  zeta[1]=zeta0[1]+(zeta1[1]-zeta0[1])*zeta_boundary;
683  }
684  }
685 
686 
687 protected:
688 
690  unsigned Nfacet;
691 
693  std::vector<bool> Facet_is_on_boundary;
694 
697 
700 
703 
706 
707 
710 
711 
713  std::map<Node*,TetMeshVertex*> Equivalent_vertex_pt;
714 
715 };
716 
717 
718 
719 
720 
724 
725 
726 
727 //================================================================
729 //================================================================
732 {
733 
734 
735 public:
736 
759  disk_parametrised_by_nonsingular_coordinates_pt,
760  const unsigned& half_nsegment,
761  const double& r_torus,
762  const unsigned& nvertex_torus,
763  const unsigned& first_one_based_boundary_id_for_disk,
764  const unsigned& one_based_torus_region_id,
765  unsigned& last_one_based_boundary_id_for_disk,
766  unsigned& first_one_based_boundary_id_for_torus,
767  unsigned& last_one_based_boundary_id_for_torus,
768  Vector<unsigned>& one_based_boundary_id_for_disk_within_torus,
769  Vector<unsigned>& one_based_boundary_id_for_disk_outside_torus) :
771  disk_parametrised_by_nonsingular_coordinates_pt,
772  half_nsegment,
773  first_one_based_boundary_id_for_disk,
774  last_one_based_boundary_id_for_disk)
775  {
776  // Wipe
777  one_based_boundary_id_for_disk_within_torus.clear();
778  one_based_boundary_id_for_disk_outside_torus.clear();
779 
780 
781  // Is element in torus region or not?
782  std::map<FiniteElement*,bool> is_in_torus_region;
783  {
784  unsigned r=1;
785  /* ofstream some_file; */
786  /* some_file.open("tri_mesh_in_region1.dat"); */
787  unsigned nel=Tri_mesh_pt->nregion_element(r);
788  for(unsigned e=0;e<nel;e++)
789  {
790  FiniteElement* el_pt=Tri_mesh_pt->region_element_pt(r,e);
791  is_in_torus_region[el_pt]=true;
792  //unsigned npts=3;
793  //el_pt->output(some_file,npts);
794  }
795  //some_file.close();
796  }
797 
798 
799  // Now loop over all elements
800  unsigned nel=Tri_mesh_pt->nelement();
801  for (unsigned e=0;e<nel;e++)
802  {
803  FiniteElement* el_pt=Tri_mesh_pt->finite_element_pt(e);
804  unsigned one_based_boundary_id=Facet_pt[e]->one_based_boundary_id();
805  if (is_in_torus_region[el_pt])
806  {
807  Facet_pt[e]->set_one_based_region_that_facet_is_embedded_in
808  (one_based_torus_region_id);
809  one_based_boundary_id_for_disk_within_torus.push_back
810  (one_based_boundary_id);
811  }
812  else
813  {
814  one_based_boundary_id_for_disk_outside_torus.push_back
815  (one_based_boundary_id);
816  }
817  }
818 
819 
820  // Now add torus:
821  //---------------
822  unsigned one_based_boundary_id=last_one_based_boundary_id_for_disk+1;
823  first_one_based_boundary_id_for_torus=one_based_boundary_id;
824 
825  // Find sorted sequence of vertices going around the
826  // inner boundary (innermost part of torus)
827  Vector<TetMeshVertex*> sorted_vertex_pt;
828  Vector<std::pair<TetMeshVertex*,double> > vertex_pt_and_boundary_coord;
829  std::map<Node*,bool> done;
830  Vector<double> boundary_zeta(1);
831  for (unsigned b=2;b<=3;b++)
832  {
833  unsigned nnod=Tri_mesh_pt->nboundary_node(b);
834  for (unsigned j=0;j<nnod;j++)
835  {
836  Node* nod_pt=Tri_mesh_pt->boundary_node_pt(b,j);
837  if (!done[nod_pt])
838  {
839  nod_pt->get_coordinates_on_boundary(b,boundary_zeta);
840  vertex_pt_and_boundary_coord.push_back(
841  std::make_pair(Equivalent_vertex_pt[nod_pt],
842  boundary_zeta[0]));
843  done[nod_pt]=true;
844  }
845  }
846  }
847 
848 
849 
850  oomph_info << "Number of vertices on inner ring: "
851  << vertex_pt_and_boundary_coord.size() << " "
852  << " sum: "
853  << Tri_mesh_pt->nboundary_node(2)+Tri_mesh_pt->nboundary_node(3)
854  << std::endl;
855 
856  // Identify point in torus (for tetgen)
857  Vector<double> point_in_torus(3);
858  unsigned b=0;
859  unsigned j=0;
860  Node* nod_pt=Tri_mesh_pt->boundary_node_pt(b,j);
861  point_in_torus[0]=Equivalent_vertex_pt[nod_pt]->x(0);
862  point_in_torus[1]=Equivalent_vertex_pt[nod_pt]->x(1);
863  point_in_torus[2]=Equivalent_vertex_pt[nod_pt]->x(2)+0.5*r_torus;
864 
865  oomph_info << "point in torus: "
866  << point_in_torus[0] << " "
867  << point_in_torus[1] << " "
868  << point_in_torus[2] << " "
869  << std::endl;
870 
871  // Sort based on boundary coordinate
872  std::sort (vertex_pt_and_boundary_coord.begin(),
873  vertex_pt_and_boundary_coord.end(),
874  HelperForSortingVectorOfPairsOfVertexPtAndDouble::
876 
877  // Loop over annular rings
878  unsigned n_vertices_on_annular_ring=nvertex_torus;
879  unsigned n_new_vertices_on_annular_ring=
880  n_vertices_on_annular_ring-2;
881 
882 
883  // Storage for vertices and facets
884  unsigned nv=Vertex_pt.size();
885  unsigned jv=nv;
886  nv+=n_new_vertices_on_annular_ring*
887  vertex_pt_and_boundary_coord.size();
888  Vertex_pt.resize(nv);
889 
890  unsigned jf=Nfacet;
891  Nfacet+=(n_new_vertices_on_annular_ring+1)*
892  (vertex_pt_and_boundary_coord.size());
893  Facet_pt.resize(Nfacet);
894 
895 
896  unsigned new_vertex_count=0;
897  unsigned new_facet_count=0;
898  unsigned n=vertex_pt_and_boundary_coord.size();
899  Vector<Vector<TetMeshVertex*> > annulus_vertex_pt(n);
900  for (unsigned j=0;j<n;j++)
901  {
902 
903  // Wrap around for simplicity
904  annulus_vertex_pt[j].resize(n_vertices_on_annular_ring);
905  annulus_vertex_pt[j][0]=vertex_pt_and_boundary_coord[j].first;
906  annulus_vertex_pt[j][n_vertices_on_annular_ring-1]=
907  vertex_pt_and_boundary_coord[j].first;
908 
909  // Position of vertex
910  Vector<double> vertex_position(3);
911  vertex_position[0]=vertex_pt_and_boundary_coord[j].first->x(0);
912  vertex_position[1]=vertex_pt_and_boundary_coord[j].first->x(1);
913  vertex_position[2]=vertex_pt_and_boundary_coord[j].first->x(2);
914 
915  // Polar angle
916  double theta=vertex_pt_and_boundary_coord[j].second;
917 
918  // Which boundary is this point located on?
919  unsigned b=0;
921  {
922  b=1;
923  }
924  double zeta_bound=theta;
925 
926  // Get coordinate on edge and normal and tangent vectors
927  Vector<double> x(3);
928  Vector<double> r_edge(3);
930  Vector<double> tangent(3);
931  Vector<double> normal_normal(3);
933  zeta_bound,
934  r_edge,
935  tangent,
936  normal,
937  normal_normal);
938 
939  // What rho do we need to create a circle, centred at the edge
940  // going through current vertex?
941  Vector<double> distance_to_edge(3);
942  distance_to_edge[0]=r_edge[0]-vertex_position[0];
943  distance_to_edge[1]=r_edge[1]-vertex_position[1];
944  distance_to_edge[2]=r_edge[2]-vertex_position[2];
945  double rho=sqrt(distance_to_edge[0]*distance_to_edge[0]+
946  distance_to_edge[1]*distance_to_edge[1]+
947  distance_to_edge[2]*distance_to_edge[2]);
948 
949  // What is the starting angle?
950  double cos_phi0=(distance_to_edge[0]*normal[0]+
951  distance_to_edge[1]*normal[1]+
952  distance_to_edge[2]*normal[2])/rho;
953  if (cos_phi0>1.0) cos_phi0=1.0;
954  if (cos_phi0<-1.0) cos_phi0=-1.0;
955 
956  double phi_0=acos(cos_phi0);
957 
958  for (unsigned i=1;i<n_vertices_on_annular_ring-1;i++)
959  {
960  double phi=phi_0+double(i)/double(n_vertices_on_annular_ring-1)*
962  x[0]=r_edge[0]+rho*cos(phi)*normal[0]+rho*sin(phi)*normal_normal[0];
963  x[1]=r_edge[1]+rho*cos(phi)*normal[1]+rho*sin(phi)*normal_normal[1];
964  x[2]=r_edge[2]+rho*cos(phi)*normal[2]+rho*sin(phi)*normal_normal[2];
965 
966  TetMeshVertex* new_vertex_pt=new TetMeshVertex(x);
967  annulus_vertex_pt[j][i]=new_vertex_pt;
968  Vertex_pt[jv]=new_vertex_pt;
969  jv++;
970  new_vertex_count++;
971  }
972  }
973 
974  for (unsigned i=0;i<n-1;i++)
975  {
976  unsigned m=annulus_vertex_pt[i].size();
977  for (unsigned j=0;j<m-1;j++)
978  {
979  unsigned n_vertex_on_facet=4;
980  TetMeshFacet* new_facet_pt=new TetMeshFacet(n_vertex_on_facet);
981  new_facet_count++;
982  new_facet_pt->set_vertex_pt(0,annulus_vertex_pt[i][j]);
983  new_facet_pt->set_vertex_pt(1,annulus_vertex_pt[i][j+1]);
984  new_facet_pt->set_vertex_pt(2,annulus_vertex_pt[i+1][j+1]);
985  new_facet_pt->set_vertex_pt(3,annulus_vertex_pt[i+1][j]);
986  Facet_pt[jf]=new_facet_pt;
987  unsigned region_id=one_based_torus_region_id;
988  Facet_pt[jf]->set_one_based_adjacent_region_id(region_id);
989  Facet_pt[jf]->set_one_based_boundary_id(one_based_boundary_id);
990  one_based_boundary_id++;
991  jf++;
992  }
993  }
994 
995  unsigned m=annulus_vertex_pt[n-1].size();
996  for (unsigned j=0;j<m-1;j++)
997  {
998  unsigned n_vertex_on_facet=4;
999  TetMeshFacet* new_facet_pt=new TetMeshFacet(n_vertex_on_facet);
1000  new_facet_count++;
1001  new_facet_pt->set_vertex_pt(0,annulus_vertex_pt[n-1][j]);
1002  new_facet_pt->set_vertex_pt(1,annulus_vertex_pt[n-1][j+1]);
1003  new_facet_pt->set_vertex_pt(2,annulus_vertex_pt[0][j+1]);
1004  new_facet_pt->set_vertex_pt(3,annulus_vertex_pt[0][j]);
1005  Facet_pt[jf]=new_facet_pt;
1006  unsigned region_id=one_based_torus_region_id;
1007  Facet_pt[jf]->set_one_based_adjacent_region_id(region_id);
1008  Facet_pt[jf]->set_one_based_boundary_id(one_based_boundary_id);
1009  last_one_based_boundary_id_for_torus=one_based_boundary_id;
1010  one_based_boundary_id++;
1011  jf++;
1012  }
1013 
1014  oomph_info << "First/last one-based disk boundary ID: "
1015  << first_one_based_boundary_id_for_disk << " "
1016  << last_one_based_boundary_id_for_disk << std::endl;
1017 
1018 
1019  oomph_info << "First/last one-based torus boundary ID: "
1020  << first_one_based_boundary_id_for_torus << " "
1021  << last_one_based_boundary_id_for_torus << std::endl;
1022 
1023 
1024  // Is it a genuine region?
1025  if (one_based_torus_region_id>0)
1026  {
1027  set_region_for_tetgen(one_based_torus_region_id-1,point_in_torus);
1028  }
1029  else
1030  {
1031  std::ostringstream error_message;
1032  error_message << "one_based_torus_region_id must be strictly positive";
1033  throw OomphLibError(error_message.str(),
1036  }
1037 
1038 
1039 
1040  }
1041 
1042 
1043 };
1044 
1045 
1049 
1050 
1051 
1052 
1053 
1054 
1058 
1059 
1060 
1061 //================================================================
1064 //================================================================
1067 {
1068 
1069 
1070 public:
1071 
1088  disk_parametrised_by_nonsingular_coordinates_pt,
1089  const unsigned& half_nsegment,
1090  const unsigned& first_one_based_boundary_id_for_disk,
1091  const unsigned& one_based_region_id_above_disk,
1092  const unsigned& one_based_region_id_below_disk,
1093  unsigned& last_one_based_boundary_id_for_disk,
1094  unsigned& last_one_based_boundary_id) :
1095  DiskTetMeshFacetedSurface(disk_parametrised_by_nonsingular_coordinates_pt,
1096  half_nsegment,
1097  first_one_based_boundary_id_for_disk,
1098  last_one_based_boundary_id_for_disk)
1099  {
1100 
1101  // Currently: Number of facets = number of elements on disk.
1102  // Set bounding region numbers for existing facets:
1103  unsigned nel=Nfacet;
1104  for (unsigned e=0;e<Nfacet;e++)
1105  {
1106  Facet_pt[e]->set_one_based_adjacent_region_id(
1107  one_based_region_id_above_disk);
1108  Facet_pt[e]->set_one_based_adjacent_region_id(
1109  one_based_region_id_below_disk);
1110  }
1111 
1112  // Additional facets: one square facet moving up/down from each
1113  // side and two lids.
1115  Facet_pt.resize(Nfacet);
1116  Facet_is_on_boundary.resize(Nfacet,false);
1117 
1118  // Find sorted sequence of vertices going around the
1119  // perimeter of the disk
1120  Vector<TetMeshVertex*> sorted_perimeter_vertex_pt;
1121  std::set<TetMeshFacet*> boundary_facet_pt;
1122  bool first=true;
1123  for (unsigned e=0;e<nel;e++)
1124  {
1125  if (Facet_is_on_boundary[e])
1126  {
1127  boundary_facet_pt.insert(Facet_pt[e]);
1128  if (first)
1129  {
1130  TetMeshVertex* vertex0_pt=Facet_pt[e]->vertex_pt(0);
1131  sorted_perimeter_vertex_pt.push_back(vertex0_pt);
1132  first=false;
1133  }
1134  }
1135  }
1136  while (boundary_facet_pt.size()!=1)
1137  {
1138  for (std::set<TetMeshFacet*>::iterator it=boundary_facet_pt.begin();
1139  it!=boundary_facet_pt.end();it++)
1140  {
1141  unsigned n_last=sorted_perimeter_vertex_pt.size();
1142  if (sorted_perimeter_vertex_pt[n_last-1]==
1143  (*it)->vertex_pt(0))
1144  {
1145  sorted_perimeter_vertex_pt.push_back((*it)->vertex_pt(1));
1146  boundary_facet_pt.erase(*it);
1147  break;
1148  }
1149  }
1150  }
1151 
1152  //Find mean position
1153  double z_mean=0.0;
1154  double z_min= DBL_MAX;
1155  double z_max=-DBL_MAX;
1156  unsigned n=sorted_perimeter_vertex_pt.size();
1157  for (unsigned j=0;j<n;j++)
1158  {
1159  double z=sorted_perimeter_vertex_pt[j]->x(2);
1160  z_mean+=z;
1161  if (z>z_max) z_max=z;
1162  if (z<z_min) z_min=z;
1163  }
1164  z_mean/=double(n);
1165  double layer_thickness=0.6*(z_max-z_min);
1166 
1167  // Loop over upper/lower layer
1168  unsigned facet_count=nel;
1169  int offset_sign=-1;
1170  unsigned one_based_boundary_id=last_one_based_boundary_id_for_disk+1;
1171  unsigned n_vertex_on_disk=Vertex_pt.size();
1172  unsigned n_vertex_on_disk_perimeter=sorted_perimeter_vertex_pt.size();
1173  for (unsigned i_offset=0;i_offset<2;i_offset++)
1174  {
1175  unsigned one_based_region_id=one_based_region_id_below_disk;
1176  if (i_offset==1) one_based_region_id=one_based_region_id_above_disk;
1177 
1178  for (unsigned j=0;j<n_vertex_on_disk_perimeter;j++)
1179  {
1180  Vector<double> posn(3);
1181  posn[0]=sorted_perimeter_vertex_pt[j]->x(0);
1182  posn[1]=sorted_perimeter_vertex_pt[j]->x(1);
1183  posn[2]=z_mean+double(offset_sign)*layer_thickness;
1184  Vertex_pt.push_back(new TetMeshVertex(posn));
1185  }
1186  unsigned count=0;
1187  for (unsigned j=0;j<n_vertex_on_disk_perimeter-1;j++)
1188  {
1189  Facet_pt[facet_count]=new TetMeshFacet(4);
1190  Facet_pt[facet_count]->set_one_based_boundary_id(one_based_boundary_id);
1191  Facet_pt[facet_count]->set_vertex_pt(0,sorted_perimeter_vertex_pt[j]);
1192  Facet_pt[facet_count]->set_vertex_pt(1,sorted_perimeter_vertex_pt[j+1]);
1193  Facet_pt[facet_count]->
1194  set_vertex_pt(2,Vertex_pt[n_vertex_on_disk+
1195  i_offset*n_vertex_on_disk_perimeter+j+1]);
1196  Facet_pt[facet_count]->
1197  set_vertex_pt(3,Vertex_pt[n_vertex_on_disk+
1198  i_offset*n_vertex_on_disk_perimeter+j ]);
1199  Facet_pt[facet_count]->
1200  set_one_based_adjacent_region_id(one_based_region_id);
1201  count++;
1202  facet_count++;
1203  one_based_boundary_id++;
1204  }
1205  Facet_pt[facet_count]=new TetMeshFacet(4);
1206  Facet_pt[facet_count]->set_one_based_boundary_id(one_based_boundary_id);
1207  Facet_pt[facet_count]->set_vertex_pt(0,sorted_perimeter_vertex_pt[count]);
1208  Facet_pt[facet_count]->set_vertex_pt(1,sorted_perimeter_vertex_pt[0]);
1209  Facet_pt[facet_count]->
1210  set_vertex_pt(2,Vertex_pt[n_vertex_on_disk+
1211  i_offset*n_vertex_on_disk_perimeter+0]);
1212  Facet_pt[facet_count]->
1213  set_vertex_pt(3,Vertex_pt[n_vertex_on_disk+
1214  i_offset*n_vertex_on_disk_perimeter+count]);
1215  Facet_pt[facet_count]->
1216  set_one_based_adjacent_region_id(one_based_region_id);
1217 
1218 
1219  // Closing lid
1220  facet_count++;
1221  one_based_boundary_id++;
1222  Facet_pt[facet_count]=new TetMeshFacet(n_vertex_on_disk_perimeter);
1223  Facet_pt[facet_count]->set_one_based_boundary_id(one_based_boundary_id);
1224  for (unsigned j=0;j<n_vertex_on_disk_perimeter;j++)
1225  {
1226  Facet_pt[facet_count]->
1227  set_vertex_pt(j,Vertex_pt[n_vertex_on_disk+
1228  i_offset*n_vertex_on_disk_perimeter+j]);
1229  }
1230  Facet_pt[facet_count]->
1231  set_one_based_adjacent_region_id(one_based_region_id);
1232 
1233  // Last one used (gets assigned twice but last one sticks!)
1234  last_one_based_boundary_id=one_based_boundary_id;
1235 
1236  // Bump
1237  facet_count++;
1238  one_based_boundary_id++;
1239 
1241  Vector<double> region_point(3,0.0);
1242  region_point[2]=z_mean+0.5*double(offset_sign)*layer_thickness;
1243  set_region_for_tetgen(one_based_region_id-1,region_point);
1244 
1245  offset_sign*=-1;
1246  }
1247  }
1248 
1249 
1250 
1251 };
1252 
1253 }
1254 
1255 
1256 #endif
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
AnnoyingScalar acos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:138
AnnoyingScalar sin(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:137
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Scalar * b
Definition: benchVecAdd.cpp:17
CubicTetMeshFacetedClosedSurface from (+/- half width)^2 x +/- half length.
Definition: tetmesh_faceted_surfaces.h:66
CubicTetMeshFacetedSurface(const double &box_half_width, const double &box_half_length, const Vector< double > &offset, const unsigned &one_based_boundary_id_offset=0)
Definition: tetmesh_faceted_surfaces.h:90
CubicTetMeshFacetedSurface(const double &box_half_width, const double &box_half_length, const unsigned &one_based_boundary_id_offset=0)
Definition: tetmesh_faceted_surfaces.h:74
CubicTetMeshFacetedSurface(const unsigned &one_based_region_id, const double &box_half_width, const double &box_half_length, const Vector< double > &offset, const unsigned &one_based_boundary_id_offset=0)
Definition: tetmesh_faceted_surfaces.h:125
void build_it(const unsigned &one_based_region_id, const double &box_half_width, const double &box_half_length, const Vector< double > &offset, const unsigned &one_based_boundary_id_offset)
Build the thing.
Definition: tetmesh_faceted_surfaces.h:142
CubicTetMeshFacetedSurface(const unsigned &one_based_region_id, const double &box_half_width, const double &box_half_length, const unsigned &one_based_boundary_id_offset=0)
Definition: tetmesh_faceted_surfaces.h:107
Definition: geom_obj_with_boundary.h:67
std::map< unsigned, Vector< double > > zeta_in_region() const
Return map that stores zeta coordinates of points that identify regions.
Definition: geom_obj_with_boundary.h:307
double zeta_boundary_end(const unsigned &b) const
Definition: geom_obj_with_boundary.h:151
virtual void boundary_triad(const unsigned &b, const double &zeta_bound, Vector< double > &r, Vector< double > &tangent, Vector< double > &normal, Vector< double > &binormal)
Definition: geom_obj_with_boundary.h:159
unsigned nboundary() const
How many boundaries do we have?
Definition: geom_obj_with_boundary.h:73
void zeta_on_boundary(const unsigned &b, const double &zeta_bound, Vector< double > &zeta) const
Definition: geom_obj_with_boundary.h:91
TetMeshFacetedSurface that defines disk.
Definition: tetmesh_faceted_surfaces.h:366
~DiskTetMeshFacetedSurface()
Destructor.
Definition: tetmesh_faceted_surfaces.h:648
Vector< double > Right_boundary_coordinate
Right boundary coordinate of i-th facet.
Definition: tetmesh_faceted_surfaces.h:699
std::map< Node *, TetMeshVertex * > Equivalent_vertex_pt
Mapping between nodes and vertices.
Definition: tetmesh_faceted_surfaces.h:713
std::vector< bool > Facet_is_on_boundary
Is facet on boundary?
Definition: tetmesh_faceted_surfaces.h:693
DiskTetMeshFacetedSurface(DiskLikeGeomObjectWithBoundaries *disk_parametrised_by_nonsingular_coordinates_pt, const unsigned &half_nsegment, const unsigned &first_one_based_boundary_id_for_disk, unsigned &last_one_based_boundary_id_for_disk)
Definition: tetmesh_faceted_surfaces.h:377
Vector< double > Left_boundary_coordinate
Left boundary coordinate of i-th facet.
Definition: tetmesh_faceted_surfaces.h:696
Vector< unsigned > Boundary_id
ID of boundary the i-th facet is located on.
Definition: tetmesh_faceted_surfaces.h:702
unsigned Nfacet
Number of facets.
Definition: tetmesh_faceted_surfaces.h:690
TriangleMesh< TPoissonElement< 2, 2 > > * Tri_mesh_pt
Mesh used to facet-ise (discretise) disk.
Definition: tetmesh_faceted_surfaces.h:709
unsigned Nelement_on_disk_boundary
Number of elements on disk boundary.
Definition: tetmesh_faceted_surfaces.h:705
void boundary_zeta01(const unsigned &facet_id, const double &zeta_boundary, Vector< double > &zeta)
Definition: tetmesh_faceted_surfaces.h:659
TetMeshFacetedSurface that defines disk with torus around edge.
Definition: tetmesh_faceted_surfaces.h:732
DiskWithTorusAroundEdgeTetMeshFacetedSurface(DiskLikeGeomObjectWithBoundaries *disk_parametrised_by_nonsingular_coordinates_pt, const unsigned &half_nsegment, const double &r_torus, const unsigned &nvertex_torus, const unsigned &first_one_based_boundary_id_for_disk, const unsigned &one_based_torus_region_id, unsigned &last_one_based_boundary_id_for_disk, unsigned &first_one_based_boundary_id_for_torus, unsigned &last_one_based_boundary_id_for_torus, Vector< unsigned > &one_based_boundary_id_for_disk_within_torus, Vector< unsigned > &one_based_boundary_id_for_disk_outside_torus)
Definition: tetmesh_faceted_surfaces.h:757
Definition: tetmesh_faceted_surfaces.h:1067
DiskWithTwoLayersTetMeshFacetedSurface(DiskLikeGeomObjectWithBoundaries *disk_parametrised_by_nonsingular_coordinates_pt, const unsigned &half_nsegment, const unsigned &first_one_based_boundary_id_for_disk, const unsigned &one_based_region_id_above_disk, const unsigned &one_based_region_id_below_disk, unsigned &last_one_based_boundary_id_for_disk, unsigned &last_one_based_boundary_id)
Definition: tetmesh_faceted_surfaces.h:1086
Definition: elements.h:1313
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
Definition: geom_objects.h:101
virtual void position(const Vector< double > &zeta, Vector< double > &r) const =0
Parametrised position on object at current time: r(zeta).
Definition: nodes.h:906
virtual bool is_on_boundary() const
Definition: nodes.h:1373
void position(Vector< double > &pos) const
Definition: nodes.cc:2499
virtual void get_coordinates_on_boundary(const unsigned &b, const unsigned &k, Vector< double > &boundary_zeta)
Definition: nodes.cc:2379
Definition: oomph_definitions.h:222
RectangularTetMeshFacetedSurface from (+/- half x width) x +/- half y length.
Definition: tetmesh_faceted_surfaces.h:284
void build_it(const double &half_x_width, const double &half_y_length, const Vector< double > &offset, const unsigned &one_based_boundary_id)
Build the thing.
Definition: tetmesh_faceted_surfaces.h:308
RectangularTetMeshFacetedSurface(const double &half_x_width, const double &half_y_length, const Vector< double > &offset, const unsigned &one_based_boundary_id)
Definition: tetmesh_faceted_surfaces.h:292
Definition: tet_mesh.h:168
void set_vertex_pt(const unsigned &j, TetMeshVertex *vertex_pt)
Definition: tet_mesh.h:194
Definition: tet_mesh.h:538
void enable_faceted_volume_represents_hole_for_gmsh()
Declare closed surface to represent hole for gmsh.
Definition: tet_mesh.h:550
void set_region_for_tetgen(const unsigned &region_id, const Vector< double > &region_point)
Definition: tet_mesh.h:582
void set_hole_for_tetgen(const Vector< double > &hole_point)
Specify coordinate of hole for tetgen.
Definition: tet_mesh.h:575
Definition: tet_mesh.h:306
Vector< TetMeshVertex * > Vertex_pt
Vector pointers to vertices.
Definition: tet_mesh.h:483
DiskLikeGeomObjectWithBoundaries * Geom_object_with_boundaries_pt
GeomObject with boundaries associated with this surface.
Definition: tet_mesh.h:497
Vector< TetMeshFacet * > Facet_pt
Vector of pointers to facets.
Definition: tet_mesh.h:486
TetMeshVertex * vertex_pt(const unsigned &j) const
Pointer to j-th vertex.
Definition: tet_mesh.h:379
Definition: tet_mesh.h:50
Vector< double > zeta_in_geom_object() const
Definition: tet_mesh.h:118
Base class defining a closed curve for the Triangle mesh generation.
Definition: unstructured_two_d_mesh_geometry_base.h:1339
Definition: unstructured_two_d_mesh_geometry_base.h:662
Definition: triangle_mesh.template.h:94
Vector< TriangleMeshClosedCurve * > internal_closed_curve_pt() const
Helper function for getting the internal closed boundaries.
Definition: triangle_mesh.template.h:163
double element_area() const
Helper function for getting the element area.
Definition: triangle_mesh.template.h:189
void add_region_coordinates(const unsigned &i, Vector< double > &region_coordinates)
Helper function for getting the extra regions.
Definition: triangle_mesh.template.h:213
Definition: triangle_mesh.template.h:424
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
int * m
Definition: level2_cplx_impl.h:294
double theta
Definition: two_d_biharmonic.cc:236
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
EIGEN_STRONG_INLINE const Eigen::CwiseBinaryOp< Eigen::internal::scalar_zeta_op< typename DerivedX::Scalar >, const DerivedX, const DerivedQ > zeta(const Eigen::ArrayBase< DerivedX > &x, const Eigen::ArrayBase< DerivedQ > &q)
Definition: SpecialFunctionsArrayAPI.h:152
r
Definition: UniformPSDSelfTest.py:20
void normal(const Vector< double > &x, Vector< double > &normal)
Definition: free_surface_rotation.cc:65
bool less_than_based_on_double(std::pair< TetMeshVertex *, double > i, std::pair< TetMeshVertex *, double > j)
Less than comparison based on double.
Definition: tetmesh_faceted_surfaces.h:47
const double Pi
50 digits from maple
Definition: oomph_utilities.h:157
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
list x
Definition: plotDoE.py:28
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2