create_fluid_and_solid_surface_mesh_from_fluid_xda_mesh.cc
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-2023 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 /// This driver code takes as input the mesh generated by VMTK in '.xda' format
28 /// and the wall thickness. The outputs are the fluid and solid domain surfaces
29 /// ============================================================================
30 /**
31  the original Boundary Ids assigned by VMTK:
32  Boundary 3
33  ______
34  / /
35  / /
36  / /
37  ----------------/ /
38  | /
39  Boundary 2 | /
40  | \
41  | \
42  ----------------\ \
43  Boundary 1 \ \
44  \ \
45  \_____\
46  Boundary 4
47 
48  In this code, we kept the same boundary numbers for the fluid surface.
49  The boundary numbers for the Solid mesh are as follow :
50 
51  Boundary 3
52  __ __
53  / / / /
54  Boundary 5 / / / /
55  |---------------/ / / /
56  Boundary 2 |----------------/ / /
57  / /
58  / /
59  \ \ .
60  Boundary 1 \ \
61  |----------------\ \ \
62  |---------------\ \ \ \
63  \ \ \ \
64  \ \ \ \
65  -- --
66  Boundary 4
67 
68  Then we assigned to each face in the fluid mesh and in the solid mesh
69  its own boubdary ID if the input bool do_multi_boundary_ids is true
70  (because some functions in oomph-lib require that all faces with the
71  same boundary ID should be planar). Find the boundary IDs informations
72  in the end of the output '.poly' files.
73 **/
74 //=============================================================================
75 //#include "generic.h"
76 //using namespace oomph;
77 
78 #include<iostream>
79 #include<string>
80 #include<fstream>
81 #include<vector>
82 #include<map>
83 #include<cmath>
84 #include<cstdlib>
85 
87  const std::string& file_name,
88  const std::string& fluid_surface_file,
89  const std::string& solid_surface_file,
90  const double& wall_tickness,
91  const bool& do_multi_boundary_ids=true)
92 {
93  std::ifstream infile(file_name.c_str(),std::ios_base::in);
94  unsigned n_node;
95  unsigned n_element;
96  unsigned nbound_cond;
97 
98  // Dummy storage to jump lines
99  char dummy[100];
100 
101  infile.getline(dummy, 100);
102 
103  // get number of elements
104  infile>>n_element;
105  infile.getline(dummy, 100);
106 
107  // get number of nodes
108  infile>>n_node;
109  infile.getline(dummy, 100);
110  infile.getline(dummy, 100);
111 
112  // get number of boundaries
113  infile>>nbound_cond;
114 
115  // jump to the first line storing element's informations
116  while (dummy[0]!= 'T')
117  {infile.getline(dummy, 100);}
118 
119 
120  // storage for the global node numbers listed element-by-element
121  std::vector<unsigned> global_node(n_element*4);
122 
123  unsigned k=0;
124  for(unsigned i=0;i<n_element;i++)
125  {
126  for(unsigned j=0;j<4;j++)
127  {
128  infile>>global_node[k];
129  k++;
130  }
131  }
132 
133 
134  // Create storage for coordinates
135  std::vector<double> x_node(n_node);
136  std::vector<double> y_node(n_node);
137  std::vector<double> z_node(n_node);
138 
139  // get nodes coordinates
140  for(unsigned i=0;i<n_node;i++)
141  {
142  infile>>x_node[i];
143  infile>>y_node[i];
144  infile>>z_node[i];
145  }
146 
147  // vector of bools, will tell us if we already visited a node
148  std::vector<bool> done_for_fluid(n_node,false);
149  std::vector<bool> done_for_solid(n_node,false);
150 
151  // A map, indexed by the old node number, gives the new node number
152  // in the fluid poly file
153  std::map<unsigned,unsigned> fluid_node_nmbr;
154 
155  // each node in the fluid surface gives birth to two nodes in the solid
156  // surface, one in the inner surface and the other in the outer surface.
157  // these maps, indexed by the old node number, give the new node number
158  // in the solid poly file
159  std::map<unsigned,unsigned> solid_inner_node_nmbr;
160  std::map<unsigned,unsigned> solid_outer_node_nmbr;
161 
162  // nfluid_face[i] will store the number of faces on boundary i+1
163  std::vector<unsigned> nfluid_face(4);
164 
165  // nsolid_linking_faces[i] will store the number of faces on boundary i+2
166  // NB: we don't store the number of faces in boundaries 1 and 5 because
167  // they are the same as the number of fluid faces on boundary 1
168  std::vector<unsigned> nsolid_linking_faces(3);
169 
170  // number of nodes in the solid surface
171  unsigned n_solid_node=0;
172 
173  // number of nodes in the fluid surface
174  unsigned n_fluid_node=0;
175 
176  // Create storage for outer solid nodes coordinates. Indexed by the old
177  // node number, these maps returns the nodes coordinates.
178  std::map<unsigned, double> x_outer_node;
179  std::map<unsigned, double> y_outer_node;
180  std::map<unsigned, double> z_outer_node;
181 
182  // Create storage for fluid faces informations :
183  // fluid_faces[i][j] will store a vector containing the three node numbers
184  // of the j-th face in the (i+1)-th boundary
185  std::vector< std::vector<std::vector<unsigned> > >
186  fluid_faces(4, std::vector<std::vector<unsigned> >(nbound_cond,std::vector<unsigned>(3) ));
187 
188  // Create storage for solid faces informations :
189  // As the solid inner and outer faces come from the fluid surface,
190  // we only need to store solid face informations in boundary 2,3 and 4.
191  // solid_faces[i][j] will store a vector containing the three node numbers
192  // of the j-th face in the (i+2)-th boundary
193  std::vector< std::vector<std::vector<unsigned> > >
194  solid_linking_faces(3, std::vector<std::vector<unsigned> >(nbound_cond,
195  std::vector<unsigned>(3) ));
196 
197  // Create storage for boundary informations
198  unsigned element_nmbr;
199  unsigned side_nmbr;
200  int bound_id;
201 
202  for(unsigned i=0;i<nbound_cond;i++)
203  {
204  infile>> element_nmbr ;
205  infile>> side_nmbr ;
206  infile>> bound_id ;
207 
208  if(bound_id!=1 && bound_id!=2 && bound_id!=3 && bound_id!=4 )
209  {
210  std::cout << "This function only takes xda type meshes with"
211  << "one inflow(boundary 2) and two outflow(boundary 3"
212  << "and 4), the countours must have the id 1. You have"
213  << "in your input file a boundary id : " << bound_id <<".\n"
214  << "Don't panic, there are only few things to change"
215  << "in this well commented code, good luck ;) \n";
216  abort();
217  }
218 
219  // get the side nodes numbers and normal_sign following the side numbering
220  // conventions in '.xda' mesh files.
221  std::vector<unsigned> side_node(3);
222  int normal_sign=1;
223 
224  switch(side_nmbr)
225  {
226  case 0:
227  side_node[0]=global_node[4*element_nmbr];
228  side_node[1]=global_node[4*element_nmbr+1];
229  side_node[2]=global_node[4*element_nmbr+2];
230  normal_sign=-1;
231  break;
232 
233  case 1:
234  side_node[0]=global_node[4*element_nmbr];
235  side_node[1]=global_node[4*element_nmbr+1];
236  side_node[2]=global_node[4*element_nmbr+3];
237  break;
238 
239  case 2:
240  side_node[0]=global_node[4*element_nmbr+1];
241  side_node[1]=global_node[4*element_nmbr+2];
242  side_node[2]=global_node[4*element_nmbr+3];
243  break;
244 
245  case 3:
246  side_node[0]=global_node[4*element_nmbr];
247  side_node[1]=global_node[4*element_nmbr+2];
248  side_node[2]=global_node[4*element_nmbr+3];
249  normal_sign=-1;
250  break;
251 
252  default :
253  std::cout << "unexpected side number in your '.xda' input file\n"
254  <<"in create_fluid_and_solid_surface_mesh_from_fluid_xda_mesh";
255  abort();
256  }
257 
258  if(bound_id==1)
259  {
260  // Create storage for the normal vector to the face
261  std::vector<double> normal(3,0.);
262 
263  // get the node's coordinates
264  double x1=x_node[side_node[0] ];
265  double x2=x_node[side_node[1] ];
266  double x3=x_node[side_node[2] ];
267 
268  double y1=y_node[side_node[0] ];
269  double y2=y_node[side_node[1] ];
270  double y3=y_node[side_node[2] ];
271 
272  double z1=z_node[side_node[0] ];
273  double z2=z_node[side_node[1] ];
274  double z3=z_node[side_node[2] ];
275 
276  // compute a normal vector
277  normal[0] =(y2-y1)*(z3-z1) - (z2-z1)*(y3-y1);
278  normal[1] =(z2-z1)*(x3-x1) - (x2-x1)*(z3-z1);
279  normal[2] =(x2-x1)*(y3-y1) - (y2-y1)*(x3-x1);
280 
281  // adjust the vector in order to have an external normal vector
282  double length= sqrt((normal[0])*(normal[0]) + (normal[1])*(normal[1])
283  + (normal[2])*(normal[2]));
284  for(unsigned idim=0; idim<3; idim++)
285  {
286  normal[idim]*=normal_sign/length;
287  }
288 
289  // loop over the face's nodes
290  for(unsigned ii=0; ii<3; ii++)
291  {
292  // get the node number
293  unsigned inod=side_node[ii];
294 
295  if(!done_for_fluid[inod])
296  {
297  done_for_fluid[inod]=true;
298 
299  // this node is a fluid node
300  n_fluid_node++;
301  }
302  if(!done_for_solid[inod])
303  {
304  done_for_solid[inod]=true;
305 
306  // this node is a solid node on boundary 1 and this node
307  // creates an other one on boundary 5
308  n_solid_node+=2;
309 
310  // compute the coordinates of the new node (on boundary 5)
311  x_outer_node[inod]= x_node[inod]+ wall_tickness* normal[0];
312  y_outer_node[inod]= y_node[inod]+ wall_tickness* normal[1];
313  z_outer_node[inod]= z_node[inod]+ wall_tickness* normal[2];
314  }
315  }
316 
317  // this is a fluid face on boundary 1
318  nfluid_face[0]++;
319 
320  // store the face node numbers
321  for(unsigned ii=0;ii<3; ii++)
322  {
323  fluid_faces[0][nfluid_face[0]-1][ii]=side_node[ii];
324  }
325  }
326  // if we are on boundary 2,3 or 4
327  else
328  {
329  // loop over the face's nodes
330  for(unsigned ii=0; ii<3; ii++)
331  {
332  // get the node number
333  unsigned inod=side_node[ii];
334 
335  if(!done_for_fluid[inod])
336  {
337  done_for_fluid[inod]=true;
338 
339  // this node is a fluid node
340  n_fluid_node++;
341  }
342  }
343  // this is a fluid face on boundary bound_id
344  nfluid_face[bound_id-1]++;
345 
346  // store the face node numbers
347  for(unsigned ii=0;ii<3; ii++)
348  {
349  fluid_faces[bound_id-1][nfluid_face[bound_id-1]-1][ii]=side_node[ii];
350  }
351  }
352  }
353  infile.close();
354 
355 
356  // resize :
357  for(unsigned i=0; i<4; i++)
358  {
359  fluid_faces[i].resize(nfluid_face[i]);
360  }
361 
362  //-------------------------------------------------------------------
363  // write some comments in the beginning of the fluid and solid sufaces
364  //-------------------------------------------------------------------
365  std::ofstream fluid_output_stream(fluid_surface_file.c_str(),std::ios::out);
366  fluid_output_stream << "# this poly file is the extraction of"
367  <<" the fluid surface from the VMTK mesh ." << '\n'
368  << "# VMTK assigns for the front inflow "
369  <<"face the boundary id 2, for the left " << '\n'
370  <<"# bifurcation face the id 3, for the right"
371  <<" bifurcation face the id 4 and for the other"
372  <<" boundaries the id 1 " << '\n'
373  << "# Oomph-lib's meshes need for each planar face "
374  <<"it's own id, so we assign new boundary ids."<< '\n'
375  <<"# Find in the end of this poly file the information"
376  <<" of the new boundary ids :" << '\n';
377 
378  std::ofstream solid_output_stream(solid_surface_file.c_str(),std::ios::out);
379  solid_output_stream << "# this poly file is the solid PLC extracted from"
380  <<" the fluid VMTK mesh." << '\n'
381  << "# Oomph-lib's meshes need for each planar face "
382  <<"it's own id, so we assign new boundary ids."<< '\n'
383  <<"# Find in the end of this poly file the information "
384  <<"of the new boundary ids :" << '\n';
385 
386  //------------------------------------------
387  // write the node list of the fluid surface
388  //------------------------------------------
389  fluid_output_stream << '\n' << "# Node list : " << '\n';
390  // write the node number(dimension =3 , no attributes, with boundary markers)
391  fluid_output_stream << n_fluid_node << ' ' << 3 << ' ' << 0
392  << ' ' << 1 << '\n'<< '\n';
393 
394  std::vector<bool> done_fluid_node(n_node,false);
395  unsigned counter=0;
396 
397  // loop over the boundaries
398  for(unsigned i=0; i<4; i++)
399  {
400  // how many faces are on boundary 'i+1' ?
401  unsigned nface=nfluid_face[i];
402  // loop over the faces
403  for(unsigned iface=0; iface<nface; iface++)
404  {
405  // get pointer to the vector storing the three nodes
406  std::vector<unsigned>* face_node=&(fluid_faces[i][iface]);
407  // loop over the face's nodes
408  for(unsigned ii=0; ii<3; ii++)
409  {
410  // get the node number (in the old numbering scheme)
411  unsigned inod=(*face_node)[ii];
412  if(!done_fluid_node[inod])
413  {
414  done_fluid_node[inod]=true;
415  counter++;
416 
417  // assign the new node number in the fluid surface
418  fluid_node_nmbr[inod]=counter;
419 
420  // write the node coordinates (boundary marker =0 )
421  fluid_output_stream << counter << ' '
422  << x_node[inod] << ' '
423  << y_node[inod] << ' '
424  << z_node[inod] << ' '
425  << 0 << '\n';
426  }
427  }
428  }
429  }
430 
431  //------------------------------------------
432  // write the node list of the solid surface
433  //------------------------------------------
434  solid_output_stream << '\n' << "# Node list : " << '\n';
435  // write the node number(dimension =3 , no attributes, with boundary markers)
436  solid_output_stream << n_solid_node << ' ' << 3 << ' ' << 0
437  << ' ' << 1 << '\n'<< '\n';
438  std::vector<bool> done_solid_node(n_node,false);
439 
440  counter=0;
441 
442  // how many faces are on boundary 0
443  unsigned nface=nfluid_face[0];
444 
445  // loop over the faces
446  for(unsigned iface=0; iface<nface; iface++)
447  {
448  // get pointer to the vector storing the three nodes
449  std::vector<unsigned>* face_node=&(fluid_faces[0][iface]);
450  // loop over the face's nodes
451  for(unsigned ii=0; ii<3; ii++)
452  {
453  // get the node number (in the old numbering scheme)
454  unsigned inod=(*face_node)[ii];
455  if(!done_solid_node[inod])
456  {
457  done_solid_node[inod]=true;
458  counter++;
459 
460  // assign the new node number in the solid surface
461  solid_inner_node_nmbr[inod]=counter;
462 
463  solid_output_stream << counter << ' '
464  << x_node[inod] << ' '
465  << y_node[inod] << ' '
466  << z_node[inod] << ' '
467  << 0 << '\n';
468 
469  // store the new nodes on boundary 5
470  counter++;
471 
472  // assign the new node number in the solid surface
473  solid_outer_node_nmbr[inod]=counter;
474 
475  solid_output_stream << counter << ' '
476  << x_outer_node[inod] << ' '
477  << y_outer_node[inod] << ' '
478  << z_outer_node[inod] << ' '
479  << 0 << '\n';
480  }
481  }
482  }
483 
484  //-----------------------------------------
485  // write the face list of the fluid surface
486  //-----------------------------------------
487  fluid_output_stream << '\n' << "# Face list : " << '\n';
488  fluid_output_stream << nfluid_face[0]+nfluid_face[1]+nfluid_face[2]
489  +nfluid_face[3] << ' ' << 1 << '\n'<< '\n';
490  counter=0;
491  for(unsigned i=0; i<4; i++)
492  {
493  fluid_output_stream <<'\n'
494  << "#============================="
495  <<"====================================="
496  << '\n'<<"# Faces Originally on boundary "
497  << i+1 << '\n'
498  <<"# --------------------------------" << '\n';
499 
500  // how many faces are on boundary 'i+1' ?
501  unsigned nface=nfluid_face[i];
502  // loop over the all faces
503  for(unsigned iface=0; iface<nface; iface++)
504  {
505  counter++;
506  fluid_output_stream <<"# Face " << counter << '\n';
507 
508  // one polygon, zero holes
509  fluid_output_stream << 1 << ' ' << 0 << ' ' ;
510 
511  // If we want for each planar face its own ID, the boundary ID is
512  // counter, otherwise, the boundary ID is i+1
513  if(do_multi_boundary_ids)
514  fluid_output_stream << counter << '\n';
515  else
516  fluid_output_stream << i+1 << '\n';
517 
518 
519  // We have three vertices
520  fluid_output_stream << 3 << ' ' ;
521 
522  // get pointer to the vector storing the three nodes
523  std::vector<unsigned>* face_node=&(fluid_faces[i][iface]);
524 
525  // This vector will store the nodes that are in both boundaries 1 and
526  // another one (2,3 or 4). We only store this nodes if we have in the
527  // face two or more double boundary nodes.
528  std::vector< unsigned> double_boundary_nod(3);
529 
530  // storage for the size of double_boundary_nod;
531  unsigned n_double_boundary_nodes=0;
532 
533  // loop over the three nodes
534  for(unsigned l=0; l<3;l++)
535  {
536 
537  // get the old node number
538  unsigned inod=(*face_node)[l];
539 
540  // Write the vertices indices
541  fluid_output_stream <<fluid_node_nmbr[inod] << ' ';
542 
543  // find out how many nodes are double boundary nodes
544  if(i!=0)
545  {
546  if(done_for_solid[inod])
547  {
548  double_boundary_nod[n_double_boundary_nodes]=inod;
549  n_double_boundary_nodes++;
550  }
551  }
552  }
553 
554  // if we have more than one double boundary node
555  // create faces linking the solid faces on
556  // boundary 1 and the solid faces on boundary 5
557  if(n_double_boundary_nodes>1)
558  {
559  for(unsigned idbn=0; idbn<n_double_boundary_nodes-1; idbn++)
560  {
561  // each two double boundary nodes create two faces
562  for(unsigned j=0; j<2; j++)
563  {
564  unsigned index=0;
565 
566  for(unsigned l=j+idbn; l<2+idbn; l++)
567  {
568  // *[i-1] because *[k] stores informations for the
569  // (k+2)-th boundary
570  solid_linking_faces[i-1][nsolid_linking_faces[i-1]][index]=
571  solid_inner_node_nmbr[double_boundary_nod[l]];
572  index++;
573  }
574  for(unsigned l=idbn; l<idbn+j+1; l++)
575  {
576  // *[i-1] because *[k] stores informations for the
577  // (k+2)-th boundary
578  solid_linking_faces[i-1][nsolid_linking_faces[i-1]][index]=
579  solid_outer_node_nmbr[double_boundary_nod[l]];
580  index++;
581  }
582  nsolid_linking_faces[i-1]++;
583  }
584  }
585  }
586  fluid_output_stream << '\n'<< '\n';
587  }
588  }
589 
590 
591  //-----------------------------------------
592  // write the face list of the solid surface
593  //-----------------------------------------
594  solid_output_stream << '\n' << "# Face list : " << '\n';
595  solid_output_stream << 2*nfluid_face[0]+ nsolid_linking_faces[0]
596  + nsolid_linking_faces[1]+ nsolid_linking_faces[2]
597  << ' ' << 1 << '\n'<< '\n';
598 
599  counter=0;
600  for(unsigned i=0; i<5; i++)
601  {
602  solid_output_stream <<'\n'
603  << "#====================================="
604  <<"============================="
605  << '\n'<<"# Faces Originally on boundary "
606  <<i+1 << '\n'
607  <<"# --------------------------------" << '\n';
608  // get the number of faces
609  unsigned nface;
610  if(i==0 || i==4) nface=nfluid_face[0];
611  else nface=nsolid_linking_faces[i-1];
612 
613  for(unsigned iface=0; iface<nface; iface++)
614  {
615  // get pointer to the vector storing the three nodes
616  std::vector<unsigned>* face_node;
617  if(i==0 || i==4) face_node=&(fluid_faces[0][iface]);
618  // *[i-1] because *[k] stores informations for the (k+2)-th boundary
619  else face_node=&(solid_linking_faces[i-1][iface]);
620 
621  counter++;
622  solid_output_stream <<"# Face " << counter << '\n';
623 
624  // one polygon, zero holes, boundary counter
625  solid_output_stream << 1 << ' ' << 0 << ' ' ;
626 
627  // If we want for each planar face its own ID, the boundary ID is
628  // counter, otherwise, the boundary ID is i+1
629  if(do_multi_boundary_ids)
630  solid_output_stream << counter << '\n';
631  else
632  solid_output_stream << i+1 << '\n';
633 
634  // three vertices and their indices in node list
635  solid_output_stream << 3 << ' ' ;
636 
637  // loop over the three nodes
638  for(unsigned l=0; l<3;l++)
639  {
640  // get the node number
641  unsigned inod=(*face_node)[l];
642 
643  if(i==0)
644  {
645  // it's the old node number
646  solid_output_stream << solid_inner_node_nmbr[inod] << ' ';
647  }
648  else if(i==4)
649  {
650  // it's the old node number
651  solid_output_stream << solid_outer_node_nmbr[inod] << ' ';
652  }
653  else
654  {
655  // it's the new node number
656  solid_output_stream <<inod << ' ';
657  }
658 
659  }
660  solid_output_stream << '\n'<< '\n';
661  }
662  }
663 
664 
665  //----------------------------------------------------
666  // write the Hole and Region lists of the fluid
667  // and solid (empty)
668  //----------------------------------------------------
669  fluid_output_stream << '\n' << "# Hole list : " << '\n';
670  fluid_output_stream << 0 << '\n';
671  fluid_output_stream << '\n' << "# Region list : " << '\n';
672  fluid_output_stream << 0 << '\n';
673 
674  solid_output_stream << '\n' << "# Hole list : " << '\n';
675  solid_output_stream << 0 << '\n';
676  solid_output_stream << '\n' << "# Region list : " << '\n';
677  solid_output_stream << 0 << '\n';
678 
679 
680 
681  //------------------------------------------------------
682  // write the boundary informations for the fluid surface
683  //------------------------------------------------------
684  fluid_output_stream << '\n'<< '\n'<< '\n'
685  <<"# The new boundary ids are as follow:"<< '\n' << '\n';
686 
687  for(unsigned i=0; i<4; i++)
688  {
689  fluid_output_stream << "# Boundary "<< i+1
690  << " : from boundary id " ;
691  // get the first boundary id:
692  unsigned id=0;
693  for(unsigned j=0; j<i; j++)
694  {
695  id+=nfluid_face[j];
696  }
697 
698  fluid_output_stream << id << " until boundary id "
699  << id+nfluid_face[i]-1 << '\n';
700  }
701  fluid_output_stream.close();
702 
703 
704  //------------------------------------------------------
705  // write the boundary informations for the solid surface
706  //------------------------------------------------------
707  solid_output_stream << '\n'<< '\n'<< '\n'
708  <<"# The new boundary ids are as follow:"<< '\n' << '\n';
709 
710  solid_output_stream << "# the inner surface : from boundary id "
711  << 0 << " until boundary id ";
712  unsigned id=nfluid_face[0]-1;
713  solid_output_stream << id << "\n";
714 
715 
716  solid_output_stream << "# the front inflow face : from boundary id "
717  << id+1 << " until boundary id " ;
718  id+=nsolid_linking_faces[0];
719  solid_output_stream <<id<< "\n";
720 
721 
722  solid_output_stream << "# the left bifurcation face : from boundary id "
723  << id+1 << " until boundary id " ;
724  id+=nsolid_linking_faces[1];
725  solid_output_stream << id<< "\n" ;
726 
727 
728  solid_output_stream << "# the right bifurcation : from boundary id "
729  << id+1 << " until boundary id " ;
730  id+=nsolid_linking_faces[2];
731  solid_output_stream << id << "\n";
732 
733 
734  solid_output_stream << "# the outer surface : from boundary id "
735  << id+1 << " until boundary id " ;
736  id+=nfluid_face[0];
737  solid_output_stream << id << "\n";
738 
739  solid_output_stream.close();
740 }
741 
742 
743 
744 int main()
745 {
746  bool do_multi_boundary_ids=true;
747 
748  char multi_boundary_ids_marker;
749 
750  double d;
751  std::string input_filename;
752 
753  std::cout << "Please enter the file name without the file extension '.xda': ";
754  std::cin >> input_filename;
755  std::cout << "\n\nEnter the (uniform) wall thickness ";
756  std::cin >> d;
757  std::cout << "\n\nDo you want to create a separate ID for each planar facet\n"
758  << "on the fluid-structure interaction boundary?"
759  << "\n" <<"Enter y or n: ";
760  std::cin >> multi_boundary_ids_marker;
761 
762  if(multi_boundary_ids_marker=='n') do_multi_boundary_ids=false;
763 
764  char xda_filename[100];
765  char fluid_filename[100];
766  char solid_filename[100];
767 
768  sprintf(xda_filename,"%s.xda", input_filename.c_str());
769  sprintf(fluid_filename,"fluid_%s.poly", input_filename.c_str());
770  sprintf(solid_filename,"solid_%s.poly", input_filename.c_str());
771 
773  xda_filename, fluid_filename, solid_filename, d,do_multi_boundary_ids);
774 return 0;
775 }
void create_fluid_and_solid_surface_mesh_from_fluid_xda_mesh(const std::string &file_name, const std::string &fluid_surface_file, const std::string &solid_surface_file, const double &wall_tickness, const bool &do_multi_boundary_ids=true)
This driver code takes as input the mesh generated by VMTK in '.xda' format.