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)
93 std::ifstream infile(file_name.c_str(),std::ios_base::in);
101 infile.getline(dummy, 100);
105 infile.getline(dummy, 100);
109 infile.getline(dummy, 100);
110 infile.getline(dummy, 100);
116 while (dummy[0]!=
'T')
117 {infile.getline(dummy, 100);}
121 std::vector<unsigned> global_node(n_element*4);
124 for(
unsigned i=0;i<n_element;i++)
126 for(
unsigned j=0;j<4;j++)
128 infile>>global_node[k];
135 std::vector<double> x_node(n_node);
136 std::vector<double> y_node(n_node);
137 std::vector<double> z_node(n_node);
140 for(
unsigned i=0;i<n_node;i++)
148 std::vector<bool> done_for_fluid(n_node,
false);
149 std::vector<bool> done_for_solid(n_node,
false);
153 std::map<unsigned,unsigned> fluid_node_nmbr;
159 std::map<unsigned,unsigned> solid_inner_node_nmbr;
160 std::map<unsigned,unsigned> solid_outer_node_nmbr;
163 std::vector<unsigned> nfluid_face(4);
168 std::vector<unsigned> nsolid_linking_faces(3);
171 unsigned n_solid_node=0;
174 unsigned n_fluid_node=0;
178 std::map<unsigned, double> x_outer_node;
179 std::map<unsigned, double> y_outer_node;
180 std::map<unsigned, double> z_outer_node;
185 std::vector< std::vector<std::vector<unsigned> > >
186 fluid_faces(4, std::vector<std::vector<unsigned> >(nbound_cond,std::vector<unsigned>(3) ));
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) ));
198 unsigned element_nmbr;
202 for(
unsigned i=0;i<nbound_cond;i++)
204 infile>> element_nmbr ;
208 if(bound_id!=1 && bound_id!=2 && bound_id!=3 && bound_id!=4 )
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";
221 std::vector<unsigned> side_node(3);
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];
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];
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];
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];
253 std::cout <<
"unexpected side number in your '.xda' input file\n"
254 <<
"in create_fluid_and_solid_surface_mesh_from_fluid_xda_mesh";
261 std::vector<double> normal(3,0.);
264 double x1=x_node[side_node[0] ];
265 double x2=x_node[side_node[1] ];
266 double x3=x_node[side_node[2] ];
268 double y1=y_node[side_node[0] ];
269 double y2=y_node[side_node[1] ];
270 double y3=y_node[side_node[2] ];
272 double z1=z_node[side_node[0] ];
273 double z2=z_node[side_node[1] ];
274 double z3=z_node[side_node[2] ];
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);
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++)
286 normal[idim]*=normal_sign/length;
290 for(
unsigned ii=0; ii<3; ii++)
293 unsigned inod=side_node[ii];
295 if(!done_for_fluid[inod])
297 done_for_fluid[inod]=
true;
302 if(!done_for_solid[inod])
304 done_for_solid[inod]=
true;
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];
321 for(
unsigned ii=0;ii<3; ii++)
323 fluid_faces[0][nfluid_face[0]-1][ii]=side_node[ii];
330 for(
unsigned ii=0; ii<3; ii++)
333 unsigned inod=side_node[ii];
335 if(!done_for_fluid[inod])
337 done_for_fluid[inod]=
true;
344 nfluid_face[bound_id-1]++;
347 for(
unsigned ii=0;ii<3; ii++)
349 fluid_faces[bound_id-1][nfluid_face[bound_id-1]-1][ii]=side_node[ii];
357 for(
unsigned i=0; i<4; i++)
359 fluid_faces[i].resize(nfluid_face[i]);
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';
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';
389 fluid_output_stream <<
'\n' <<
"# Node list : " <<
'\n';
391 fluid_output_stream << n_fluid_node <<
' ' << 3 <<
' ' << 0
392 <<
' ' << 1 <<
'\n'<<
'\n';
394 std::vector<bool> done_fluid_node(n_node,
false);
398 for(
unsigned i=0; i<4; i++)
401 unsigned nface=nfluid_face[i];
403 for(
unsigned iface=0; iface<nface; iface++)
406 std::vector<unsigned>* face_node=&(fluid_faces[i][iface]);
408 for(
unsigned ii=0; ii<3; ii++)
411 unsigned inod=(*face_node)[ii];
412 if(!done_fluid_node[inod])
414 done_fluid_node[inod]=
true;
418 fluid_node_nmbr[inod]=counter;
421 fluid_output_stream << counter <<
' '
422 << x_node[inod] <<
' '
423 << y_node[inod] <<
' '
424 << z_node[inod] <<
' '
434 solid_output_stream <<
'\n' <<
"# Node list : " <<
'\n';
436 solid_output_stream << n_solid_node <<
' ' << 3 <<
' ' << 0
437 <<
' ' << 1 <<
'\n'<<
'\n';
438 std::vector<bool> done_solid_node(n_node,
false);
443 unsigned nface=nfluid_face[0];
446 for(
unsigned iface=0; iface<nface; iface++)
449 std::vector<unsigned>* face_node=&(fluid_faces[0][iface]);
451 for(
unsigned ii=0; ii<3; ii++)
454 unsigned inod=(*face_node)[ii];
455 if(!done_solid_node[inod])
457 done_solid_node[inod]=
true;
461 solid_inner_node_nmbr[inod]=counter;
463 solid_output_stream << counter <<
' '
464 << x_node[inod] <<
' '
465 << y_node[inod] <<
' '
466 << z_node[inod] <<
' '
473 solid_outer_node_nmbr[inod]=counter;
475 solid_output_stream << counter <<
' '
476 << x_outer_node[inod] <<
' '
477 << y_outer_node[inod] <<
' '
478 << z_outer_node[inod] <<
' '
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';
491 for(
unsigned i=0; i<4; i++)
493 fluid_output_stream <<
'\n'
494 <<
"#============================="
495 <<
"====================================="
496 <<
'\n'<<
"# Faces Originally on boundary "
498 <<
"# --------------------------------" <<
'\n';
501 unsigned nface=nfluid_face[i];
503 for(
unsigned iface=0; iface<nface; iface++)
506 fluid_output_stream <<
"# Face " << counter <<
'\n';
509 fluid_output_stream << 1 <<
' ' << 0 <<
' ' ;
513 if(do_multi_boundary_ids)
514 fluid_output_stream << counter <<
'\n';
516 fluid_output_stream << i+1 <<
'\n';
520 fluid_output_stream << 3 <<
' ' ;
523 std::vector<unsigned>* face_node=&(fluid_faces[i][iface]);
528 std::vector< unsigned> double_boundary_nod(3);
531 unsigned n_double_boundary_nodes=0;
534 for(
unsigned l=0; l<3;l++)
538 unsigned inod=(*face_node)[l];
541 fluid_output_stream <<fluid_node_nmbr[inod] <<
' ';
546 if(done_for_solid[inod])
548 double_boundary_nod[n_double_boundary_nodes]=inod;
549 n_double_boundary_nodes++;
557 if(n_double_boundary_nodes>1)
559 for(
unsigned idbn=0; idbn<n_double_boundary_nodes-1; idbn++)
562 for(
unsigned j=0; j<2; j++)
566 for(
unsigned l=j+idbn; l<2+idbn; l++)
570 solid_linking_faces[i-1][nsolid_linking_faces[i-1]][index]=
571 solid_inner_node_nmbr[double_boundary_nod[l]];
574 for(
unsigned l=idbn; l<idbn+j+1; l++)
578 solid_linking_faces[i-1][nsolid_linking_faces[i-1]][index]=
579 solid_outer_node_nmbr[double_boundary_nod[l]];
582 nsolid_linking_faces[i-1]++;
586 fluid_output_stream <<
'\n'<<
'\n';
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';
600 for(
unsigned i=0; i<5; i++)
602 solid_output_stream <<
'\n'
603 <<
"#====================================="
604 <<
"============================="
605 <<
'\n'<<
"# Faces Originally on boundary "
607 <<
"# --------------------------------" <<
'\n';
610 if(i==0 || i==4) nface=nfluid_face[0];
611 else nface=nsolid_linking_faces[i-1];
613 for(
unsigned iface=0; iface<nface; iface++)
616 std::vector<unsigned>* face_node;
617 if(i==0 || i==4) face_node=&(fluid_faces[0][iface]);
619 else face_node=&(solid_linking_faces[i-1][iface]);
622 solid_output_stream <<
"# Face " << counter <<
'\n';
625 solid_output_stream << 1 <<
' ' << 0 <<
' ' ;
629 if(do_multi_boundary_ids)
630 solid_output_stream << counter <<
'\n';
632 solid_output_stream << i+1 <<
'\n';
635 solid_output_stream << 3 <<
' ' ;
638 for(
unsigned l=0; l<3;l++)
641 unsigned inod=(*face_node)[l];
646 solid_output_stream << solid_inner_node_nmbr[inod] <<
' ';
651 solid_output_stream << solid_outer_node_nmbr[inod] <<
' ';
656 solid_output_stream <<inod <<
' ';
660 solid_output_stream <<
'\n'<<
'\n';
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';
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';
684 fluid_output_stream <<
'\n'<<
'\n'<<
'\n'
685 <<
"# The new boundary ids are as follow:"<<
'\n' <<
'\n';
687 for(
unsigned i=0; i<4; i++)
689 fluid_output_stream <<
"# Boundary "<< i+1
690 <<
" : from boundary id " ;
693 for(
unsigned j=0; j<i; j++)
698 fluid_output_stream <<
id <<
" until boundary id "
699 <<
id+nfluid_face[i]-1 <<
'\n';
701 fluid_output_stream.close();
707 solid_output_stream <<
'\n'<<
'\n'<<
'\n'
708 <<
"# The new boundary ids are as follow:"<<
'\n' <<
'\n';
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";
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";
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" ;
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";
734 solid_output_stream <<
"# the outer surface : from boundary id "
735 <<
id+1 <<
" until boundary id " ;
737 solid_output_stream <<
id <<
"\n";
739 solid_output_stream.close();
746 bool do_multi_boundary_ids=
true;
748 char multi_boundary_ids_marker;
751 std::string input_filename;
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 ";
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;
762 if(multi_boundary_ids_marker==
'n') do_multi_boundary_ids=
false;
764 char xda_filename[100];
765 char fluid_filename[100];
766 char solid_filename[100];
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());
773 xda_filename, fluid_filename, solid_filename, d,do_multi_boundary_ids);
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.