WaveBEM: Unsteady Nonlinear Potential Flow Solver for Ship-Wave Interaction.
numerical_towing_tank.cc
Go to the documentation of this file.
1 //---------------------------- step-34.cc ---------------------------
2 // $Id: step-34.cc 18734 2009-04-25 13:36:48Z heltai $
3 // Version: $Name$
4 //
5 // Copyright (C) 2009, 2010, 2011 by the deal.II authors
6 //
7 // This file is subject to QPL and may not be distributed
8 // without copyright and license information. Please refer
9 // to the file deal.II/doc/license.html for the text and
10 // further information on this license.
11 //
12 // Authors: Luca Heltai, Cataldo Manigrasso, Andrea Mola
13 //
14 //---------------------------- step-34.cc ---------------------------
15 
16 #define TOLL 0.001
17 #define MAXELEMENTSPERBLOCK 1
18 
19 #include "../include/numerical_towing_tank.h"
20 #include "../include/boat_surface.h"
23 #include <BRepAdaptor_Curve.hxx>
24 
25 using namespace dealii;
26 using namespace OpenCascade;
27 using namespace std;
28 
29 NumericalTowingTank::NumericalTowingTank(const unsigned int fe_degree,
30  const unsigned int mapping_degree) :
31  ComputationalDomain<3>(fe_degree, mapping_degree),
32  restart_surface_smoother(NULL),
33  surface_smoother(NULL),
34  line_smoothers(7,NULL),
35  mapping_degree(mapping_degree)
36 {}
37 
39 
40 {
41  std::cout<<"Performing full mesh treatment"<<std::endl;
42 
43 
45 
47 // for (unsigned int i=0; i<vector_dh.n_dofs(); ++i)
48 
49 //perform_surface_projection();
50  perform_smoothing(true,1);
52 
54 // writing boat/free surface nodes to a file
56 //std::ofstream myfile;
57 //myfile.open ("waterLine.txt",std::ios::trunc);
58 //for (std::set <unsigned int>::iterator pos = free_surf_and_boat_nodes.begin(); pos != free_surf_and_boat_nodes.end(); pos++)
59 // {
60 // myfile << support_points[*pos]<<" \n";
61 // }
62 //myfile.close();
63 
64  std::cout<<"done full mesh treatment"<<std::endl;
65 }
66 
67 void NumericalTowingTank::partial_mesh_treatment(const double blend_factor)
68 
69 {
70  std::cout<<"Performing partial mesh treatment"<<std::endl;
71 
72  if (line_smoothers.size() == 7)
75  perform_smoothing(false,blend_factor);
77 
78  std::cout<<"done partial mesh treatment"<<std::endl;
79 }
80 
81 void NumericalTowingTank::apply_curvatures(const Vector<double> &curvatures, const vector<bool> boundary_dofs)
82 
83 {
84  std::cout<<"Computing geometrically conforming mesh"<<std::endl;
85 
87 
88  restart_surface_smoother->apply_curvatures(curvatures,boundary_dofs);
89 
90  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
91  {
92  if ((flags[i] & water) == 0)
93  {
94  map_points(3*i) = smoothing_map_points(3*i);
95  map_points(3*i+1) = smoothing_map_points(3*i+1);
96  map_points(3*i+2) = smoothing_map_points(3*i+2);
97  }
98  }
99 
100 
101  std::cout<<"Done computing geometrically conforming mesh"<<std::endl;
102 }
103 
104 
106 {
107  for (unsigned int i=0; i<vector_dh.n_dofs(); ++i)
108  map_points(i) = new_disp(i);
109 }
110 
112 
113 {
114  std::cout<<"Computing curvatures for geometrically conforming mesh refinement"<<std::endl;
115 
117 
119 
120 
121  std::cout<<"Done computing curvatures for geometrically conforming mesh"<<std::endl;
122 }
123 
125 {
126  std::cout<<"Refining and resizing mesh as required"<<std::endl;
127 
130 
131  std::cout<<"Total number of dofs of first mesh: "<<dh.n_dofs()<<std::endl;
132 
138  ref_points.resize(vector_dh.n_dofs());
139  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
141 
144 
146 
148 
149 // anisotropic refinement
152 
153  Vector<double> positions(vector_dh.n_dofs());
154  std::vector< Point<3> > normals(vector_dh.n_dofs()/3);
155  Vector<float> estimated_error_per_cell(tria.n_active_cells());
156 
158  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
159  {
160  for (unsigned int j=0; j<3; ++j)
161  {
162  positions(3*i+j) = vector_support_points[3*i][j];
163  }
164  }
165 
166 
167  Point<3> projection;
168 
169  for (unsigned int k=0; k<init_adaptive_boat_refs; ++k)
170  {
171  std::cout<<"Adaptive refinement cycle "<<k+1<<" of "<<init_adaptive_boat_refs<<std::endl;
172  estimated_error_per_cell.reinit(tria.n_active_cells());
173  /*
174  QGauss<1> quad(2);
175 
176  KellyErrorEstimator<2,3>::estimate (vector_dh,
177  quad,
178  FunctionMap<3>::type(),
179  positions,
180  estimated_error_per_cell);
181 
182  */
183  QGauss<2> quad(1);
184 
185  FEValues<2,3> fe_v(*mapping, fe, quad,
186  update_values | update_cell_normal_vectors | update_quadrature_points |
187  update_JxW_values);
188 
189  const unsigned int n_q_points = fe_v.n_quadrature_points;
190  unsigned int cell_count = 0;
191  cell_it
192  cell = dh.begin_active(),
193  endc = dh.end();
194 
195  for (; cell!=endc; ++cell)
196  {
197  fe_v.reinit (cell);
198  const std::vector<Point<3> > &node_normals = fe_v.get_normal_vectors();
199  const std::vector<Point<3> > &quadrature_points = fe_v.get_quadrature_points();
200  if ((cell->material_id() == wall_sur_ID1 ||
201  cell->material_id() == wall_sur_ID2 ||
202  cell->material_id() == wall_sur_ID3 ) )
203  {
204  Point<3> proj_node;
205  if (quadrature_points[0](1) > 0) //right side
206  {
208  quadrature_points[0],
209  node_normals[0]); // for projection in mesh normal direction
210  //cout<<cell<<" center:"<<quadrature_points[0]<<" normal: " <<node_normals[0]<<endl;
211  //cout<<"Projection: "<<proj_node<<" distance: "<<proj_node.distance(quadrature_points[0])<<endl;
212  //cout<<endl;
213  estimated_error_per_cell(cell_count) = proj_node.distance(quadrature_points[0]);
214  }
215  else // left side
216  {
218  quadrature_points[0],
219  node_normals[0]); // for projection in mesh normal direction
220  //cout<<cell<<" center:"<<quadrature_points[0]<<" normal: " <<node_normals[0]<<endl;
221  //cout<<"Projection: "<<proj_node<<" distance: "<<proj_node.distance(quadrature_points[0])<<endl;
222  //cout<<endl;
223  estimated_error_per_cell(cell_count) = proj_node.distance(quadrature_points[0]);
224  }
225  }
226  ++cell_count;
227  }
228 
229 
231  estimated_error_per_cell,
233  0.0,
234  5000);
235 
238 
240  vector_dh.distribute_dofs(vector_fe);
241  map_points.reinit(vector_dh.n_dofs());
242  smoothing_map_points.reinit(vector_dh.n_dofs());
243  old_map_points.reinit(vector_dh.n_dofs());
244  rigid_motion_map_points.reinit(vector_dh.n_dofs());
245  initial_map_points.reinit(vector_dh.n_dofs());
246  ref_points.resize(vector_dh.n_dofs());
247  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
250  make_edges_conformal(true);
251  make_edges_conformal(true);
253 
255  positions.reinit(vector_dh.n_dofs());
256 
257  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
258  for (unsigned int j=0; j<3; ++j)
259  positions(3*i+j) = vector_support_points[3*i][j];
260  }
261 
263 
264 
265  min_diameter = 10000;
267  cell = tria.begin_active(), endc = tria.end();
268 
269  for ( ; cell != endc; ++cell)
270  {
271  if (cell->material_id() == free_sur_ID1 ||
272  cell->material_id() == free_sur_ID2 ||
273  cell->material_id() == free_sur_ID3 )
274  min_diameter = std::min(min_diameter,cell->diameter());
275  }
276  std::cout << "Min diameter: << " << min_diameter << std::endl;
277 
278 
279 
280 
281 
282  std::cout<<"Total number of dofs after whole refinement: "<<dh.n_dofs()<<std::endl;
283 
284  std::cout<<"...done refining and resizing mesh"<<std::endl;
285 
286 
287 
288 }
289 
291 {
292 
293  //tria.set_mesh_smoothing (Triangulation<2,3>::do_not_produce_unrefined_islands );
294  //coarse_tria.set_mesh_smoothing (Triangulation<2,3>::do_not_produce_unrefined_islands );
295  cout<<"Hey: "<<iges_file_name<<endl;
296  cout<<iges_file_name.compare("NO_BOAT")<<endl;
297  if (!iges_file_name.compare("NO_BOAT"))
298  //if (true)
299  {
300  no_boat = true;
301  line_smoothers.resize(0);
302  }
303  else
304  {
305  no_boat = false;
307  1.0/1000.0,
315  }
316 
317  //boat_model.start_iges_model(iges_file_name,1.0/1000.0,boat_displacement,assigned_sink,assigned_trim,0.068979, 0.075, .5); //con kcs.iges
318  //boat_model.start_iges_model(iges_file_name, 1.0/1000.0,boat_displacement,assigned_sink,assigned_trim,0.13, 0.05, .5); //con goteborg.iges
319  //boat_model.start_iges_model(iges_file_name, 1.0/1000.0,boat_displacement,assigned_sink,assigned_trim,0.13, .05, .47); //con goteborgLow.iges
320  //boat_model.start_iges_model(iges_file_name, 1.0/1000.0,boat_displacement,assigned_sink,assigned_trim,0.13, .075, .5); //con goteborgTransom.iges
321  //boat_model.start_iges_model(iges_file_name, 1.0/1000.0,boat_displacement,assigned_sink,assigned_trim,0.055556, 0.055556, .5); //con wigley.iges
322  //boat_model.start_iges_model(iges_file_name, 1.0/1000.0,boat_displacement,assigned_sink,assigned_trim,0.068979, 0.049807, .5); //con series_60.iges
323  //boat_model.start_iges_model(iges_file_name, 1.0/1000.0,boat_displacement,assigned_sink,assigned_trim,0.35, 0.2, .5); //con vela_enave.iges
324 
325  cout<<"FrontBot "<<boat_model.PointFrontBot<<endl;
326  cout<<"BackBot "<<boat_model.PointBackBot<<endl;
336  coarse_tria);
337 
338  tria.restore();
339 
340  /*
341  Triangulation<2,3>::active_cell_iterator
342  cell = tria.begin_active(), endc = tria.end();
343 
344  for (cell=tria.begin_active(); cell!= endc;++cell)
345  {
346  if ((cell->material_id() == free_sur_ID1 ||
347  cell->material_id() == free_sur_ID2 ||
348  cell->material_id() == free_sur_ID3 ))
349  {
350  if ( cell->at_boundary() )
351  for (unsigned int f = 0; f < GeometryInfo<2>::faces_per_cell;++f)
352  {
353  if (cell->face(f)->boundary_indicator()==0)
354  cell->face(f)->set_boundary_indicator(22);
355  }
356  }
357  }
358  */
359  if (!no_boat)
360  {
363  //tria.set_boundary(21, *boat_model.boat_surface_right);
364  tria.set_boundary(21, *boat_model.water_line_right); //tria.set_boundary(21, *boat_model.boat_water_line_right);
365  //tria.set_boundary(23, *boat_model.boat_surface_right);
366  tria.set_boundary(23, *boat_model.water_line_right);//tria.set_boundary(23, *boat_model.boat_water_line_right);
367  //tria.set_boundary(22, *boat_model.boat_surface_left);
368  tria.set_boundary(22, *boat_model.water_line_left);//tria.set_boundary(22, *boat_model.boat_water_line_left);
369  //tria.set_boundary(24, *boat_model.boat_surface_left);
370  tria.set_boundary(24, *boat_model.water_line_left);//tria.set_boundary(22, *boat_model.boat_water_line_left);
371  //tria.set_boundary(26, *boat_model.boat_surface_right);
372  tria.set_boundary(26, *boat_model.water_line_right);//tria.set_boundary(26, *boat_model.boat_water_line_right);
373  //tria.set_boundary(28, *boat_model.boat_surface_right);
374  tria.set_boundary(28, *boat_model.water_line_right);//tria.set_boundary(28, *boat_model.boat_water_line_right);
375  //tria.set_boundary(27, *boat_model.boat_surface_left);
376  tria.set_boundary(27, *boat_model.water_line_left);//tria.set_boundary(27, *boat_model.boat_water_line_left);
377  //tria.set_boundary(29, *boat_model.boat_surface_left);
378  tria.set_boundary(29, *boat_model.water_line_left);//tria.set_boundary(29, *boat_model.boat_water_line_left);
381  else
387  else
392  {
395  }
396 
399  //coarse_tria.set_boundary(21, *boat_model.boat_surface_right);
400  coarse_tria.set_boundary(21, *boat_model.water_line_right); //coarse_tria.set_boundary(21, *boat_model.boat_water_line_right);
401  //coarse_tria.set_boundary(23, *boat_model.boat_surface_right);
402  coarse_tria.set_boundary(23, *boat_model.water_line_right);//coarse_tria.set_boundary(23, *boat_model.boat_water_line_right);
403  //coarse_tria.set_boundary(22, *boat_model.boat_surface_left);
404  coarse_tria.set_boundary(22, *boat_model.water_line_left);//coarse_tria.set_boundary(22, *boat_model.boat_water_line_left);
405  //coarse_tria.set_boundary(24, *boat_model.boat_surface_left);
406  coarse_tria.set_boundary(24, *boat_model.water_line_left);//coarse_tria.set_boundary(22, *boat_model.boat_water_line_left);
407  //coarse_tria.set_boundary(26, *boat_model.boat_surface_right);
408  coarse_tria.set_boundary(26, *boat_model.water_line_right);//coarse_tria.set_boundary(26, *boat_model.boat_water_line_right);
409  //coarse_tria.set_boundary(28, *boat_model.boat_surface_right);
410  coarse_tria.set_boundary(28, *boat_model.water_line_right);//coarse_tria.set_boundary(28, *boat_model.boat_water_line_right);
411  //coarse_tria.set_boundary(27, *boat_model.boat_surface_left);
412  coarse_tria.set_boundary(27, *boat_model.water_line_left);//coarse_tria.set_boundary(27, *boat_model.boat_water_line_left);
413  //coarse_tria.set_boundary(29, *boat_model.boat_surface_left);
414  coarse_tria.set_boundary(29, *boat_model.water_line_left);//coarse_tria.set_boundary(29, *boat_model.boat_water_line_left);
417  else
423  else
428  {
431  }
432  }
433 }
434 
435 
437 {
438  for (unsigned int i=0; i<line_smoothers.size(); ++i)
439  delete line_smoothers[i];
440  if (surface_smoother)
441  delete surface_smoother;
442 
443  //tria.set_boundary(3);
444  //tria.set_boundary(4);
445  tria.set_boundary(21);
446  tria.set_boundary(23);
447  tria.set_boundary(22);
448  tria.set_boundary(24);
449  tria.set_boundary(26);
450  tria.set_boundary(28);
451  tria.set_boundary(27);
452  tria.set_boundary(29);
453  tria.set_boundary(32);
454  tria.set_boundary(31);
455  tria.set_boundary(30);
456  tria.set_boundary(37);
457  tria.set_boundary(36);
458  tria.set_boundary(35);
459  //coarse_tria.set_boundary(3);
460  //coarse_tria.set_boundary(4);
475 
476 
477 }
478 
479 
480 
481 
483 {
485 // parameters to set domain 2ensions with respect to boat length could
486 // be asked here to the user
487  prm.declare_entry("Iges file name", "NO_BOAT", Patterns::Anything());
488 
489  prm.declare_entry("Refinement level on boat", "0", Patterns::Integer());
490 
491  prm.declare_entry("Boat displacement (Kg)","0",Patterns::Double());
492 
493  prm.declare_entry("Assigned sink (m)","0",Patterns::Double());
494 
495  prm.declare_entry("Assigned trim (rad)","0",Patterns::Double());
496 
497  prm.declare_entry("Moment of intertia Ixx (Kg m^2)","1",Patterns::Double());
498 
499  prm.declare_entry("Moment of intertia Ixy (Kg m^2)","0",Patterns::Double());
500 
501  prm.declare_entry("Moment of intertia Ixz (Kg m^2)","0",Patterns::Double());
502 
503  prm.declare_entry("Moment of intertia Iyy (Kg m^2)","1",Patterns::Double());
504 
505  prm.declare_entry("Moment of intertia Iyz (Kg m^2)","0",Patterns::Double());
506 
507  prm.declare_entry("Moment of intertia Izz (Kg m^2)","1",Patterns::Double());
508 
509  prm.declare_entry("Max aspect ratio","1.5",Patterns::Double());
510 
511  prm.declare_entry("Front mesh inclination coeff","1.0",Patterns::Double());
512 
513  prm.declare_entry("Back mesh inclination coeff","1.0",Patterns::Double());
514 
515  prm.declare_entry("Back keel length","0.1",Patterns::Double());
516 
517  prm.declare_entry("Front keel length","0.05",Patterns::Double());
518 
519  prm.declare_entry("Middle keel length","0.5",Patterns::Double());
520 
521  prm.declare_entry("Number of boat initial uniform refinements", "2", Patterns::Integer());
522 
523  prm.declare_entry("Number of boat initial curvature based refinements", "0", Patterns::Integer());
524 
525  prm.declare_entry("Initial curvature based refinements fraction","0.2",Patterns::Double());
526 
527  prm.declare_entry("Number of transom edges", "1", Patterns::Integer());
528 }
529 
530 
532 {
534 // parameters to set domain dimensions with respect to boat length could
535 // be asked here to the user
536  n_cycles = prm.get_integer("Refinement level on boat");
537 
538  iges_file_name = prm.get("Iges file name");
539 
540  boat_displacement = prm.get_double("Boat displacement (Kg)");
541 
542  assigned_sink = prm.get_double("Assigned sink (m)");
543 
544  assigned_trim = prm.get_double("Assigned trim (rad)");
545 
546  Ixx = prm.get_double("Moment of intertia Ixx (Kg m^2)");
547 
548  Ixy = prm.get_double("Moment of intertia Ixy (Kg m^2)");
549 
550  Ixz = prm.get_double("Moment of intertia Ixz (Kg m^2)");
551 
552  Iyy = prm.get_double("Moment of intertia Iyy (Kg m^2)");
553 
554  Iyz = prm.get_double("Moment of intertia Iyz (Kg m^2)");
555 
556  Izz = prm.get_double("Moment of intertia Izz (Kg m^2)");
557 
558  max_aspect_ratio = prm.get_double("Max aspect ratio");
559 
560  front_mesh_inclination_coeff = prm.get_double("Front mesh inclination coeff");
561 
562  back_mesh_inclination_coeff = prm.get_double("Back mesh inclination coeff");
563 
564  back_keel_length = prm.get_double("Back keel length");
565 
566  front_keel_length = prm.get_double("Front keel length");
567 
568  middle_keel_length = prm.get_double("Middle keel length");
569 
570  init_global_boat_refs = prm.get_integer("Number of boat initial uniform refinements");
571 
572  init_adaptive_boat_refs = prm.get_integer("Number of boat initial curvature based refinements");
573 
574  init_adaptive_boat_refs_fraction = prm.get_double("Initial curvature based refinements fraction");
575 
576  number_of_transom_edges = prm.get_integer("Number of transom edges");
577 }
578 
579 
580 
581 
583  const Point<3> PointFrontBot,
584  const Point<3> PointMidTop,
585  const Point<3> PointMidBot,
586  const Point<3> PointBackTop,
587  const Point<3> PointBackBot,
588  const Point<3> PointLeftTransom,
589  const Point<3> PointRightTransom,
590  const Point<3> PointCenterTransom,
591  Triangulation<2,3> &triangulation)
592 {
593 
594 
595  std::vector<Point<3> > vertices;
596  std::vector<CellData<2> > cells;
597  SubCellData subcelldata;
598 
599  double a = front_mesh_inclination_coeff;
600  double b = back_mesh_inclination_coeff;
601 
602  if (no_boat)
603  {
604 
605  Lx_domain = 100.0;
606  Ly_domain = 5.5/4.0;
607  Lz_domain = 5.5;
608 
609  vertices.resize(24);
610  vertices[0](0)=-Lx_domain/2.0;
611  vertices[0](1)=-Ly_domain/2.0;
612  vertices[0](2)=0.0;
613  vertices[1](0)=-Lx_domain/2.0;
614  vertices[1](1)=Ly_domain/2.0;
615  vertices[1](2)=0.0;
616  vertices[2](0)=-Lx_domain/2.0;
617  vertices[2](1)=-Ly_domain/2.0;
618  vertices[2](2)=-Lz_domain;
619  vertices[3](0)=-Lx_domain/2.0;
620  vertices[3](1)=Ly_domain/2.0;
621  vertices[3](2)=-Lz_domain;
622  vertices[4](0)=-Lx_domain/2.0;
623  vertices[4](1)=Ly_domain/2.0;
624  vertices[4](2)=0.0;
625  vertices[5](0)=-Lx_domain/2.0;
626  vertices[5](1)=-Ly_domain/2.0;
627  vertices[5](2)=0.0;
628  vertices[6](0)=Lx_domain/2.0;
629  vertices[6](1)=-Ly_domain/2.0;
630  vertices[6](2)=0.0;
631  vertices[7](0)=Lx_domain/2.0;
632  vertices[7](1)=Ly_domain/2.0;
633  vertices[7](2)=0.0;
634  vertices[8](0)=-Lx_domain/2.0;
635  vertices[8](1)=Ly_domain/2.0;
636  vertices[8](2)=0.0;
637  vertices[9](0)=Lx_domain/2.0;
638  vertices[9](1)=Ly_domain/2.0;
639  vertices[9](2)=0.0;
640  vertices[10](0)=Lx_domain/2.0;
641  vertices[10](1)=Ly_domain/2.0;
642  vertices[10](2)=-Lz_domain;
643  vertices[11](0)=-Lx_domain/2.0;
644  vertices[11](1)=Ly_domain/2.0;
645  vertices[11](2)=-Lz_domain;
646  vertices[12](0)=-Lx_domain/2.0;
647  vertices[12](1)=-Ly_domain/2.0;
648  vertices[12](2)=0.0;
649  vertices[13](0)=-Lx_domain/2.0;
650  vertices[13](1)=-Ly_domain/2.0;
651  vertices[13](2)=-Lz_domain;
652  vertices[14](0)=Lx_domain/2.0;
653  vertices[14](1)=-Ly_domain/2.0;
654  vertices[14](2)=-Lz_domain;
655  vertices[15](0)=Lx_domain/2.0;
656  vertices[15](1)=-Ly_domain/2.0;
657  vertices[15](2)=0.0;
658  vertices[16](0)=-Lx_domain/2.0;
659  vertices[16](1)=-Ly_domain/2.0;
660  vertices[16](2)=-Lz_domain;
661  vertices[17](0)=-Lx_domain/2.0;
662  vertices[17](1)=Ly_domain/2.0;
663  vertices[17](2)=-Lz_domain;
664  vertices[18](0)=Lx_domain/2.0;
665  vertices[18](1)=Ly_domain/2.0;
666  vertices[18](2)=-Lz_domain;
667  vertices[19](0)=Lx_domain/2.0;
668  vertices[19](1)=-Ly_domain/2.0;
669  vertices[19](2)=-Lz_domain;
670  vertices[20](0)=Lx_domain/2.0;
671  vertices[20](1)=Ly_domain/2.0;
672  vertices[20](2)=0.0;
673  vertices[21](0)=Lx_domain/2.0;
674  vertices[21](1)=-Ly_domain/2.0;
675  vertices[21](2)=0.0;
676  vertices[22](0)=Lx_domain/2.0;
677  vertices[22](1)=-Ly_domain/2.0;
678  vertices[22](2)=-Lz_domain;
679  vertices[23](0)=Lx_domain/2.0;
680  vertices[23](1)=Ly_domain/2.0;
681  vertices[23](2)=-Lz_domain;
682 
683  cells.resize(6);
684 
685  cells[0].vertices[0]=0;
686  cells[0].vertices[1]=1;
687  cells[0].vertices[2]=3;
688  cells[0].vertices[3]=2;
689  cells[1].vertices[0]=4;
690  cells[1].vertices[1]=5;
691  cells[1].vertices[2]=6;
692  cells[1].vertices[3]=7;
693  cells[2].vertices[0]=8;
694  cells[2].vertices[1]=9;
695  cells[2].vertices[2]=10;
696  cells[2].vertices[3]=11;
697  cells[3].vertices[0]=12;
698  cells[3].vertices[1]=13;
699  cells[3].vertices[2]=14;
700  cells[3].vertices[3]=15;
701  cells[4].vertices[0]=16;
702  cells[4].vertices[1]=17;
703  cells[4].vertices[2]=18;
704  cells[4].vertices[3]=19;
705  cells[5].vertices[0]=20;
706  cells[5].vertices[1]=21;
707  cells[5].vertices[2]=22;
708  cells[5].vertices[3]=23;
709 
710  cells[0].material_id = 9; // inflow
711  cells[1].material_id = 5; // free surface
712  cells[2].material_id = 2; // side(+)
713  cells[3].material_id = 1; // side(-)
714  cells[4].material_id = 7; // bottom
715  cells[5].material_id = 11; // outflow
716 //*/
717  }
718  else
719  {
721  {
722 
723 
725  Lx_domain = Lx_boat*12.0;
726  Ly_domain = Lx_boat*4.0;
727  Lz_domain = Lx_boat*2.0;
728 
729  vertices.resize(88);
730 
731  vertices[0](0)=-Lx_domain/2;
732  vertices[0](1)=-Ly_domain/2 ;
733  vertices[0](2)=0;
734  vertices[1](0)=-Lx_domain/2;
735  vertices[1](1)=-Ly_domain/2;
736  vertices[1](2)=-Lz_domain;
737  vertices[2](0)=Lx_domain/2;
738  vertices[2](1)=-Ly_domain/2;
739  vertices[2](2)=-Lz_domain;
740  vertices[3](0)=Lx_domain/2;
741  vertices[3](1)=-Ly_domain/2;
742  vertices[3](2)=0;
743  vertices[4](0)=b*PointLeftTransom(0);
744  vertices[4](1)=-Ly_domain/2;
745  vertices[4](2)=0;
746  vertices[5](0)=a*PointFrontTop(0);
747  vertices[5](1)=-Ly_domain/2;
748  vertices[5](2)=0;
749  vertices[6](0)=b*PointLeftTransom(0);
750  vertices[6](1)=-Ly_domain/2;
751  vertices[6](2)=-Lz_domain;
752  vertices[7](0)=0;
753  vertices[7](1)=-Ly_domain/2;
754  vertices[7](2)=-Lz_domain;
755  vertices[8](0)=a*PointFrontTop(0);
756  vertices[8](1)=-Ly_domain/2;
757  vertices[8](2)=-Lz_domain;
758  vertices[9](0)=0;
759  vertices[9](1)=-Ly_domain/2;
760  vertices[9](2)=0;
761  vertices[10](0)=Lx_domain/2;
762  vertices[10](1)=Ly_domain/2;
763  vertices[10](2)=0;
764  vertices[11](0)=Lx_domain/2;
765  vertices[11](1)=Ly_domain/2;
766  vertices[11](2)=-Lz_domain;
767  vertices[12](0)=-Lx_domain/2;
768  vertices[12](1)=Ly_domain/2;
769  vertices[12](2)=-Lz_domain;
770  vertices[13](0)=-Lx_domain/2;
771  vertices[13](1)=Ly_domain/2;
772  vertices[13](2)=0;
773  vertices[14](0)=a*PointFrontTop(0);
774  vertices[14](1)=Ly_domain/2;
775  vertices[14](2)=0;
776  vertices[15](0)=b*PointRightTransom(0);
777  vertices[15](1)=Ly_domain/2;
778  vertices[15](2)=0;
779  vertices[16](0)=a*PointFrontTop(0);
780  vertices[16](1)=Ly_domain/2;
781  vertices[16](2)=-Lz_domain;
782  vertices[17](0)=0;
783  vertices[17](1)=Ly_domain/2;
784  vertices[17](2)=-Lz_domain;
785  vertices[18](0)=b*PointRightTransom(0);
786  vertices[18](1)=Ly_domain/2;
787  vertices[18](2)=-Lz_domain;
788  vertices[19](0)=0;
789  vertices[19](1)=Ly_domain/2;
790  vertices[19](2)=0;
791  vertices[20](0)=PointFrontTop(0);
792  vertices[20](1)=0;
793  vertices[20](2)=0;
794  vertices[21](0)=PointRightTransom(0);
795  vertices[21](1)=PointRightTransom(1);
796  vertices[21](2)=0;
797  vertices[22](0)=PointFrontBot(0);
798  vertices[22](1)=0;
799  vertices[22](2)=PointFrontBot(2);
800  vertices[23](0)=PointCenterTransom(0);
801  vertices[23](1)=0;
802  vertices[23](2)=PointCenterTransom(2);
803  vertices[24](0)=0;
804  vertices[24](1)=PointMidTop(1);
805  vertices[24](2)=0;
806  vertices[25](0)=PointMidBot(0);
807  vertices[25](1)=0;
808  vertices[25](2)=PointMidBot(2);
809  vertices[26](0)=PointLeftTransom(0);
810  vertices[26](1)=PointLeftTransom(1);
811  vertices[26](2)=0;
812  vertices[27](0)=PointFrontTop(0);
813  vertices[27](1)=0;
814  vertices[27](2)=0;
815  vertices[28](0)=PointCenterTransom(0);
816  vertices[28](1)=0;
817  vertices[28](2)=PointCenterTransom(2);
818  vertices[29](0)=PointFrontBot(0);
819  vertices[29](1)=0;
820  vertices[29](2)=PointFrontBot(2);
821  vertices[30](0)=0;
822  vertices[30](1)=-PointMidTop(1);
823  vertices[30](2)=0;
824  vertices[31](0)=PointMidBot(0);
825  vertices[31](1)=0;
826  vertices[31](2)=PointMidBot(2);
827  vertices[32](0)=PointLeftTransom(0);
828  vertices[32](1)=PointLeftTransom(1);
829  vertices[32](2)=0;
830  vertices[33](0)=PointFrontTop(0);
831  vertices[33](1)=0;
832  vertices[33](2)=0;
833  vertices[34](0)=-Lx_domain/2;
834  vertices[34](1)=0;
835  vertices[34](2)=0;
836  vertices[35](0)=-Lx_domain/2;
837  vertices[35](1)=-Ly_domain/2;
838  vertices[35](2)=0;
839  vertices[36](0)=a*PointFrontTop(0);
840  vertices[36](1)=-Ly_domain/2;
841  vertices[36](2)=0;
842  vertices[37](0)=b*PointLeftTransom(0);
843  vertices[37](1)=-Ly_domain/2;
844  vertices[37](2)=0;
845  vertices[38](0)=Lx_domain/2;
846  vertices[38](1)=-Ly_domain/2;
847  vertices[38](2)=0;
848  vertices[39](0)=Lx_domain/2;
849  vertices[39](1)=-Ly_domain/4;
850  vertices[39](2)=0;
851  vertices[40](0)=0;
852  vertices[40](1)=-PointMidTop(1);
853  vertices[40](2)=0;
854  vertices[41](0)=0;
855  vertices[41](1)=-Ly_domain/2;
856  vertices[41](2)=0;
857  vertices[42](0)=Lx_domain/2;
858  vertices[42](1)=Ly_domain/2;
859  vertices[42](2)=0;
860  vertices[43](0)=b*PointRightTransom(0);
861  vertices[43](1)=Ly_domain/2;
862  vertices[43](2)=0;
863  vertices[44](0)=a*PointFrontTop(0);
864  vertices[44](1)=Ly_domain/2;
865  vertices[44](2)=0;
866  vertices[45](0)=-Lx_domain/2;
867  vertices[45](1)=Ly_domain/2;
868  vertices[45](2)=0;
869  vertices[46](0)=0;
870  vertices[46](1)=PointMidTop(1);
871  vertices[46](2)=0;
872  vertices[47](0)=0;
873  vertices[47](1)=Ly_domain/2;
874  vertices[47](2)=0;
875  vertices[48](0)=-Lx_domain/2;
876  vertices[48](1)=0;
877  vertices[48](2)=-Lz_domain;
878  vertices[49](0)=Lx_domain/2;
879  vertices[49](1)=0;
880  vertices[49](2)=-Lz_domain;
881  vertices[50](0)=-Lx_domain/2;
882  vertices[50](1)=Ly_domain/2;
883  vertices[50](2)=-Lz_domain;
884  vertices[51](0)=Lx_domain/2;
885  vertices[51](1)=Ly_domain/2;
886  vertices[51](2)=-Lz_domain;
887  vertices[52](0)=a*PointFrontTop(0);
888  vertices[52](1)=0;
889  vertices[52](2)=-Lz_domain;
890  vertices[53](0)=0;
891  vertices[53](1)=0;
892  vertices[53](2)=-Lz_domain;
893  vertices[54](0)=b*(PointRightTransom(0)+PointLeftTransom(0))/2.0;
894  vertices[54](1)=0;
895  vertices[54](2)=-Lz_domain;
896  vertices[55](0)=a*PointFrontTop(0);
897  vertices[55](1)=Ly_domain/2;
898  vertices[55](2)=-Lz_domain;
899  vertices[56](0)=0;
900  vertices[56](1)=Ly_domain/2;
901  vertices[56](2)=-Lz_domain;
902  vertices[57](0)=b*PointRightTransom(0);
903  vertices[57](1)=Ly_domain/2;
904  vertices[57](2)=-Lz_domain;
905  vertices[58](0)=-Lx_domain/2;
906  vertices[58](1)=0;
907  vertices[58](2)=-Lz_domain;
908  vertices[59](0)=Lx_domain/2;
909  vertices[59](1)=0;
910  vertices[59](2)=-Lz_domain;
911  vertices[60](0)=Lx_domain/2;
912  vertices[60](1)=-Ly_domain/2;
913  vertices[60](2)=-Lz_domain;
914  vertices[61](0)=-Lx_domain/2;
915  vertices[61](1)=-Ly_domain/2;
916  vertices[61](2)=-Lz_domain;
917  vertices[62](0)=a*PointFrontTop(0);
918  vertices[62](1)=0;
919  vertices[62](2)=-Lz_domain;
920  vertices[63](0)=0;
921  vertices[63](1)=0;
922  vertices[63](2)=-Lz_domain;
923  vertices[64](0)=b*(PointRightTransom(0)+PointLeftTransom(0))/2.0;
924  vertices[64](1)=0;
925  vertices[64](2)=-Lz_domain;
926  vertices[65](0)=b*PointLeftTransom(0);
927  vertices[65](1)=-Ly_domain/2;
928  vertices[65](2)=-Lz_domain;
929  vertices[66](0)=0;
930  vertices[66](1)=-Ly_domain/2;
931  vertices[66](2)=-Lz_domain;
932  vertices[67](0)=a*PointFrontTop(0);
933  vertices[67](1)=-Ly_domain/2;
934  vertices[67](2)=-Lz_domain;
935  vertices[68](0)=-Lx_domain/2;
936  vertices[68](1)=0;
937  vertices[68](2)=0;
938  vertices[69](0)=-Lx_domain/2;
939  vertices[69](1)=0;
940  vertices[69](2)=-Lz_domain;
941  vertices[70](0)=-Lx_domain/2;
942  vertices[70](1)=Ly_domain/2;
943  vertices[70](2)=0;
944  vertices[71](0)=-Lx_domain/2;
945  vertices[71](1)=Ly_domain/2;
946  vertices[71](2)=-Lz_domain;
947  vertices[72](0)=-Lx_domain/2;
948  vertices[72](1)=0;
949  vertices[72](2)=0;
950  vertices[73](0)=-Lx_domain/2;
951  vertices[73](1)=0;
952  vertices[73](2)=-Lz_domain;
953  vertices[74](0)=-Lx_domain/2;
954  vertices[74](1)=-Ly_domain/2;
955  vertices[74](2)=-Lz_domain;
956  vertices[75](0)=-Lx_domain/2;
957  vertices[75](1)=-Ly_domain/2;
958  vertices[75](2)=0;
959  vertices[76](0)=Lx_domain/2;
960  vertices[76](1)=-Ly_domain/4;
961  vertices[76](2)=0;
962  vertices[77](0)=Lx_domain/2;
963  vertices[77](1)=Ly_domain/4;
964  vertices[77](2)=0;
965  vertices[78](0)=Lx_domain/2;
966  vertices[78](1)=-Ly_domain/2;
967  vertices[78](2)=0;
968  vertices[79](0)=Lx_domain/2;
969  vertices[79](1)=-Ly_domain/2;
970  vertices[79](2)=-Lz_domain;
971  vertices[80](0)=Lx_domain/2;
972  vertices[80](1)=0;
973  vertices[80](2)=0;
974  vertices[81](0)=Lx_domain/2;
975  vertices[81](1)=0;
976  vertices[81](2)=-Lz_domain;
977  vertices[82](0)=Lx_domain/2;
978  vertices[82](1)=Ly_domain/2;
979  vertices[82](2)=-Lz_domain;
980  vertices[83](0)=Lx_domain/2;
981  vertices[83](1)=Ly_domain/2;
982  vertices[83](2)=0;
983  vertices[84](0)=PointRightTransom(0);
984  vertices[84](1)=PointRightTransom(1);
985  vertices[84](2)=0;
986  vertices[85](0)=Lx_domain/2;
987  vertices[85](1)=Ly_domain/4;
988  vertices[85](2)=0;
989  vertices[86](0)=Lx_domain/2;
990  vertices[86](1)=0;
991  vertices[86](2)=0;
992  vertices[87](0)=PointCenterTransom(0);
993  vertices[87](1)=0;
994  vertices[87](2)=PointCenterTransom(2);
995 
996  cells.resize(35);
997 
998  cells[0].vertices[0]=0;
999  cells[0].vertices[1]=1;
1000  cells[0].vertices[2]=8;
1001  cells[0].vertices[3]=5;
1002  cells[1].vertices[0]=5;
1003  cells[1].vertices[1] =8;
1004  cells[1].vertices[2] =7;
1005  cells[1].vertices[3]=9;
1006  cells[2].vertices[0]=9;
1007  cells[2].vertices[1] =7;
1008  cells[2].vertices[2] =6;
1009  cells[2].vertices[3]=4;
1010  cells[3].vertices[0]=4;
1011  cells[3].vertices[1] =6;
1012  cells[3].vertices[2] =2;
1013  cells[3].vertices[3]=3;
1014  cells[4].vertices[0]=10;
1015  cells[4].vertices[1] =11;
1016  cells[4].vertices[2] =18;
1017  cells[4].vertices[3]=15;
1018  cells[5].vertices[0]=15;
1019  cells[5].vertices[1] =18;
1020  cells[5].vertices[2] =17;
1021  cells[5].vertices[3]=19;
1022  cells[6].vertices[0]=19;
1023  cells[6].vertices[1] =17;
1024  cells[6].vertices[2] =16;
1025  cells[6].vertices[3]=14;
1026  cells[7].vertices[0]=14;
1027  cells[7].vertices[1] =16;
1028  cells[7].vertices[2] =12;
1029  cells[7].vertices[3]=13;
1030  cells[8].vertices[0]=21;
1031  cells[8].vertices[1] =24;
1032  cells[8].vertices[2] =25;
1033  cells[8].vertices[3]=23;
1034  cells[9].vertices[0]=24;
1035  cells[9].vertices[1] =20;
1036  cells[9].vertices[2] =22;
1037  cells[9].vertices[3]=25;
1038  cells[10].vertices[0]=27;
1039  cells[10].vertices[1] =30;
1040  cells[10].vertices[2] =31;
1041  cells[10].vertices[3]=29;
1042  cells[11].vertices[0]=30;
1043  cells[11].vertices[1] =26;
1044  cells[11].vertices[2] =28;
1045  cells[11].vertices[3]=31;
1046  cells[12].vertices[0]=34;
1047  cells[12].vertices[1] =35;
1048  cells[12].vertices[2] =36;
1049  cells[12].vertices[3]=33;
1050  cells[13].vertices[0]=33;
1051  cells[13].vertices[1] =36;
1052  cells[13].vertices[2] =41;
1053  cells[13].vertices[3]=40;
1054  cells[14].vertices[0]=40;
1055  cells[14].vertices[1] =41;
1056  cells[14].vertices[2] =37;
1057  cells[14].vertices[3]=32;
1058  cells[15].vertices[0]=32;
1059  cells[15].vertices[1] =37;
1060  cells[15].vertices[2] =38;
1061  cells[15].vertices[3]=39;
1062  cells[16].vertices[0]=85;
1063  cells[16].vertices[1] =42;
1064  cells[16].vertices[2] =43;
1065  cells[16].vertices[3]=84;
1066  cells[17].vertices[0]=84;
1067  cells[17].vertices[1] =43;
1068  cells[17].vertices[2] =47;
1069  cells[17].vertices[3]=46;
1070  cells[18].vertices[0]=46;
1071  cells[18].vertices[1] =47;
1072  cells[18].vertices[2] =44;
1073  cells[18].vertices[3]=33;
1074  cells[19].vertices[0]=33;
1075  cells[19].vertices[1] =44;
1076  cells[19].vertices[2] =45;
1077  cells[19].vertices[3]=34;
1078  cells[20].vertices[0]=49;
1079  cells[20].vertices[1] =54;
1080  cells[20].vertices[2] =57;
1081  cells[20].vertices[3]=51;
1082  cells[21].vertices[0]=54;
1083  cells[21].vertices[1] =53;
1084  cells[21].vertices[2] =56;
1085  cells[21].vertices[3]=57;
1086  cells[22].vertices[0]=53;
1087  cells[22].vertices[1] =52;
1088  cells[22].vertices[2] =55;
1089  cells[22].vertices[3]=56;
1090  cells[23].vertices[0]=52;
1091  cells[23].vertices[1] =48;
1092  cells[23].vertices[2] =50;
1093  cells[23].vertices[3]=55;
1094  cells[24].vertices[0]=58;
1095  cells[24].vertices[1] =62;
1096  cells[24].vertices[2] =67;
1097  cells[24].vertices[3]=61;
1098  cells[25].vertices[0]=62;
1099  cells[25].vertices[1] =63;
1100  cells[25].vertices[2] =66;
1101  cells[25].vertices[3]=67;
1102  cells[26].vertices[0]=63;
1103  cells[26].vertices[1] =64;
1104  cells[26].vertices[2] =65;
1105  cells[26].vertices[3]=66;
1106  cells[27].vertices[0]=64;
1107  cells[27].vertices[1] =59;
1108  cells[27].vertices[2] =60;
1109  cells[27].vertices[3]=65;
1110  cells[28].vertices[0]=69;
1111  cells[28].vertices[1] =68;
1112  cells[28].vertices[2] =70;
1113  cells[28].vertices[3]=71;
1114  cells[29].vertices[0]=72;
1115  cells[29].vertices[1] =73;
1116  cells[29].vertices[2] =74;
1117  cells[29].vertices[3]=75;
1118  cells[30].vertices[0]=81;
1119  cells[30].vertices[1] =76;
1120  cells[30].vertices[2] =78;
1121  cells[30].vertices[3]=79;
1122  cells[31].vertices[0]=77;
1123  cells[31].vertices[1] =81;
1124  cells[31].vertices[2] =82;
1125  cells[31].vertices[3]=83;
1126  cells[32].vertices[0]=87;
1127  cells[32].vertices[1] =32;
1128  cells[32].vertices[2] =39;
1129  cells[32].vertices[3]=86;
1130  cells[33].vertices[0]=86;
1131  cells[33].vertices[1] =85;
1132  cells[33].vertices[2] =84;
1133  cells[33].vertices[3]=87;
1134  cells[34].vertices[0]=81;
1135  cells[34].vertices[1] =77;
1136  cells[34].vertices[2] =80;
1137  cells[34].vertices[3]=76;//*/
1138 
1139  cells[0].material_id = 1;
1140  cells[1].material_id = 1;
1141  cells[2].material_id = 1;
1142  cells[3].material_id = 1;
1143  cells[4].material_id = 2;
1144  cells[5].material_id = 2;
1145  cells[6].material_id = 2;
1146  cells[7].material_id = 2;
1147  cells[8].material_id = 3;
1148  cells[9].material_id = 3;
1149  cells[10].material_id = 4;
1150  cells[11].material_id = 4;
1151  cells[12].material_id = 5;
1152  cells[13].material_id = 5;
1153  cells[14].material_id = 5;
1154  cells[15].material_id = 5;
1155  cells[16].material_id = 6;
1156  cells[17].material_id = 6;
1157  cells[18].material_id = 6;
1158  cells[19].material_id = 6;
1159  cells[20].material_id = 7;
1160  cells[21].material_id = 7;
1161  cells[22].material_id = 7;
1162  cells[23].material_id = 7;
1163  cells[24].material_id = 8;
1164  cells[25].material_id = 8;
1165  cells[26].material_id = 8;
1166  cells[27].material_id = 8;
1167  cells[28].material_id = 9;
1168  cells[29].material_id = 10;
1169  cells[30].material_id = 11;
1170  cells[31].material_id = 11;
1171  cells[32].material_id = 5;
1172  cells[33].material_id = 6;
1173  cells[34].material_id = 11;//*/
1174 
1175 // waterline (on water) rear left
1176  subcelldata.boundary_lines.push_back (CellData<1>());
1177  subcelldata.boundary_lines.back().vertices[0] = 32;
1178  subcelldata.boundary_lines.back().vertices[1] = 40;
1179  subcelldata.boundary_lines.back().material_id = 29;
1180 // waterline (on water) front left
1181  subcelldata.boundary_lines.push_back (CellData<1>());
1182  subcelldata.boundary_lines.back().vertices[0] = 40;
1183  subcelldata.boundary_lines.back().vertices[1] = 33;
1184  subcelldata.boundary_lines.back().material_id = 27;
1185 // waterline (on water) front right
1186  subcelldata.boundary_lines.push_back (CellData<1>());
1187  subcelldata.boundary_lines.back().vertices[0] = 33;
1188  subcelldata.boundary_lines.back().vertices[1] = 46;
1189  subcelldata.boundary_lines.back().material_id = 26;
1190 // waterline (on water) rear right
1191  subcelldata.boundary_lines.push_back (CellData<1>());
1192  subcelldata.boundary_lines.back().vertices[0] = 46;
1193  subcelldata.boundary_lines.back().vertices[1] = 84;
1194  subcelldata.boundary_lines.back().material_id = 28;
1195 // waterline (on boat) right front
1196  subcelldata.boundary_lines.push_back (CellData<1>());
1197  subcelldata.boundary_lines.back().vertices[0] = 20;
1198  subcelldata.boundary_lines.back().vertices[1] = 24;
1199  subcelldata.boundary_lines.back().material_id = 21;
1200 // waterline (on boat) right rear
1201  subcelldata.boundary_lines.push_back (CellData<1>());
1202  subcelldata.boundary_lines.back().vertices[0] = 24;
1203  subcelldata.boundary_lines.back().vertices[1] = 21;
1204  subcelldata.boundary_lines.back().material_id = 23;
1205 // waterline (on boat) left rear
1206  subcelldata.boundary_lines.push_back (CellData<1>());
1207  subcelldata.boundary_lines.back().vertices[0] = 26;
1208  subcelldata.boundary_lines.back().vertices[1] = 30;
1209  subcelldata.boundary_lines.back().material_id = 24;
1210 // waterline (on boat) left front
1211  subcelldata.boundary_lines.push_back (CellData<1>());
1212  subcelldata.boundary_lines.back().vertices[0] = 30;
1213  subcelldata.boundary_lines.back().vertices[1] = 27;
1214  subcelldata.boundary_lines.back().material_id = 22;
1215 //front part of the keel (region needed for keel smoothing) left
1216  subcelldata.boundary_lines.push_back (CellData<1>());
1217  subcelldata.boundary_lines.back().vertices[0] = 29;
1218  subcelldata.boundary_lines.back().vertices[1] = 27;
1219  subcelldata.boundary_lines.back().material_id = 30;
1220 //front part of the keel (region needed for keel smoothing) right
1221  subcelldata.boundary_lines.push_back (CellData<1>());
1222  subcelldata.boundary_lines.back().vertices[0] = 20;
1223  subcelldata.boundary_lines.back().vertices[1] = 22;
1224  subcelldata.boundary_lines.back().material_id = 35;
1225 //central/front part of the keel left
1226  subcelldata.boundary_lines.push_back (CellData<1>());
1227  subcelldata.boundary_lines.back().vertices[0] = 31;
1228  subcelldata.boundary_lines.back().vertices[1] = 29;
1229  subcelldata.boundary_lines.back().material_id = 31;
1230 //central/front part of the keel right
1231  subcelldata.boundary_lines.push_back (CellData<1>());
1232  subcelldata.boundary_lines.back().vertices[0] = 22;
1233  subcelldata.boundary_lines.back().vertices[1] = 25;
1234  subcelldata.boundary_lines.back().material_id = 36;
1235 //central/rear part of the keel left
1236  subcelldata.boundary_lines.push_back (CellData<1>());
1237  subcelldata.boundary_lines.back().vertices[0] = 28;
1238  subcelldata.boundary_lines.back().vertices[1] = 31;
1239  subcelldata.boundary_lines.back().material_id = 31;
1240 //central/rear part of the keel right
1241  subcelldata.boundary_lines.push_back (CellData<1>());
1242  subcelldata.boundary_lines.back().vertices[0] = 25;
1243  subcelldata.boundary_lines.back().vertices[1] = 23;
1244  subcelldata.boundary_lines.back().material_id = 36;
1245 //rear part of the keel / transom edge on boat (region needed for keel smoothing) left
1246  subcelldata.boundary_lines.push_back (CellData<1>());
1247  subcelldata.boundary_lines.back().vertices[0] = 26;
1248  subcelldata.boundary_lines.back().vertices[1] = 28;
1249  subcelldata.boundary_lines.back().material_id = 32;
1250 //rear part of the keel / transom edge on boat (region needed for keel smoothing) right
1251  subcelldata.boundary_lines.push_back (CellData<1>());
1252  subcelldata.boundary_lines.back().vertices[0] = 23;
1253  subcelldata.boundary_lines.back().vertices[1] = 21;
1254  subcelldata.boundary_lines.back().material_id = 37;
1255 //transom edge on water left
1256  subcelldata.boundary_lines.push_back (CellData<1>());
1257  subcelldata.boundary_lines.back().vertices[0] = 32;
1258  subcelldata.boundary_lines.back().vertices[1] = 87;
1259  subcelldata.boundary_lines.back().material_id = 40;
1260 //transom edge on water right
1261  subcelldata.boundary_lines.push_back (CellData<1>());
1262  subcelldata.boundary_lines.back().vertices[0] = 84;
1263  subcelldata.boundary_lines.back().vertices[1] = 87;
1264  subcelldata.boundary_lines.back().material_id = 41;
1265 
1266  }
1267 
1268  else
1269  {
1270 
1272  Lx_domain = Lx_boat*12.0;
1273  Ly_domain = Lx_boat*4.0;
1274  Lz_domain = Lx_boat*2.0;
1275 
1276  vertices.resize(84);
1277 
1278  vertices[0](0)=-Lx_domain/2;
1279  vertices[0](1)=-Ly_domain/2 ;
1280  vertices[0](2)=0;
1281  vertices[1](0)=-Lx_domain/2;
1282  vertices[1](1)=-Ly_domain/2;
1283  vertices[1](2)=-Lz_domain;
1284  vertices[2](0)=Lx_domain/2;
1285  vertices[2](1)=-Ly_domain/2;
1286  vertices[2](2)=-Lz_domain;
1287  vertices[3](0)=Lx_domain/2;
1288  vertices[3](1)=-Ly_domain/2;
1289  vertices[3](2)=0;
1290  vertices[4](0)=b*PointBackTop(0);
1291  vertices[4](1)=-Ly_domain/2;
1292  vertices[4](2)=0;
1293  vertices[5](0)=a*PointFrontTop(0);
1294  vertices[5](1)=-Ly_domain/2;
1295  vertices[5](2)=0;
1296  vertices[6](0)=b*PointBackTop(0);
1297  vertices[6](1)=-Ly_domain/2;
1298  vertices[6](2)=-Lz_domain;
1299  vertices[7](0)=0;
1300  vertices[7](1)=-Ly_domain/2;
1301  vertices[7](2)=-Lz_domain;
1302  vertices[8](0)=a*PointFrontTop(0);
1303  vertices[8](1)=-Ly_domain/2;
1304  vertices[8](2)=-Lz_domain;
1305  vertices[9](0)=0;
1306  vertices[9](1)=-Ly_domain/2;
1307  vertices[9](2)=0;
1308  vertices[10](0)=Lx_domain/2;
1309  vertices[10](1)=Ly_domain/2;
1310  vertices[10](2)=0;
1311  vertices[11](0)=Lx_domain/2;
1312  vertices[11](1)=Ly_domain/2;
1313  vertices[11](2)=-Lz_domain;
1314  vertices[12](0)=-Lx_domain/2;
1315  vertices[12](1)=Ly_domain/2;
1316  vertices[12](2)=-Lz_domain;
1317  vertices[13](0)=-Lx_domain/2;
1318  vertices[13](1)=Ly_domain/2;
1319  vertices[13](2)=0;
1320  vertices[14](0)=a*PointFrontTop(0);
1321  vertices[14](1)=Ly_domain/2;
1322  vertices[14](2)=0;
1323  vertices[15](0)=b*PointBackTop(0);
1324  vertices[15](1)=Ly_domain/2;
1325  vertices[15](2)=0;
1326  vertices[16](0)=a*PointFrontTop(0);
1327  vertices[16](1)=Ly_domain/2;
1328  vertices[16](2)=-Lz_domain;
1329  vertices[17](0)=0;
1330  vertices[17](1)=Ly_domain/2;
1331  vertices[17](2)=-Lz_domain;
1332  vertices[18](0)=b*PointBackTop(0);
1333  vertices[18](1)=Ly_domain/2;
1334  vertices[18](2)=-Lz_domain;
1335  vertices[19](0)=0;
1336  vertices[19](1)=Ly_domain/2;
1337  vertices[19](2)=0;
1338  vertices[20](0)=PointFrontTop(0);
1339  vertices[20](1)=0;
1340  vertices[20](2)=0;
1341  vertices[21](0)=PointBackTop(0);
1342  vertices[21](1)=0;
1343  vertices[21](2)=0;
1344  vertices[22](0)=PointFrontBot(0);
1345  vertices[22](1)=0;
1346  vertices[22](2)=PointFrontBot(2);
1347  vertices[23](0)=PointBackBot(0);
1348  vertices[23](1)=0;
1349  vertices[23](2)=PointBackBot(2);
1350  vertices[24](0)=0;
1351  vertices[24](1)=PointMidTop(1);
1352  vertices[24](2)=0;
1353  vertices[25](0)=PointMidBot(0);
1354  vertices[25](1)=0;
1355  vertices[25](2)=PointMidBot(2);
1356  vertices[26](0)=PointBackTop(0);
1357  vertices[26](1)=0;
1358  vertices[26](2)=0;
1359  vertices[27](0)=PointFrontTop(0);
1360  vertices[27](1)=0;
1361  vertices[27](2)=0;
1362  vertices[28](0)=PointBackBot(0);
1363  vertices[28](1)=0;
1364  vertices[28](2)=PointBackBot(2);
1365  vertices[29](0)=PointFrontBot(0);
1366  vertices[29](1)=0;
1367  vertices[29](2)=PointFrontBot(2);
1368  vertices[30](0)=0;
1369  vertices[30](1)=-PointMidTop(1);
1370  vertices[30](2)=0;
1371  vertices[31](0)=PointMidBot(0);
1372  vertices[31](1)=0;
1373  vertices[31](2)=PointMidBot(2);
1374  vertices[32](0)=PointBackTop(0);
1375  vertices[32](1)=0;
1376  vertices[32](2)=0;
1377  vertices[33](0)=PointFrontTop(0);
1378  vertices[33](1)=0;
1379  vertices[33](2)=0;
1380  vertices[34](0)=-Lx_domain/2;
1381  vertices[34](1)=0;
1382  vertices[34](2)=0;
1383  vertices[35](0)=-Lx_domain/2;
1384  vertices[35](1)=-Ly_domain/2;
1385  vertices[35](2)=0;
1386  vertices[36](0)=a*PointFrontTop(0);
1387  vertices[36](1)=-Ly_domain/2;
1388  vertices[36](2)=0;
1389  vertices[37](0)=b*PointBackTop(0);
1390  vertices[37](1)=-Ly_domain/2;
1391  vertices[37](2)=0;
1392  vertices[38](0)=Lx_domain/2;
1393  vertices[38](1)=-Ly_domain/2;
1394  vertices[38](2)=0;
1395  vertices[39](0)=Lx_domain/2;
1396  vertices[39](1)=0;
1397  vertices[39](2)=0;
1398  vertices[40](0)=0;
1399  vertices[40](1)=-PointMidTop(1);
1400  vertices[40](2)=0;
1401  vertices[41](0)=0;
1402  vertices[41](1)=-Ly_domain/2;
1403  vertices[41](2)=0;
1404  vertices[42](0)=Lx_domain/2;
1405  vertices[42](1)=Ly_domain/2;
1406  vertices[42](2)=0;
1407  vertices[43](0)=b*PointBackTop(0);
1408  vertices[43](1)=Ly_domain/2;
1409  vertices[43](2)=0;
1410  vertices[44](0)=a*PointFrontTop(0);
1411  vertices[44](1)=Ly_domain/2;
1412  vertices[44](2)=0;
1413  vertices[45](0)=-Lx_domain/2;
1414  vertices[45](1)=Ly_domain/2;
1415  vertices[45](2)=0;
1416  vertices[46](0)=0;
1417  vertices[46](1)=PointMidTop(1);
1418  vertices[46](2)=0;
1419  vertices[47](0)=0;
1420  vertices[47](1)=Ly_domain/2;
1421  vertices[47](2)=0;
1422  vertices[48](0)=-Lx_domain/2;
1423  vertices[48](1)=0;
1424  vertices[48](2)=-Lz_domain;
1425  vertices[49](0)=Lx_domain/2;
1426  vertices[49](1)=0;
1427  vertices[49](2)=-Lz_domain;
1428  vertices[50](0)=-Lx_domain/2;
1429  vertices[50](1)=Ly_domain/2;
1430  vertices[50](2)=-Lz_domain;
1431  vertices[51](0)=Lx_domain/2;
1432  vertices[51](1)=Ly_domain/2;
1433  vertices[51](2)=-Lz_domain;
1434  vertices[52](0)=a*PointFrontTop(0);
1435  vertices[52](1)=0;
1436  vertices[52](2)=-Lz_domain;
1437  vertices[53](0)=0;
1438  vertices[53](1)=0;
1439  vertices[53](2)=-Lz_domain;
1440  vertices[54](0)=b*PointBackTop(0);
1441  vertices[54](1)=0;
1442  vertices[54](2)=-Lz_domain;
1443  vertices[55](0)=a*PointFrontTop(0);
1444  vertices[55](1)=Ly_domain/2;
1445  vertices[55](2)=-Lz_domain;
1446  vertices[56](0)=0;
1447  vertices[56](1)=Ly_domain/2;
1448  vertices[56](2)=-Lz_domain;
1449  vertices[57](0)=b*PointBackTop(0);
1450  vertices[57](1)=Ly_domain/2;
1451  vertices[57](2)=-Lz_domain;
1452  vertices[58](0)=-Lx_domain/2;
1453  vertices[58](1)=0;
1454  vertices[58](2)=-Lz_domain;
1455  vertices[59](0)=Lx_domain/2;
1456  vertices[59](1)=0;
1457  vertices[59](2)=-Lz_domain;
1458  vertices[60](0)=Lx_domain/2;
1459  vertices[60](1)=-Ly_domain/2;
1460  vertices[60](2)=-Lz_domain;
1461  vertices[61](0)=-Lx_domain/2;
1462  vertices[61](1)=-Ly_domain/2;
1463  vertices[61](2)=-Lz_domain;
1464  vertices[62](0)=a*PointFrontTop(0);
1465  vertices[62](1)=0;
1466  vertices[62](2)=-Lz_domain;
1467  vertices[63](0)=0;
1468  vertices[63](1)=0;
1469  vertices[63](2)=-Lz_domain;
1470  vertices[64](0)=b*PointBackTop(0);
1471  vertices[64](1)=0;
1472  vertices[64](2)=-Lz_domain;
1473  vertices[65](0)=b*PointBackTop(0);
1474  vertices[65](1)=-Ly_domain/2;
1475  vertices[65](2)=-Lz_domain;
1476  vertices[66](0)=0;
1477  vertices[66](1)=-Ly_domain/2;
1478  vertices[66](2)=-Lz_domain;
1479  vertices[67](0)=a*PointFrontTop(0);
1480  vertices[67](1)=-Ly_domain/2;
1481  vertices[67](2)=-Lz_domain;
1482  vertices[68](0)=-Lx_domain/2;
1483  vertices[68](1)=0;
1484  vertices[68](2)=0;
1485  vertices[69](0)=-Lx_domain/2;
1486  vertices[69](1)=0;
1487  vertices[69](2)=-Lz_domain;
1488  vertices[70](0)=-Lx_domain/2;
1489  vertices[70](1)=Ly_domain/2;
1490  vertices[70](2)=0;
1491  vertices[71](0)=-Lx_domain/2;
1492  vertices[71](1)=Ly_domain/2;
1493  vertices[71](2)=-Lz_domain;
1494  vertices[72](0)=-Lx_domain/2;
1495  vertices[72](1)=0;
1496  vertices[72](2)=0;
1497  vertices[73](0)=-Lx_domain/2;
1498  vertices[73](1)=0;
1499  vertices[73](2)=-Lz_domain;
1500  vertices[74](0)=-Lx_domain/2;
1501  vertices[74](1)=-Ly_domain/2;
1502  vertices[74](2)=-Lz_domain;
1503  vertices[75](0)=-Lx_domain/2;
1504  vertices[75](1)=-Ly_domain/2;
1505  vertices[75](2)=0;
1506  vertices[76](0)=Lx_domain/2;
1507  vertices[76](1)=0;
1508  vertices[76](2)=0;
1509  vertices[77](0)=Lx_domain/2;
1510  vertices[77](1)=0;
1511  vertices[77](2)=-Lz_domain;
1512  vertices[78](0)=Lx_domain/2;
1513  vertices[78](1)=-Ly_domain/2;
1514  vertices[78](2)=0;
1515  vertices[79](0)=Lx_domain/2;
1516  vertices[79](1)=-Ly_domain/2;
1517  vertices[79](2)=-Lz_domain;
1518  vertices[80](0)=Lx_domain/2;
1519  vertices[80](1)=0;
1520  vertices[80](2)=0;
1521  vertices[81](0)=Lx_domain/2;
1522  vertices[81](1)=0;
1523  vertices[81](2)=-Lz_domain;
1524  vertices[82](0)=Lx_domain/2;
1525  vertices[82](1)=Ly_domain/2;
1526  vertices[82](2)=-Lz_domain;
1527  vertices[83](0)=Lx_domain/2;
1528  vertices[83](1)=Ly_domain/2;
1529  vertices[83](2)=0;
1530 
1531  cells.resize(32);
1532 
1533  cells[0].vertices[0]=0;
1534  cells[0].vertices[1]=1;
1535  cells[0].vertices[2]=8;
1536  cells[0].vertices[3]=5;
1537  cells[1].vertices[0]=5;
1538  cells[1].vertices[1] =8;
1539  cells[1].vertices[2] =7;
1540  cells[1].vertices[3]=9;
1541  cells[2].vertices[0]=9;
1542  cells[2].vertices[1] =7;
1543  cells[2].vertices[2] =6;
1544  cells[2].vertices[3]=4;
1545  cells[3].vertices[0]=4;
1546  cells[3].vertices[1] =6;
1547  cells[3].vertices[2] =2;
1548  cells[3].vertices[3]=3;
1549  cells[4].vertices[0]=10;
1550  cells[4].vertices[1] =11;
1551  cells[4].vertices[2] =18;
1552  cells[4].vertices[3]=15;
1553  cells[5].vertices[0]=15;
1554  cells[5].vertices[1] =18;
1555  cells[5].vertices[2] =17;
1556  cells[5].vertices[3]=19;
1557  cells[6].vertices[0]=19;
1558  cells[6].vertices[1] =17;
1559  cells[6].vertices[2] =16;
1560  cells[6].vertices[3]=14;
1561  cells[7].vertices[0]=14;
1562  cells[7].vertices[1] =16;
1563  cells[7].vertices[2] =12;
1564  cells[7].vertices[3]=13;
1565  cells[8].vertices[0]=21;
1566  cells[8].vertices[1] =24;
1567  cells[8].vertices[2] =25;
1568  cells[8].vertices[3]=23;
1569  cells[9].vertices[0]=24;
1570  cells[9].vertices[1] =20;
1571  cells[9].vertices[2] =22;
1572  cells[9].vertices[3]=25;
1573  cells[10].vertices[0]=27;
1574  cells[10].vertices[1] =30;
1575  cells[10].vertices[2] =31;
1576  cells[10].vertices[3]=29;
1577  cells[11].vertices[0]=30;
1578  cells[11].vertices[1] =26;
1579  cells[11].vertices[2] =28;
1580  cells[11].vertices[3]=31;
1581  cells[12].vertices[0]=34;
1582  cells[12].vertices[1] =35;
1583  cells[12].vertices[2] =36;
1584  cells[12].vertices[3]=33;
1585  cells[13].vertices[0]=33;
1586  cells[13].vertices[1] =36;
1587  cells[13].vertices[2] =41;
1588  cells[13].vertices[3]=40;
1589  cells[14].vertices[0]=40;
1590  cells[14].vertices[1] =41;
1591  cells[14].vertices[2] =37;
1592  cells[14].vertices[3]=32;
1593  cells[15].vertices[0]=32;
1594  cells[15].vertices[1] =37;
1595  cells[15].vertices[2] =38;
1596  cells[15].vertices[3]=39;
1597  cells[16].vertices[0]=39;
1598  cells[16].vertices[1] =42;
1599  cells[16].vertices[2] =43;
1600  cells[16].vertices[3]=32;
1601  cells[17].vertices[0]=32;
1602  cells[17].vertices[1] =43;
1603  cells[17].vertices[2] =47;
1604  cells[17].vertices[3]=46;
1605  cells[18].vertices[0]=46;
1606  cells[18].vertices[1] =47;
1607  cells[18].vertices[2] =44;
1608  cells[18].vertices[3]=33;
1609  cells[19].vertices[0]=33;
1610  cells[19].vertices[1] =44;
1611  cells[19].vertices[2] =45;
1612  cells[19].vertices[3]=34;
1613  cells[20].vertices[0]=49;
1614  cells[20].vertices[1] =54;
1615  cells[20].vertices[2] =57;
1616  cells[20].vertices[3]=51;
1617  cells[21].vertices[0]=54;
1618  cells[21].vertices[1] =53;
1619  cells[21].vertices[2] =56;
1620  cells[21].vertices[3]=57;
1621  cells[22].vertices[0]=53;
1622  cells[22].vertices[1] =52;
1623  cells[22].vertices[2] =55;
1624  cells[22].vertices[3]=56;
1625  cells[23].vertices[0]=52;
1626  cells[23].vertices[1] =48;
1627  cells[23].vertices[2] =50;
1628  cells[23].vertices[3]=55;
1629  cells[24].vertices[0]=58;
1630  cells[24].vertices[1] =62;
1631  cells[24].vertices[2] =67;
1632  cells[24].vertices[3]=61;
1633  cells[25].vertices[0]=62;
1634  cells[25].vertices[1] =63;
1635  cells[25].vertices[2] =66;
1636  cells[25].vertices[3]=67;
1637  cells[26].vertices[0]=63;
1638  cells[26].vertices[1] =64;
1639  cells[26].vertices[2] =65;
1640  cells[26].vertices[3]=66;
1641  cells[27].vertices[0]=64;
1642  cells[27].vertices[1] =59;
1643  cells[27].vertices[2] =60;
1644  cells[27].vertices[3]=65;
1645  cells[28].vertices[0]=69;
1646  cells[28].vertices[1] =68;
1647  cells[28].vertices[2] =70;
1648  cells[28].vertices[3]=71;
1649  cells[29].vertices[0]=72;
1650  cells[29].vertices[1] =73;
1651  cells[29].vertices[2] =74;
1652  cells[29].vertices[3]=75;
1653  cells[30].vertices[0]=77;
1654  cells[30].vertices[1] =76;
1655  cells[30].vertices[2] =78;
1656  cells[30].vertices[3]=79;
1657  cells[31].vertices[0]=80;
1658  cells[31].vertices[1] =81;
1659  cells[31].vertices[2] =82;
1660  cells[31].vertices[3]=83;//*/
1661 
1662  cells[0].material_id = 1;
1663  cells[1].material_id = 1;
1664  cells[2].material_id = 1;
1665  cells[3].material_id = 1;
1666  cells[4].material_id = 2;
1667  cells[5].material_id = 2;
1668  cells[6].material_id = 2;
1669  cells[7].material_id = 2;
1670  cells[8].material_id = 3;
1671  cells[9].material_id = 3;
1672  cells[10].material_id = 4;
1673  cells[11].material_id = 4;
1674  cells[12].material_id = 5;
1675  cells[13].material_id = 5;
1676  cells[14].material_id = 5;
1677  cells[15].material_id = 5;
1678  cells[16].material_id = 6;
1679  cells[17].material_id = 6;
1680  cells[18].material_id = 6;
1681  cells[19].material_id = 6;
1682  cells[20].material_id = 7;
1683  cells[21].material_id = 7;
1684  cells[22].material_id = 7;
1685  cells[23].material_id = 7;
1686  cells[24].material_id = 8;
1687  cells[25].material_id = 8;
1688  cells[26].material_id = 8;
1689  cells[27].material_id = 8;
1690  cells[28].material_id = 9;
1691  cells[29].material_id = 10;
1692  cells[30].material_id = 11;
1693  cells[31].material_id = 12;//*/
1694 
1695 // waterline (on water) rear left
1696  subcelldata.boundary_lines.push_back (CellData<1>());
1697  subcelldata.boundary_lines.back().vertices[0] = 32;
1698  subcelldata.boundary_lines.back().vertices[1] = 40;
1699  subcelldata.boundary_lines.back().material_id = 29;
1700 // waterline (on water) front left
1701  subcelldata.boundary_lines.push_back (CellData<1>());
1702  subcelldata.boundary_lines.back().vertices[0] = 40;
1703  subcelldata.boundary_lines.back().vertices[1] = 33;
1704  subcelldata.boundary_lines.back().material_id = 27;
1705 // waterline (on water) front right
1706  subcelldata.boundary_lines.push_back (CellData<1>());
1707  subcelldata.boundary_lines.back().vertices[0] = 33;
1708  subcelldata.boundary_lines.back().vertices[1] = 46;
1709  subcelldata.boundary_lines.back().material_id = 26;
1710 // waterline (on water) rear right
1711  subcelldata.boundary_lines.push_back (CellData<1>());
1712  subcelldata.boundary_lines.back().vertices[0] = 46;
1713  subcelldata.boundary_lines.back().vertices[1] = 32;
1714  subcelldata.boundary_lines.back().material_id = 28;
1715 // waterline (on boat) right front
1716  subcelldata.boundary_lines.push_back (CellData<1>());
1717  subcelldata.boundary_lines.back().vertices[0] = 20;
1718  subcelldata.boundary_lines.back().vertices[1] = 24;
1719  subcelldata.boundary_lines.back().material_id = 21;
1720 // waterline (on boat) right rear
1721  subcelldata.boundary_lines.push_back (CellData<1>());
1722  subcelldata.boundary_lines.back().vertices[0] = 24;
1723  subcelldata.boundary_lines.back().vertices[1] = 21;
1724  subcelldata.boundary_lines.back().material_id = 23;
1725 // waterline (on boat) left rear
1726  subcelldata.boundary_lines.push_back (CellData<1>());
1727  subcelldata.boundary_lines.back().vertices[0] = 26;
1728  subcelldata.boundary_lines.back().vertices[1] = 30;
1729  subcelldata.boundary_lines.back().material_id = 24;
1730 // waterline (on boat) left front
1731  subcelldata.boundary_lines.push_back (CellData<1>());
1732  subcelldata.boundary_lines.back().vertices[0] = 30;
1733  subcelldata.boundary_lines.back().vertices[1] = 27;
1734  subcelldata.boundary_lines.back().material_id = 22;
1735 //front part of the keel (region needed for keel smoothing) left
1736  subcelldata.boundary_lines.push_back (CellData<1>());
1737  subcelldata.boundary_lines.back().vertices[0] = 29;
1738  subcelldata.boundary_lines.back().vertices[1] = 27;
1739  subcelldata.boundary_lines.back().material_id = 30;
1740 //front part of the keel (region needed for keel smoothing) right
1741  subcelldata.boundary_lines.push_back (CellData<1>());
1742  subcelldata.boundary_lines.back().vertices[0] = 20;
1743  subcelldata.boundary_lines.back().vertices[1] = 22;
1744  subcelldata.boundary_lines.back().material_id = 35;
1745 //central/front part of the keel left
1746  subcelldata.boundary_lines.push_back (CellData<1>());
1747  subcelldata.boundary_lines.back().vertices[0] = 31;
1748  subcelldata.boundary_lines.back().vertices[1] = 29;
1749  subcelldata.boundary_lines.back().material_id = 31;
1750 //central/front part of the keel right
1751  subcelldata.boundary_lines.push_back (CellData<1>());
1752  subcelldata.boundary_lines.back().vertices[0] = 22;
1753  subcelldata.boundary_lines.back().vertices[1] = 25;
1754  subcelldata.boundary_lines.back().material_id = 36;
1755 //central/rear part of the keel left
1756  subcelldata.boundary_lines.push_back (CellData<1>());
1757  subcelldata.boundary_lines.back().vertices[0] = 28;
1758  subcelldata.boundary_lines.back().vertices[1] = 31;
1759  subcelldata.boundary_lines.back().material_id = 31;
1760 //central/rear part of the keel right
1761  subcelldata.boundary_lines.push_back (CellData<1>());
1762  subcelldata.boundary_lines.back().vertices[0] = 25;
1763  subcelldata.boundary_lines.back().vertices[1] = 23;
1764  subcelldata.boundary_lines.back().material_id = 36;
1765 //rear part of the keel (region needed for keel smoothing) left
1766  subcelldata.boundary_lines.push_back (CellData<1>());
1767  subcelldata.boundary_lines.back().vertices[0] = 26;
1768  subcelldata.boundary_lines.back().vertices[1] = 28;
1769  subcelldata.boundary_lines.back().material_id = 32;
1770 //rear part of the keel (region needed for keel smoothing) right
1771  subcelldata.boundary_lines.push_back (CellData<1>());
1772  subcelldata.boundary_lines.back().vertices[0] = 23;
1773  subcelldata.boundary_lines.back().vertices[1] = 21;
1774  subcelldata.boundary_lines.back().material_id = 37;
1775 
1776  }
1777  }
1778 
1779  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
1781 
1782  triangulation.create_triangulation_compatibility(vertices, cells, subcelldata );
1783 
1784 
1785  std::ofstream logfile("meshResult.inp");
1786  GridOut grid_out;
1787  grid_out.write_ucd(triangulation, logfile);
1788 //*/
1789 
1790 }
1791 
1793 {
1794 
1796 
1798 
1801  for (unsigned int i=0; i<dh.n_dofs(); ++i)
1802  {
1803  if (flags[i] & water || flags[i] & pressure)
1804  surface_nodes(i) = 1;
1805  else
1806  other_nodes(i) = 1;
1807  }
1808 
1809  iges_normals.clear();
1810  iges_mean_curvatures.clear();
1811  iges_normals.resize(dh.n_dofs());
1812  old_iges_normals.resize(dh.n_dofs());
1813  iges_mean_curvatures.resize(dh.n_dofs());
1819  vector_dh.n_dofs(),
1824  set_up_smoother();
1825 
1826  /*
1827  // Let's put all the pressure quad nodes in memory
1828  cell_it
1829  cell = dh.begin_active(),
1830  endc = dh.end();
1831  FEValues<2,3> fe_v(*mapping, fe, *quadrature,
1832  update_values | update_gradients |
1833  update_cell_normal_vectors |
1834  update_quadrature_points |
1835  update_JxW_values);
1836 
1837  const unsigned int n_q_points = fe_v.n_quadrature_points;
1838  const unsigned int dofs_per_cell = fe.dofs_per_cell;
1839  std::vector<unsigned int> local_dof_indices (dofs_per_cell);
1840 
1841 
1842  for (; cell != endc; ++cell)
1843  {
1844  if ((cell->material_id() == wall_sur_ID1 )) // right side of the boat
1845  {
1846  fe_v.reinit(cell);
1847  const std::vector<Point<3> > &node_positions = fe_v.get_quadrature_points();
1848  const std::vector<Point<dim> > &node_normals = fe_v.get_normal_vectors();
1849  std::vector<Point<3> > proj_quad_nodes(n_q_points);
1850  for (unsigned int q=0; q<n_q_points; ++q)
1851  {
1852  boat_model.boat_water_line_right->assigned_axis_projection_and_diff_forms(proj_quad_nodes[],
1853  iges_normals[i],
1854  iges_mean_curvatures[i],
1855  vector_support_points[3*i],
1856  node_normals[i]); // for projection in mesh normal direction
1857  }
1858  }
1859  }
1860  */
1861 
1862 }
1863 
1864 
1865 
1867 {
1868 
1869  double tol = 1e-8;
1870 
1871 
1872 
1873  cell_it
1874  vector_cell = vector_dh.begin_active(),
1875  vector_endc = vector_dh.end();
1876 
1877  cell_it
1878  cell = dh.begin_active(),
1879  endc = dh.end();
1880 
1881  std::vector<unsigned int> dofs(fe.dofs_per_cell);
1882  std::vector<unsigned int> vector_dofs(vector_fe.dofs_per_cell);
1883 
1884  // mappa che associa ad ogni dof le celle cui esso appartiene
1885  dof_to_elems.clear();
1886 
1887  // mappa che associa ad ogni gradient dof le celle cui esso appartiene
1888  vector_dof_to_elems.clear();
1889 
1890  // vettore che associa ad ogni gradient dof la sua componente
1891  vector_dof_components.clear();
1893 
1894  // mappa che associa ad ogni cella un set contenente le celle circostanti
1895  elem_to_surr_elems.clear();
1896 
1897  // set che raccoglie i nodi della free surface che stanno sulla barca
1898  free_surf_and_boat_nodes.clear();
1899 
1900  // mappa raccoglie i nodi degli edges della barca
1901  boat_nodes.clear();
1902 
1903 
1904  for (; cell!=endc,vector_cell!=vector_endc; ++cell,++vector_cell)
1905  {
1906  Assert(cell->index() == vector_cell->index(), ExcInternalError());
1907 
1908  cell->get_dof_indices(dofs);
1909  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
1910  {
1911  dof_to_elems[dofs[j]].push_back(cell);
1912  }
1913  vector_cell->get_dof_indices(vector_dofs);
1914  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
1915  {
1916  vector_dof_to_elems[vector_dofs[j]].push_back(vector_cell);
1917  vector_dof_components[vector_dofs[j]] = vector_fe.system_to_component_index(j).first;
1918  }
1919  }
1920 
1921  // qui viene creata la mappa degli elmenti che circondano ciascun elemento
1922  for (cell = dh.begin_active(); cell != endc; ++cell)
1923  {
1924  cell->get_dof_indices(dofs);
1925  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
1926  {
1927  std::set <unsigned int> duplicates = double_nodes_set[dofs[j]];
1928  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
1929  {
1930  std::vector<cell_it>
1931  dof_cell_list = dof_to_elems[*pos];
1932  for (unsigned int k=0; k<dof_cell_list.size(); ++k)
1933  elem_to_surr_elems[cell].insert(dof_cell_list[k]);
1934  }
1935  }
1936  }
1937 
1938 
1939  std::vector<unsigned int> face_dofs(fe.dofs_per_face);
1940  for (cell=dh.begin_active(); cell!= endc; ++cell)
1941  {
1942  if ((cell->material_id() == free_sur_ID1 ||
1943  cell->material_id() == free_sur_ID2 ||
1944  cell->material_id() == free_sur_ID3 ))
1945  {
1946  if ( cell->at_boundary() )
1947  {
1948  for (unsigned int j = 0; j < GeometryInfo<2>::faces_per_cell; j++)
1949  {
1950  if (cell->face(j)->boundary_id() == free_sur_edge_on_boat_ID )
1951  {
1952  cell->face(j)->get_dof_indices(face_dofs);
1953  for (unsigned int k=0; k<fe.dofs_per_face; ++k)
1954  free_surf_and_boat_nodes.insert(face_dofs[k]);
1955  }
1956  }
1957  }
1958  }
1959  }
1960 
1961 
1963 
1964  std::vector<unsigned int> vector_local_dof_indices (vector_fe.dofs_per_cell);
1965  vector_cell = vector_dh.begin_active();
1966  vector_endc = vector_dh.end();
1967 
1968  for (; vector_cell!=vector_endc; ++vector_cell)
1969  {
1970  //std::cout<<"??1 "<<vector_fe.dofs_per_cell<<std::endl;
1971  vector_cell->get_dof_indices(vector_local_dof_indices);
1972  if (vector_cell->material_id() == wall_sur_ID1 ||
1973  vector_cell->material_id() == wall_sur_ID2 ||
1974  vector_cell->material_id() == wall_sur_ID3 )
1975  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
1976  {
1977  //std::cout<<"??2"<<std::endl;
1978  unsigned int id=vector_local_dof_indices[j];
1979  boat_nodes.insert(id);
1980  //std::cout<<"??3 "<<id<<" "<<comp_i<<std::endl;
1981  }
1982  }
1983 
1984  edge_cells.clear();
1985  {
1986  tria_it
1987  cell = tria.begin_active(),
1988  endc = tria.end();
1989 
1990  for (; cell != endc; ++cell)
1991  if (cell->at_boundary() )
1992  edge_cells.insert(cell);
1993 
1994  }
1995 
1996 
1997 
1998 
1999  //for( std::map<tria_it, tria_it>::iterator it=boat_to_water_edge_cells.begin();
2000  // it != boat_to_water_edge_cells.end(); ++it)
2001  //std::cout << it->first << " -> " << it->second << std::endl;
2002  //}
2003 //*/
2004 
2005 
2006  flags.clear();
2007  flags.resize(dh.n_dofs());
2008 
2009  vector_flags.clear();
2010  vector_flags.resize(vector_dh.n_dofs());
2011 
2012  cell_flags.clear();
2013  cell_flags.resize(tria.n_active_cells());
2014 
2015 
2016 
2017  unsigned int cell_id=0;
2018  std::vector<unsigned int> vector_face_dofs(vector_fe.dofs_per_face);
2019  //std::vector<unsigned int> face_dofs(fe.dofs_per_face);
2020 
2021  vector_cell = vector_dh.begin_active();
2022  vector_endc = vector_dh.end();
2023 
2024  cell = dh.begin_active();
2025  endc = dh.end();
2026 
2027  //std::vector<unsigned int> dofs(fe.dofs_per_cell);
2028  //std::vector<unsigned int> vector_dofs(vector_fe.dofs_per_cell);
2029 
2030  for (cell = dh.begin_active(), vector_cell = vector_dh.begin_active();
2031  cell != endc; ++cell, ++vector_cell, ++cell_id)
2032  {
2033  Assert(cell->index() == vector_cell->index(), ExcInternalError());
2034  cell->get_dof_indices(dofs);
2035  vector_cell->get_dof_indices(vector_dofs);
2036 
2037  // left or right
2038  if (cell->center()(1) > 0)
2039  {
2040  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2041  flags[dofs[j]] |= right_side;
2042  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
2043  vector_flags[vector_dofs[j]] |= right_side;
2044  }
2045  else
2046  {
2047  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2048  flags[dofs[j]] |= left_side;
2049  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
2050  vector_flags[vector_dofs[j]] |= left_side;
2051  }
2052  // Free surface
2053  if ((cell->material_id() == free_sur_ID1 ||
2054  cell->material_id() == free_sur_ID2 ))
2055  {
2056  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2057  flags[dofs[j]] |= water;
2058  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
2059  vector_flags[vector_dofs[j]] |= water;
2060 
2061  } // boat surface
2062  else if ((cell->material_id() == wall_sur_ID1 ||
2063  cell->material_id() == wall_sur_ID2 ))
2064  {
2065  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2066  flags[dofs[j]] |= boat;
2067  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
2068  vector_flags[vector_dofs[j]] |= boat;
2069  }
2070  else if ((cell->material_id() == inflow_sur_ID1 ||
2071  cell->material_id() == inflow_sur_ID2 ))
2072  {
2073  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2074  flags[dofs[j]] |= inflow;
2075  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
2076  vector_flags[vector_dofs[j]] |= inflow;
2077  }
2078  else if ((cell->material_id() == pressure_sur_ID ))
2079  {
2080  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2081  flags[dofs[j]] |= pressure;
2082  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
2083  vector_flags[vector_dofs[j]] |= pressure;
2084  }
2085  else
2086  {
2087  for (unsigned int j=0; j<fe.dofs_per_cell; ++j)
2088  flags[dofs[j]] |= walls;
2089  for (unsigned int j=0; j<vector_fe.dofs_per_cell; ++j)
2090  vector_flags[vector_dofs[j]] |= walls;
2091  }
2092 
2093 
2094  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
2095  if ( cell->face(f)->at_boundary() )
2096  {
2097  cell->face(f)->get_dof_indices(face_dofs);
2098  vector_cell->face(f)->get_dof_indices(vector_face_dofs);
2099  for (unsigned int k=0; k<face_dofs.size(); ++k)
2100  flags[face_dofs[k]] |= edge;
2101  for (unsigned int k=0; k<vector_face_dofs.size(); ++k)
2102  vector_flags[vector_face_dofs[k]] |= edge;
2103  }
2104  }
2105  // Now set the relationships...
2106  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2107  {
2108  std::set<unsigned int> doubles = double_nodes_set[i];
2109  doubles.erase(i);
2110  for (std::set<unsigned int>::iterator it = doubles.begin() ; it != doubles.end(); it++ )
2111  {
2112  if (flags[*it] & water)
2113  {
2114  flags[i] |= near_water;
2115  }
2116  else if (flags[*it] & boat)
2117  {
2118  flags[i] |= near_boat;
2119  if (flags[i] & boat)
2120  {
2121  flags[i] |= keel;
2122  }
2123  }
2124  else if (flags[*it] & inflow)
2125  {
2126  flags[i] |= near_inflow;
2127  }
2128  else if (flags[*it] & pressure)
2129  {
2130  flags[i] |= near_pressure;
2131  }
2132  else
2133  flags[i] |= near_walls;
2134  }
2135  }
2136 
2137  // Now set the relationships...
2138  for (unsigned int i=0; i<vector_dh.n_dofs(); ++i)
2139  {
2140  std::set<unsigned int> doubles = vector_double_nodes_set[i];
2141  doubles.erase(i);
2142  for (std::set<unsigned int>::iterator it = doubles.begin() ; it != doubles.end(); it++ )
2143  {
2144  if (vector_flags[*it] & water)
2145  {
2146  vector_flags[i] |= near_water;
2147  }
2148  else if (vector_flags[*it] & boat)
2149  {
2150  vector_flags[i] |= near_boat;
2151  if (vector_flags[i] & boat)
2152  {
2153  vector_flags[i] |= keel;
2154  //z++;
2155  }
2156  }
2157  else if (vector_flags[*it] & inflow)
2158  {
2159  vector_flags[i] |= near_inflow;
2160  }
2161  else if (vector_flags[*it] & pressure)
2162  {
2164  }
2165  else
2166  vector_flags[i] |= near_walls;
2167  }
2168  }
2169 
2170  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2171  {
2172  std::set<unsigned int> doubles = double_nodes_set[i];
2173  if ((flags[i] & near_boat) &&
2174  (doubles.size() == 3))
2175  flags[i] |= keel;
2176 
2177  }
2178 
2179  for (unsigned int i=0; i<vector_dh.n_dofs(); ++i)
2180  {
2181  std::set<unsigned int> doubles = vector_double_nodes_set[i];
2182  if ((vector_flags[i] & near_boat) &&
2183  (doubles.size() == 3))
2184  vector_flags[i] |= keel;
2185 
2186  }
2187 
2188  if (boat_model.is_transom)
2189  {
2190 
2191  // parameters for rear left water line smoothing
2192  unsigned int left_boat_transom_point_id = 0;
2193  unsigned int right_boat_transom_point_id = 0;
2194  unsigned int left_water_transom_point_id = 0;
2195  unsigned int right_water_transom_point_id = 0;
2196 
2197  unsigned int point_id_left = find_point_id(boat_model.PointLeftTransom, ref_points);
2198  unsigned int point_id_right = find_point_id(boat_model.PointRightTransom, ref_points);
2199  std::set<unsigned int> duplicates = double_nodes_set[point_id_left];
2200  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2201  {
2202  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
2203  if ( flags[*pos] & water)
2204  {
2205  left_water_transom_point_id = *pos;
2206  }
2207  else
2208  {
2209  left_boat_transom_point_id = *pos;
2210  }
2211  }
2212  duplicates = double_nodes_set[point_id_right];
2213  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2214  {
2215  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
2216  if ( flags[*pos] & water)
2217  {
2218  right_water_transom_point_id = *pos;
2219  }
2220  else
2221  {
2222  right_boat_transom_point_id = *pos;
2223  }
2224  }
2225 
2226 
2227  std::vector<unsigned int> face_dofs(fe.dofs_per_face);
2228  for (cell=dh.begin_active(); cell!= endc; ++cell)
2229  {
2230  if ( cell->at_boundary() )
2231  {
2232  for (unsigned int j = 0; j < GeometryInfo<2>::faces_per_cell; j++)
2233  {
2234  if ((cell->face(j)->boundary_id() == 40) ||
2235  (cell->face(j)->boundary_id() == 41) )
2236  {
2237  cell->face(j)->get_dof_indices(face_dofs);
2238  for (unsigned int k=0; k<fe.dofs_per_face; ++k)
2239  {
2240  if ( (right_water_transom_point_id != face_dofs[k]) &&
2241  (left_water_transom_point_id != face_dofs[k]) )
2242  {
2243  flags[face_dofs[k]] |= transom_on_water;
2244  for (unsigned int p=0; p<3; ++p)
2245  vector_flags[3*face_dofs[k]+p] |= transom_on_water;
2246  }
2247  }
2248  }
2249  else if ((cell->face(j)->boundary_id() == 37) ||
2250  (cell->face(j)->boundary_id() == 32) )
2251  {
2252  cell->face(j)->get_dof_indices(face_dofs);
2253  for (unsigned int k=0; k<fe.dofs_per_face; ++k)
2254  {
2255  if ( (right_boat_transom_point_id != face_dofs[k]) &&
2256  (left_boat_transom_point_id != face_dofs[k]) )
2257  {
2258  flags[face_dofs[k]] |= transom_on_boat;
2259  for (unsigned int p=0; p<3; ++p)
2260  vector_flags[3*face_dofs[k]+p] |= transom_on_boat;
2261  }
2262  }
2263  }
2264  }
2265  }
2266 
2267  }
2268 
2269  }
2270 
2271 
2272 }
2273 
2275 {
2276  if (surface_smoother)
2277  {
2279  }
2280  else
2281  {
2284  }
2286  {
2288  }
2289  else
2290  {
2292  vector_dh, *mapping);
2293  }
2294 
2295  if (line_smoothers.size() == 7)
2296  {
2297  if ( line_smoothers[0] )
2298  {
2299  update_smoother();
2300  }
2301  else
2302  {
2304  }
2305  }
2306 
2307 
2308 }
2309 
2311 {
2312 
2313 
2314 
2315 
2316  // The boundary dofs
2317  boundary_dofs.resize(7, vector<bool>(vector_dh.n_dofs(), false));
2318  // The boundary ids
2319  boundary_ids.resize(7);
2320 
2321  base_points.resize(7);
2322  moving_points.resize(7);
2323  base_point_ids.resize(7);
2324  moving_point_ids.resize(7);
2325 
2326  curves.resize(7);
2327  on_curve_option.resize(7);
2328  smoothers_locations.resize(7,NULL);
2329 
2330  // parameters for front keel smoothing
2333  curves[0] = boat_model.equiv_keel_bspline;
2334  boundary_ids[0] = 30;
2335  on_curve_option[0] = true;
2337 
2338  // parameters for rear keel/left transom smoothing
2339  if (boat_model.is_transom)
2340  {
2343  curves[1] = boat_model.left_transom_bspline;
2344  boundary_ids[1] = 32;
2345  on_curve_option[1] = true;
2347  }
2348  else
2349  {
2352  curves[1] = boat_model.equiv_keel_bspline;
2353  boundary_ids[1] = 32;
2354  on_curve_option[1] = true;
2356  }
2357 
2358  // parameters for rear keel/right transom smoothing
2359  if (boat_model.is_transom)
2360  {
2363  curves[2] = boat_model.right_transom_bspline;
2364  boundary_ids[2] = 37;
2365  on_curve_option[2] = true;
2367  }
2368  else
2369  {
2372  curves[2] = boat_model.equiv_keel_bspline;
2373  boundary_ids[2] = 32;
2374  on_curve_option[2] = true;
2376  }
2377 
2378  // parameters for front right water line smoothing
2381  curves[3] = boat_model.right_undisturbed_waterline_curve;
2382  boundary_ids[3] = 26;
2383  on_curve_option[3] = false;
2384 
2385  // parameters for front left water line smoothing
2388  curves[4] = boat_model.left_undisturbed_waterline_curve;
2389  boundary_ids[4] = 27;
2390  on_curve_option[4] = false;
2391 
2392  // parameters for rear right water line smoothing
2394  moving_points[5] = moving_points[2];
2395  curves[5] = boat_model.right_undisturbed_waterline_curve;
2396  boundary_ids[5] = 28;
2397  on_curve_option[5] = false;
2398 
2399  // parameters for rear left water line smoothing
2401  moving_points[6] = moving_points[1];
2402  curves[6] = boat_model.left_undisturbed_waterline_curve;
2403  boundary_ids[6] = 29;
2404  on_curve_option[6] = false;
2405 
2406 
2407  for (unsigned int i=0; i<7; ++i)
2408  {
2411  moving_point_ids[i] = find_point_id(moving_points[i], ref_points);
2412  std::set<unsigned int> duplicates = double_nodes_set[moving_point_ids[i]];
2413  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2414  {
2415  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
2416  if (boundary_dofs[i][3*(*pos)] == 1)
2417  {
2418  moving_point_ids[i] = *pos;
2419  break;
2420  }
2421  }
2422  duplicates = double_nodes_set[base_point_ids[i]];
2423  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2424  {
2425  //cout<<i<<" bpid "<<*pos<<" is in? "<<boundary_dofs[i][3*(*pos)]<<endl;
2426  if (boundary_dofs[i][3*(*pos)] == 1)
2427  {
2428  base_point_ids[i] = *pos;
2429  break;
2430  }
2431  }
2432  //cout<<"Base point "<<i<<" "<<base_points[i]<<" base_point_ids "<<base_point_ids[i]<<" "<<ref_points[3*base_point_ids[i]]<<endl;
2433  }
2434 
2435 
2436  for (unsigned int i=0; i<7; ++i)
2437  {
2438  double smoother_tolerance = boat_model.boatWetLength*1e-3;
2440  curves[i],
2442  vector_dh,
2443  boundary_dofs[i],
2444  base_point_ids[i],
2445  moving_point_ids[i],
2446  smoother_tolerance);
2447  }
2448 
2449 }
2450 
2451 
2452 
2454 {
2455 
2456 
2457  // parameters for front keel smoothing
2460  curves[0] = boat_model.equiv_keel_bspline;
2461  boundary_ids[0] = 30;
2462  on_curve_option[0] = true;
2464 
2465  // parameters for rear keel/left transom smoothing
2466  if (boat_model.is_transom)
2467  {
2470  curves[1] = boat_model.left_transom_bspline;
2471  boundary_ids[1] = 32;
2472  on_curve_option[1] = true;
2474  }
2475  else
2476  {
2479  curves[1] = boat_model.equiv_keel_bspline;
2480  boundary_ids[1] = 32;
2481  on_curve_option[1] = true;
2483  }
2484 
2485  // parameters for rear keel/right transom smoothing
2486  if (boat_model.is_transom)
2487  {
2490  curves[2] = boat_model.right_transom_bspline;
2491  boundary_ids[2] = 37;
2492  on_curve_option[2] = true;
2494  }
2495  else
2496  {
2499  curves[2] = boat_model.equiv_keel_bspline;
2500  boundary_ids[2] = 32;
2501  on_curve_option[2] = true;
2503  }
2504 
2505  // parameters for front right water line smoothing
2508  curves[3] = boat_model.right_undisturbed_waterline_curve;
2509  boundary_ids[3] = 26;
2510  on_curve_option[3] = false;
2511 
2512  // parameters for front left water line smoothing
2515  curves[4] = boat_model.left_undisturbed_waterline_curve;
2516  boundary_ids[4] = 27;
2517  on_curve_option[4] = false;
2518 
2519  // parameters for rear right water line smoothing
2521  moving_points[5] = moving_points[2];
2522  curves[5] = boat_model.right_undisturbed_waterline_curve;
2523  boundary_ids[5] = 28;
2524  on_curve_option[5] = false;
2525 
2526  // parameters for rear left water line smoothing
2528  moving_points[6] = moving_points[1];
2529  curves[6] = boat_model.left_undisturbed_waterline_curve;
2530  boundary_ids[6] = 29;
2531  on_curve_option[6] = false;
2532 
2533 
2534  for (unsigned int i=0; i<7; ++i)
2535  {
2536  //cout<<"Base point "<<i<<" "<<base_points[i]<<endl;
2539  moving_point_ids[i] = find_point_id(moving_points[i], ref_points);
2540  std::set<unsigned int> duplicates = double_nodes_set[moving_point_ids[i]];
2541  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2542  {
2543  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
2544  if (boundary_dofs[i][3*(*pos)] == 1)
2545  {
2546  moving_point_ids[i] = *pos;
2547  break;
2548  }
2549  }
2550  duplicates = double_nodes_set[base_point_ids[i]];
2551  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2552  {
2553  //cout<<i<<" bpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
2554  if (boundary_dofs[i][3*(*pos)] == 1)
2555  {
2556  base_point_ids[i] = *pos;
2557  break;
2558  }
2559  }
2560  }
2561 
2562  for (unsigned int i=0; i<7; ++i)
2563  {
2564  //cout<<"smoother "<<i<<endl;
2565  line_smoothers[i]->update_reference(base_point_ids[i],moving_point_ids[i]);
2566  }
2567 
2568 }
2569 
2570 
2571 
2572 void NumericalTowingTank::perform_line_smoothing(unsigned int num_smoothings)
2573 {
2574 
2575 //smoothing is done on a COPY of map_points
2577 
2578  // line smoothing is performed here
2579  for (unsigned int i=0; i<num_smoothings; ++i)
2580  {
2581  line_smoothers[i]->smooth(on_curve_option[i]);
2582  }
2583 
2584 
2586  // we update the support points
2588 
2589  // the smoothing moved all the right keel nodes: now
2590  // we loop over all the left keel nodes to move them
2591  // along with their right twins
2592  for (unsigned int k=0; k<num_smoothings; ++k)
2593  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2594  {
2595  if ( (boundary_dofs[k][3*i]) )
2596  {
2597  std::set<unsigned int> duplicates = vector_double_nodes_set[3*i];
2598  duplicates.erase(i);
2599  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2600  for (unsigned int j=0; j<3; ++j)
2601  map_points(*pos+j) += vector_support_points[3*i](j) - vector_support_points[*pos](j);
2602  }
2603  }
2604 
2605 
2606  /*
2607  // the smoothing moved all the boat water line nodes: now
2608  // we loop over all the free surface water line nodes to
2609  // move their horizontal componentsalong with their boat twins.
2610  // as for the vertical components, the free surface node rules,
2611  // so the vertical component of boat node is taken from that
2612  // of free surface node
2613  for (unsigned int k=2; k<6;++k)
2614  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2615  {
2616  if ( boundary_dofs[k][3*i])
2617  {
2618  std::set<unsigned int> duplicates = vector_double_nodes_set[3*i];
2619  duplicates.erase(i);
2620  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2621  {
2622  for (unsigned int j=0; j<2; ++j)
2623  map_points(*pos+j) += vector_support_points[3*i](j) - vector_support_points[*pos](j);
2624  map_points(3*i+2) += vector_support_points[*pos](2) - vector_support_points[3*i](2);
2625  }
2626  // duplicates = vector_double_nodes_set[3*i];
2627  // for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2628  // {
2629  // Point<3> p = ref_points[3*i];
2630  // for (unsigned int j=0; j<3; ++j)
2631  // p(j)+= map_points(*pos+j);
2632  // cout<<3*i<<" ("<<*pos<<") p("<<p<<")"<<" ref("<<ref_points[3*i]<<")"<<endl;
2633  // }
2634  }
2635  }
2636  */
2637 
2638 }
2639 
2640 
2641 
2643 {
2644  // we first update the vector of mesh normals at nodes
2646  // we update the vector with the support points
2648 
2649  std::pair<double,double> params;
2650  // we move all nodes of the right side of
2651  // the boat surface using the specified projection
2652  Point<3> proj_node;
2653  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2654  {
2655  if ( (flags[i] & boat) &&
2656  (flags[i] & right_side) &&
2657  ((flags[i] & edge)== 0) )
2658  {
2660  iges_normals[i],
2662  vector_support_points[3*i],
2663  node_normals[i]); // for projection in mesh normal direction
2664  for (unsigned int j=0; j<3; ++j)
2665  map_points(3*i+j) += proj_node(j) - vector_support_points[3*i](j);
2666  }
2667  }
2668 
2669  // we move all nodes of the left side of
2670  // the boat surface using the specified projection
2671  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2672  {
2673  if ( (flags[i] & boat) &&
2674  (flags[i] & left_side) &&
2675  ((flags[i] & edge)== 0) )
2676  {
2678  iges_normals[i],
2680  vector_support_points[3*i],
2681  node_normals[i]); // for projection in mesh normal direction
2682  //iges_normals[i]*=-1.0; // reflected shape has wrong orientation! we should change it instead of acting here
2683  //iges_mean_curvatures[i]*=-1.0;
2684  for (unsigned int j=0; j<3; ++j)
2685  map_points(3*i+j) += proj_node(j) - vector_support_points[3*i](j);
2686  }
2687  }
2688 
2689  /*
2690  // we also need to compute the normals and curvatures on the
2691  // keel nodes (right and left side)
2692  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2693  {
2694  if ( (flags[i] & keel) &&
2695  (flags[i] & right_side) )
2696  {
2697  boat_model.boat_surface_right->normal_projection_and_diff_forms(proj_node,
2698  iges_normals[i],
2699  iges_mean_curvatures[i],
2700  vector_support_points[3*i]); // for projection in surface normal direction
2701  }
2702  }
2703  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2704  {
2705  if ( (flags[i] & keel) &&
2706  (flags[i] & left_side) )
2707  {
2708  boat_model.boat_surface_left->normal_projection_and_diff_forms(proj_node,
2709  iges_normals[i],
2710  iges_mean_curvatures[i],
2711  vector_support_points[3*i]); // for projection in surface normal direction
2712  //iges_normals[i]*=-1.0; // reflected shape has wrong orientation! we should change it instead of acting here
2713  //iges_mean_curvatures[i]*=-1.0;
2714  //cout<<"node ("<<vector_support_points[3*i]<<") proj("<<proj_node<<endl;
2715  //cout<<"normal ("<<iges_normals[i]<<") curvature "<<iges_mean_curvatures[i]<<endl;
2716  }
2717  }
2718  */
2719 }
2720 
2721 
2723 {
2724  // we update the vector with the support points
2726 
2727  // we move all nodes of the right side of
2728  // the water line on the boat surface
2729  Point<3> proj_node;
2730  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2731  {
2732  if ( (flags[i] & water) &&
2733  (flags[i] & near_boat) &&
2734  (flags[i] & right_side) &&
2735  !(flags[i] & transom_on_water) &&
2736  (moving_point_ids[3] != i) &&
2737  (moving_point_ids[4] != i) &&
2738  (moving_point_ids[5] != i) &&
2739  (moving_point_ids[6] != i) ) // to avoid the bow and stern node
2740  {
2742  iges_normals[i],
2744  vector_support_points[3*i]); // y axis projection
2745  //cout<<i<<" (rw) --> dist "<<proj_node.distance(vector_support_points[3*i])<<" ("<<proj_node<<") Vs ("<<vector_support_points[3*i]<<")"<<endl;
2746  // " + n("<<iges_normals[i]<<")"<<endl;
2747  std::set<unsigned int> duplicates = vector_double_nodes_set[3*i];
2748  for (std::set<unsigned int>::iterator pos=duplicates.begin(); pos!=duplicates.end(); pos++)
2749  for (unsigned int j=0; j<3; ++j)
2750  map_points(*pos+j) += proj_node(j) - vector_support_points[*pos](j);
2751  }
2752  }
2753 
2754  // we move all nodes of the left side of
2755  // the water line on the boat surface
2756  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2757  {
2758  if ( (flags[i] & water) &&
2759  (flags[i] & near_boat) &&
2760  (flags[i] & left_side) &&
2761  !(flags[i] & transom_on_water) &&
2762  (moving_point_ids[3] != i) &&
2763  (moving_point_ids[4] != i) &&
2764  (moving_point_ids[5] != i) &&
2765  (moving_point_ids[6] != i) ) // to avoid the bow and stern node
2766  {
2768  iges_normals[i],
2770  vector_support_points[3*i]); // y axis direction projection
2771  //cout<<i<<" (lw) --> dist "<<proj_node.distance(vector_support_points[3*i])<<" ("<<proj_node<<") Vs ("<<vector_support_points[3*i]<<")"<<endl;
2772  // " + n("<<iges_normals[i]<<")"<<endl;
2773  std::set<unsigned int> duplicates = vector_double_nodes_set[3*i];
2774  for (std::set<unsigned int>::iterator pos=duplicates.begin(); pos!=duplicates.end(); pos++)
2775  for (unsigned int j=0; j<3; ++j)
2776  map_points(*pos+j) += proj_node(j) - vector_support_points[*pos](j);
2777  }
2778  }
2779 
2780 }
2781 
2782 
2783 void NumericalTowingTank::evaluate_ref_surf_distances(Vector <double> &distances,
2784  const bool only_surf_smoothing)
2785 {
2786  cout<<"Evaluating boat surf distances"<<endl;
2787  // we update the vector with the support points
2789  // we now update the vector of mesh normals at nodes
2790  // using the current geometry
2792 
2793 //we work on a COPY of map_points
2795 
2796 
2797 //we enforce contraint on the new geometry assigned by the DAE solver
2799 
2801 //this takes care of the bow and stern nodes
2802  if (only_surf_smoothing == false)
2803  for (unsigned int k=3; k<7; ++k)
2804  {
2805  unsigned int i = moving_point_ids[k];
2806  {
2807  Point <3> dP0 = support_points[i];
2808  Point <3> dP;
2809  //this is the horizontal plane
2810  Handle(Geom_Plane) horPlane = new Geom_Plane(0.,0.,1.,-dP0(2));
2811  Handle(Geom_Curve) curve;
2812  TopLoc_Location L = boat_model.current_loc;
2813  TopLoc_Location L_inv = L.Inverted();
2814 
2815  horPlane->Transform(L_inv.Transformation());
2816  if (boat_model.is_transom)
2817  {
2818  if (k==3 || k==4)
2819  curve = boat_model.equiv_keel_bspline;
2820  else if (k == 6)
2821  curve = boat_model.left_transom_bspline;
2822  else
2823  curve = boat_model.right_transom_bspline;
2824  }
2825  else
2826  {
2827  curve = boat_model.equiv_keel_bspline;
2828  }
2829 
2830  TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve);
2831  edge.Location(L);
2832  BRepAdaptor_Curve AC(edge);
2833  gp_Pnt P;
2834  gp_Vec V1;
2835  GeomAPI_IntCS Intersector(curve, horPlane);
2836  int npoints = Intersector.NbPoints();
2837 
2838  AssertThrow((npoints != 0), ExcMessage("Keel or transom curve is not intersecting with horizontal plane!"));
2839  double minDistance=1e7;
2840  double t,u,v;
2841  for (int j=0; j<npoints; ++j)
2842  {
2843  gp_Pnt int_point = Intersector.Point(j+1);
2844  int_point.Transform(L.Transformation());
2845  Point<3> inters = Pnt(int_point);
2846  Intersector.Parameters(j+1,u,v,t);
2847  if (dP0.distance(inters) < minDistance)
2848  {
2849  minDistance = dP0.distance(inters);
2850  dP = inters;
2851  AC.D1(t,P,V1);
2852  }
2853  }
2854  //cout<<"Check plane-curve intersection:"<<endl;
2855  //cout<<"Origin: "<<dP0<<" Proj: "<<dP<<" dist: "<<minDistance<<endl;
2856  //cout<<Pnt(P)<<endl;
2857  /*
2858  // here temporarily for kcs hull tests
2859  if (minDistance > 0.5*boat_model.boatWetLength)
2860  {
2861  Standard_Real First = curve->FirstParameter();
2862  Standard_Real Last = curve->LastParameter();
2863  gp_Pnt PIn(0.0,0.0,0.0);
2864  gp_Pnt PFin(0.0,0.0,0.0);
2865  gp_Vec VIn;
2866  gp_Vec VFin;
2867  curve->D1(First,PIn,VIn);
2868  curve->D1(Last,PFin,VFin);
2869  cout<<"New part one: "<<Pnt(PIn)<<" | "<<Pnt(PFin)<<endl;
2870  if (dP0.distance(Pnt(PIn)) < dP0.distance(Pnt(PFin)))
2871  {
2872  double delta_z = dP0(2) - PIn.Z();
2873  dP = Point<3>(PIn.X()+delta_z*VIn.X()/VIn.Z(),PIn.Y()+delta_z*VIn.Y()/VIn.Z(),dP0(2));
2874  V1 = VIn;
2875  }
2876  else
2877  {
2878  double delta_z = dP0(2) - PFin.Z();
2879  dP = Point<3>(PFin.X()+delta_z*VFin.X()/VFin.Z(),PIn.Y()+delta_z*VFin.Y()/VFin.Z(),dP0(2));
2880  V1 = VFin;
2881  }
2882  cout<<"New part two: "<<dP<<" | "<<V1.X()<<" "<<V1.Y()<<" "<<V1.Z()<<" | "<<dP0<<endl;
2883  }
2884  */
2885  std::set<unsigned int> duplicates = double_nodes_set[i];
2886  //duplicates.erase(i);
2887  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2888  {
2889  smoothing_map_points(3*(*pos)) = dP(0)-ref_points[3*(*pos)](0);
2890  smoothing_map_points(3*(*pos)+1) = dP(1)-ref_points[3*(*pos)](1);
2891  smoothing_map_points(3*(*pos)+2) = dP(2)-ref_points[3*(*pos)](2);
2892  edges_tangents[3*(*pos)] = V1.X();
2893  edges_tangents[3*(*pos)+1] = V1.Y();
2894  edges_tangents[3*(*pos)+2] = V1.Z();
2895  //cout<<*pos<<" "<<i<<" "<<smoothing_map_points(3*i)<<" vs "<<map_points(3*i)<<" ("<<vector_support_points[3*i]<<")"<<endl;
2896  }
2897 
2898  }
2899  }
2900 
2901 
2902 // this cycle hooks the boat and far field double nodes
2903 // to their water twins that have been moved
2904  if (only_surf_smoothing == false)
2905  for (unsigned int i=0; i<vector_dh.n_dofs(); ++i)
2906  {
2907  if ( (vector_flags[i] & water) &&
2908  (vector_flags[i] & edge) )
2909  {
2910  std::set<unsigned int> duplicates = vector_double_nodes_set[i];
2911  duplicates.erase(i);
2912  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2913  {
2915  }
2916  }
2917  }
2918 
2920  // line smoothing on keel/transom is performed here and modifies smoothing_map_points
2921  // it ONLY moves nodes on the LEFT side of the keel
2922  for (unsigned int i=0; i<3; ++i)
2923  {
2924  line_smoothers[i]->smooth(on_curve_option[i]);
2925  line_smoothers[i]->get_curve_tangent_vectors_at_smoothing_dofs(edges_tangents);
2926  line_smoothers[i]->get_curve_length_ratios_at_smoothing_dofs(edges_length_ratios);
2927 
2928  for (unsigned int j=0; j<vector_dh.n_dofs(); ++j)
2929  if (boundary_dofs[i][j])
2930  {
2931  std::set<unsigned int> duplicates = vector_double_nodes_set[j];
2932  //duplicates.erase(j);
2933  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2934  {
2935  //cout<<*pos<<" "<<smoothing_map_points(*pos)<<" "<<j<<" "<<smoothing_map_points(j)<<endl;
2937  edges_tangents(*pos) = edges_tangents(j);
2939  }
2940 
2941  }
2942  }
2943  // line smoothing on water_lines is performed here and modifies smoothing_map_points
2944  // it ONLY moves nodes on the water that are also near_boat
2945  if (only_surf_smoothing == false)
2946  for (unsigned int i=3; i<7; ++i)
2947  {
2948  line_smoothers[i]->smooth(on_curve_option[i]);
2949  line_smoothers[i]->get_curve_tangent_vectors_at_smoothing_dofs(edges_tangents);
2950  line_smoothers[i]->get_curve_length_ratios_at_smoothing_dofs(edges_length_ratios);
2951  }
2952 
2953 
2954  // we move all nodes of the right side of
2955  // the water line on the boat surface
2956  Point<3> proj_node;
2957  if (only_surf_smoothing == false)
2958  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2959  {
2960  if ( (flags[i] & water) &&
2961  (flags[i] & near_boat) &&
2962  (flags[i] & right_side) &&
2963  !(flags[i] & transom_on_water) &&
2964  (moving_point_ids[3] != i) &&
2965  (moving_point_ids[4] != i) &&
2966  (moving_point_ids[5] != i) &&
2967  (moving_point_ids[6] != i) ) // to avoid the bow and stern node
2968  {
2969  Point<3> intermadiate_point_pos(ref_points[3*i](0)+smoothing_map_points(3*i),
2970  ref_points[3*i](1)+smoothing_map_points(3*i+1),
2971  ref_points[3*i](2)+smoothing_map_points(3*i+2));
2972 
2973  Point<3> direction(iges_normals[i](0),iges_normals[i](1),0.0);
2974  if (direction.square() < 1e-3)
2975  {
2976  std::set<unsigned int> duplicates = double_nodes_set[i];
2977  duplicates.erase(i);
2978  unsigned int j = *(duplicates.begin());
2979  direction(0) = node_normals[j](0);
2980  direction(1) = node_normals[j](1);
2981  direction(2) = 0.0;
2982  }
2983  //cout<<i<<"(rw) --> ("<<intermadiate_point_pos<<") and ("<<direction<<")"<<endl;
2985  iges_normals[i],
2987  intermadiate_point_pos,
2988  direction); // hor normal dir projection
2989  //cout<<i<<"(rw) --> ("<<proj_node<<") Vs ("<<vector_support_points[3*i]<<") + n("<<iges_normals[i]<<")"<<endl;
2990  //cout<<i<<"(rw) --> ("<<proj_node<<") Vs ("<<intermadiate_point_pos<<")"<<endl;
2991  for (unsigned int j=0; j<2; ++j)
2992  smoothing_map_points(3*i+j) = proj_node(j) - ref_points[3*i](j);
2993  // we're doing this thing on the water side, but the iges_normal and iges_mean curvature belong to the boat side
2994  std::set<unsigned int> duplicates = double_nodes_set[i];
2995  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
2996  {
2997  iges_normals[*pos] = iges_normals[i];
2999  }
3000  //iges_normals[i] = Point<3>(0.0,0.0,0.0);
3001  //iges_mean_curvatures[i] = 0;
3002  }
3003  }
3004 
3005  // we move all nodes of the left side of
3006  // the water line on the boat surface
3007  if (only_surf_smoothing == false)
3008  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3009  {
3010  if ( (flags[i] & water) &&
3011  (flags[i] & near_boat) &&
3012  (flags[i] & left_side) &&
3013  !(flags[i] & transom_on_water) &&
3014  (moving_point_ids[3] != i) &&
3015  (moving_point_ids[4] != i) &&
3016  (moving_point_ids[5] != i) &&
3017  (moving_point_ids[6] != i) ) // to avoid the bow and stern node
3018  {
3019  Point<3> intermadiate_point_pos(ref_points[3*i](0)+smoothing_map_points(3*i),
3020  ref_points[3*i](1)+smoothing_map_points(3*i+1),
3021  ref_points[3*i](2)+smoothing_map_points(3*i+2));
3022  Point<3> direction(iges_normals[i](0),iges_normals[i](1),0.0);
3023  if (direction.square() < 1e-3)
3024  {
3025  std::set<unsigned int> duplicates = double_nodes_set[i];
3026  duplicates.erase(i);
3027  unsigned int j = *(duplicates.begin());
3028  direction(0) = node_normals[j](0);
3029  direction(1) = node_normals[j](1);
3030  direction(2) = 0.0;
3031  }
3033  iges_normals[i],
3035  intermadiate_point_pos,
3036  direction); // hor normal dir projection
3037  //cout<<i<<"(lw) --> ("<<proj_node<<") Vs ("<<vector_support_points[3*i]<<") + n("<<iges_normals[i]<<")"<<endl;
3038  for (unsigned int j=0; j<2; ++j)
3039  smoothing_map_points(3*i+j) = proj_node(j) - ref_points[3*i](j);
3040  // we're doing this thing on the water side, but the iges_normal and iges_mean curvature belong to the boat side
3041  std::set<unsigned int> duplicates = double_nodes_set[i];
3042  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
3043  {
3044  iges_normals[*pos] = iges_normals[i];
3046  }
3047  //iges_normals[i] = Point<3>(0.0,0.0,0.0);
3048  //iges_mean_curvatures[i] = 0;
3049  }
3050  }
3051 
3052 // this cycle hooks the boat and far field double nodes
3053 // to their water twins that have been moved
3054  if (only_surf_smoothing == false)
3055  for (unsigned int i=0; i<vector_dh.n_dofs(); ++i)
3056  {
3057  if ( (vector_flags[i] & water) &&
3058  (vector_flags[i] & edge) )
3059  {
3060  std::set<unsigned int> duplicates = vector_double_nodes_set[i];
3061  duplicates.erase(i);
3062  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
3063  {
3065  }
3066  }
3067  }
3068 // the line treatment (smoothing and projection) part is finished here
3069 
3070 
3071  // surface treatment starts here: before doing the smoothing
3072  // we must project all nodes on the boat surface to obtain
3073  // the normals and curvatures of the surface
3074 
3075  // we move all nodes of the right side of
3076  // the boat surface using the specified projection
3077  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3078  {
3079  if ( (flags[i] & boat) &&
3080  (flags[i] & right_side) &&
3081  ((flags[i] & edge)== 0))
3082  {
3083  Point<3> intermediate_point_pos = ref_points[3*i] +
3085  bool succeed =
3087  iges_normals[i],
3089  intermediate_point_pos,
3090  node_normals[i]); // for projection in mesh normal direction
3091  if (succeed == false)
3093  iges_normals[i],
3095  intermediate_point_pos); // for projection in normal direction
3096 
3097  for (unsigned int j=0; j<3; ++j)
3098  smoothing_map_points(3*i+j) = proj_node(j) - ref_points[3*i](j);
3099  }
3100  }
3101  // we move all nodes of the left side of
3102  // the boat surface using the specified projection
3103  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3104  {
3105  if ( (flags[i] & boat) &&
3106  (flags[i] & left_side) &&
3107  ((flags[i] & edge)== 0))
3108  {
3109  Point<3> intermediate_point_pos = ref_points[3*i] +
3111  bool succeed =
3113  iges_normals[i],
3115  intermediate_point_pos,
3116  node_normals[i]); // for projection in mesh normal direction
3117  if (succeed == false)
3119  iges_normals[i],
3121  intermediate_point_pos); // for projection in normal direction
3122 
3123  for (unsigned int j=0; j<3; ++j)
3124  smoothing_map_points(3*i+j) = proj_node(j) - ref_points[3*i](j);
3125  }
3126  }
3127 
3128 
3129  // with all the normals and curvatures we assemble the vector
3130  // used by the smoothing
3131  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
3132  {
3133  if ((boundary_dofs[0][3*i] == false) &&
3134  (boundary_dofs[1][3*i] == false) &&
3135  (boundary_dofs[2][3*i] == false) &&
3136  (boundary_dofs[3][3*i] == false) &&
3137  (boundary_dofs[4][3*i] == false) &&
3138  (boundary_dofs[5][3*i] == false) &&
3139  (boundary_dofs[6][3*i] == false))
3140  {
3141  for (unsigned int j=0; j<3; ++j)
3142  {
3144  //cout<<"smooth("<<3*i+j<<") = "<<smoothing_curvature_vector(3*i+j)<<endl;
3145  }
3146  }
3147  }
3148 
3149 // we perform the surface smoothing
3152 
3154 
3155 
3156 // this cycle is needed because surface smoothing
3157 // on free surface must not be effective
3158  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3159  {
3160  if ( (flags[i] & water) &&
3161  ((flags[i] & edge)== 0) )
3162  {
3163  smoothing_map_points(3*i) = map_points(3*i);
3164  smoothing_map_points(3*i+1) = map_points(3*i+1);
3165  smoothing_map_points(3*i+2) = map_points(3*i+2);
3166  }
3167  }
3168 
3169 // here we decide if free surface smoothing is active also on boat
3170 // nodes
3171 // for (unsigned int i=0; i<dh.n_dofs(); ++i)
3172 // {
3173 // if ( (flags[i] & boat) &&
3174 // ((flags[i] & edge)== 0) )
3175 // {
3176 // smoothing_map_points(3*i) = map_points(3*i);
3177 // smoothing_map_points(3*i+1) = map_points(3*i+1);
3178 // smoothing_map_points(3*i+2) = map_points(3*i+2);
3179 // }
3180 // }
3181  // we move all nodes of the right side of
3182  // the boat surface using the specified projection
3183  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3184  {
3185  if ( (flags[i] & boat) &&
3186  (flags[i] & right_side) &&
3187  ((flags[i] & edge)== 0))
3188  {
3189  Point<3> intermediate_point_pos = ref_points[3*i] +
3191  bool succeed =
3193  iges_normals[i],
3195  intermediate_point_pos,
3196  node_normals[i]); // for projection in mesh normal direction
3197  if (succeed == false)
3199  iges_normals[i],
3201  intermediate_point_pos); // for projection in normal direction
3202  for (unsigned int j=0; j<3; ++j)
3203  smoothing_map_points(3*i+j) = proj_node(j) - ref_points[3*i](j);
3204  }
3205  }
3206  // we move all nodes of the left side of
3207  // the boat surface using the specified projection
3208  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3209  {
3210  if ( (flags[i] & boat) &&
3211  (flags[i] & left_side) &&
3212  ((flags[i] & edge)== 0))
3213  {
3214  Point<3> intermediate_point_pos = ref_points[3*i] +
3216  bool succeed =
3218  iges_normals[i],
3220  intermediate_point_pos,
3221  node_normals[i]); // for projection in mesh normal direction
3222  if (succeed == false)
3224  iges_normals[i],
3226  intermediate_point_pos); // for projection in normal direction
3227 
3228  for (unsigned int j=0; j<3; ++j)
3229  smoothing_map_points(3*i+j) = proj_node(j) - ref_points[3*i](j);
3230  }
3231  }
3232  // we also need to compute the normals and curvatures on the
3233  // keel nodes (right and left side)
3234  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3235  {
3236  if ( (flags[i] & keel) &&
3237  (flags[i] & right_side) )
3238  {
3239  Point<3> intermediate_point_pos = ref_points[3*i] +
3242  iges_normals[i],
3244  intermediate_point_pos); // for projection in surface normal direction
3245  }
3246  }
3247 
3248  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3249  {
3250  if ( (flags[i] & keel) &&
3251  (flags[i] & left_side) )
3252  {
3253  Point<3> intermediate_point_pos = ref_points[3*i] +
3256  iges_normals[i],
3258  intermediate_point_pos); // for projection in surface normal direction
3259  }
3260  }
3261 //*/
3262 
3263 
3264  Vector<double> xyz_coordinates(vector_dh.n_dofs());
3265 
3266  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3267  {
3268  xyz_coordinates(3*i) = ref_points[3*i](0)+smoothing_map_points(3*i);
3269  xyz_coordinates(3*i+1) = ref_points[3*i](1)+smoothing_map_points(3*i+1);
3270  xyz_coordinates(3*i+2) = ref_points[3*i](2)+smoothing_map_points(3*i+2);
3271  }
3272 
3273  vector_constraints.distribute(xyz_coordinates);
3274 
3275  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3277  {
3278  smoothing_map_points(3*i) = xyz_coordinates(3*i) - ref_points[3*i](0);
3279  smoothing_map_points(3*i+1) = xyz_coordinates(3*i+1) - ref_points[3*i](1);
3280  smoothing_map_points(3*i+2) = xyz_coordinates(3*i+2) - ref_points[3*i](2);
3281  }
3282 
3283 //vector_constraints.distribute(smoothing_map_points);
3284  distances = smoothing_map_points;
3285 
3286 
3287  distances*=-1;
3288 
3289  distances.add(map_points);
3290 
3293  cout<<"Done evaluating boat surf distances"<<endl;
3294 
3295 
3296 
3297 }
3298 
3299 
3300 void NumericalTowingTank::perform_smoothing(bool full_treatment, const double blend_factor)
3301 {
3302  if (!no_boat)
3303  {
3304  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
3305  {
3306  if ( (boundary_dofs[0][3*i] == false) &&
3307  (boundary_dofs[1][3*i] == false) &&
3308  (boundary_dofs[2][3*i] == false) &&
3309  (boundary_dofs[3][3*i] == false) &&
3310  (boundary_dofs[4][3*i] == false) &&
3311  (boundary_dofs[5][3*i] == false) &&
3312  (boundary_dofs[6][3*i] == false) )
3313  {
3314  for (unsigned int j=0; j<3; ++j)
3315  {
3317  }
3318  }
3319  }
3320  }
3321  //smoothing is done on a COPY of map_points
3324  // if we are on the free surface, only horizontal components of map_points must be changed
3325  // according to the smoothing (the third one will be changed according to the free surface differential
3326  // equation). otherwise, all three components are updated
3327 
3328  if (full_treatment)
3329  {
3330  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
3331  {
3332  if ((flags[i] & water) == 0)
3333  {
3334  map_points(3*i) = smoothing_map_points(3*i);
3335  map_points(3*i+1) = smoothing_map_points(3*i+1);
3336  map_points(3*i+2) = smoothing_map_points(3*i+2);
3337  }
3338  }
3339  }
3340  else
3341  {
3342  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
3343  {
3344  if ( (flags[i] & water) &&
3345  ((flags[i] & edge) == 0) )
3346  {
3347  map_points(3*i) = old_map_points(3*i) + blend_factor*(smoothing_map_points(3*i)-old_map_points(3*i));
3348  map_points(3*i+1) = old_map_points(3*i+1) + blend_factor*(smoothing_map_points(3*i+1)-old_map_points(3*i+1));
3349  }
3350  }
3351  }
3352 
3353 
3354 
3355 }
3356 
3357 
3359 {
3360 
3364 
3365  MappingQEulerian<2, Vector<double>, 3> mappingg(mapping_degree, map_points_used, vector_dh);
3366 
3367  FEValues<2,3> vector_fe_v(mappingg, vector_fe, *quadrature,
3368  update_values | update_cell_normal_vectors |
3369  update_JxW_values);
3370 
3371  const unsigned int vector_n_q_points = vector_fe_v.n_quadrature_points;
3372  const unsigned int vector_dofs_per_cell = vector_fe.dofs_per_cell;
3373  std::vector<unsigned int> vector_local_dof_indices (vector_dofs_per_cell);
3374 
3375  FullMatrix<double> local_normals_matrix (vector_dofs_per_cell, vector_dofs_per_cell);
3376  Vector<double> local_normals_rhs (vector_dofs_per_cell);
3377 
3378  cell_it
3379  vector_cell = vector_dh.begin_active(),
3380  vector_endc = vector_dh.end();
3381 
3382  for (; vector_cell!=vector_endc; ++vector_cell)
3383  {
3384  vector_fe_v.reinit (vector_cell);
3385  local_normals_matrix = 0;
3386  local_normals_rhs = 0;
3387  const std::vector<Point<3> > &vector_node_normals = vector_fe_v.get_normal_vectors();
3388  unsigned int comp_i, comp_j;
3389 
3390  for (unsigned int q=0; q<vector_n_q_points; ++q)
3391  for (unsigned int i=0; i<vector_dofs_per_cell; ++i)
3392  {
3393  comp_i = vector_fe.system_to_component_index(i).first;
3394  for (unsigned int j=0; j<vector_dofs_per_cell; ++j)
3395  {
3396  comp_j = vector_fe.system_to_component_index(j).first;
3397  if (comp_i == comp_j)
3398  {
3399  local_normals_matrix(i,j) += vector_fe_v.shape_value(i,q)*
3400  vector_fe_v.shape_value(j,q)*
3401  vector_fe_v.JxW(q);
3402  }
3403  }
3404  local_normals_rhs(i) += (vector_fe_v.shape_value(i, q)) *
3405  vector_node_normals[q](comp_i) * vector_fe_v.JxW(q);
3406  }
3407 
3408  vector_cell->get_dof_indices (vector_local_dof_indices);
3409 
3411  (local_normals_matrix,
3412  local_normals_rhs,
3413  vector_local_dof_indices,
3416  }
3417 
3418  SparseDirectUMFPACK normals_inverse;
3419  normals_inverse.initialize(vector_normals_matrix);
3422 
3423  node_normals.clear();
3424  node_normals.resize(dh.n_dofs());
3425  for (unsigned int i=0; i<vector_dh.n_dofs()/3; ++i)
3427  vector_normals_solution(3*i+1),
3428  vector_normals_solution(3*i+2));
3429 
3430 
3431 }
3432 
3433 
3434 
3435 
3437 {
3438 
3439  // we start clearing the constraint matrices
3440  cc.clear();
3441 
3442  // here we prepare the constraint matrices so as to account for the presence hanging
3443  // nodes
3445 
3446  cc.close();
3447 }
3448 
3449 
3450 // in the first layer of water cells past
3451 // the transom there can't be hanging nodes:
3452 // this method removes them
3454 {
3455  cout<<"Removing hanging nodes from transom stern..."<<endl;
3456 
3457  cout<<"dofs before: "<<dh.n_dofs()<<endl;
3458 
3459  unsigned int refinedCellCounter = 1;
3460  unsigned int cycles_counter = 0;
3461  while (refinedCellCounter)
3462  {
3463  refinedCellCounter = 0;
3464  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3465  {
3466  if ((flags[i] & transom_on_water) )
3467  //if ((flags[i] & water) && (flags[i] & near_boat))
3468  {
3469  //cout<<i<<": "<<support_points[i]<<endl;
3470  std::vector<cell_it> cells = dof_to_elems[i];
3471  for (unsigned int k=0; k<cells.size(); ++k)
3472  {
3473  //cout<<k<<": "<<cells[k]<<" ("<<cells[k]->center()<<")"<<endl;
3474  for (unsigned int j=0; j<GeometryInfo<2>::faces_per_cell; ++j)
3475  {
3476  //cout<<"j: "<<j<<" nb: "<<cells[k]->neighbor_index(j)<<" ("<<endl;
3477  if (cells[k]->neighbor_index(j) != -1)
3478  if (cells[k]->neighbor(j)->at_boundary() && cells[k]->neighbor_is_coarser(j))
3479  {
3480  //cout<<"FOUND: "<<cells[k]->neighbor(j)<<" ("<<cells[k]->neighbor(j)->center()<<")"<<endl;
3481  cells[k]->neighbor(j)->set_refine_flag();
3482  refinedCellCounter++;
3483  //cout<<"Cycle: "<<cycles_counter<<" Refined Cells: "<<refinedCellCounter<<endl;
3484  }
3485  }
3486  }
3487  }
3488  }
3489  cycles_counter++;
3490  if (cycles_counter > 20)
3491  {
3492  cout<<"Warning! Maximum number of transom stern edge uniforming cycles reached!"<<endl;
3493  break;
3494  }
3495 
3496  //cout<<"refinedCellCounter "<<refinedCellCounter<<endl;
3500 
3506  ref_points.resize(vector_dh.n_dofs());
3507  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3510  make_edges_conformal(true);
3511  make_edges_conformal(true);
3513  cycles_counter++;
3514  }
3515 //*/
3516  cout<<"dofs after: "<<dh.n_dofs()<<endl;
3517  cout<<"...Done removing hanging nodes from transom stern"<<endl;
3518 }
3519 
3520 
3521 
3522 // this routine detects if mesh is not
3523 // conformal at edges (because of double
3524 // nodes) and makes the refinements needed
3525 // to make it conformal
3526 void NumericalTowingTank::make_edges_conformal(bool isotropic_ref_on_opposite_side)
3527 {
3528  cout<<"Restoring mesh conformity..."<<endl;
3529 
3530  cout<<"dofs before: "<<dh.n_dofs()<<endl;
3531 
3532  double tol=1e-7;
3533  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3534  {
3535  if ((flags[i] & edge) &&
3536  (double_nodes_set[i].size() == 1) )
3537  {
3538  //we identify here the two vertices of the parent cell on the considered side
3539  //(which is the one with the non conformal node)
3540  vector<Point<3> > nodes(2);
3541  for (unsigned int kk=0; kk<2; ++kk)
3542  {
3544  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
3545  {
3546  if (cell->face(f)->at_boundary())
3547  {
3548  if (ref_points[3*i].distance(cell->face(f)->vertex(0)) <tol)
3549  nodes[kk] = cell->face(f)->vertex(1);
3550  else if (ref_points[3*i].distance(cell->face(f)->vertex(1)) <tol)
3551  nodes[kk] = cell->face(f)->vertex(0);
3552  }
3553  }
3554  }
3555  // we can now compute the center of the parent cell face
3556  Point<3> parent_face_center = 0.5*(nodes[0]+nodes[1]);
3557  // now we look for the opposite side cell that has a face on an edge, having the same center
3558  DoFHandler<2,3>::cell_iterator cell1 = dof_to_elems[i][0]->parent();
3559  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
3560  if (cell1->face(f)->at_boundary())
3561  {
3562  for (std::set<tria_it>::iterator jt=edge_cells.begin(); jt != edge_cells.end(); ++jt)
3563  for (unsigned int d=0; d<GeometryInfo<2>::faces_per_cell; ++d)
3564  if ((*jt)->face(d)->at_boundary())
3565  if ( parent_face_center.distance(((*jt)->face(d)->vertex(0)+(*jt)->face(d)->vertex(1))/2) < tol)
3566  {
3567  // if we are on wall or free surf, use isotropic refinement
3568  if ( isotropic_ref_on_opposite_side )//(*jt)->material_id() == free_sur_ID1 ||
3569  //(*jt)->material_id() == free_sur_ID2 ||
3570  //(*jt)->material_id() == free_sur_ID3 ||
3571  //(*jt)->material_id() == wall_sur_ID1 ||
3572  //(*jt)->material_id() == wall_sur_ID2 ||
3573  //(*jt)->material_id() == wall_sur_ID3 )
3574  (*jt)->set_refine_flag();
3575  // otherwise, use anisotropic refinement to make edge mesh conformal
3576  else
3577  {
3578  if ((d==0) || (d==1))
3579  (*jt)->set_refine_flag(RefinementCase<2>::cut_axis(1));
3580  else
3581  (*jt)->set_refine_flag(RefinementCase<2>::cut_axis(0));
3582  }
3583  }
3584  }
3585  }
3586  }
3587 
3588  //std::cout << "Refined counter: " << refinedCellCounter << std::endl;
3597  ref_points.resize(vector_dh.n_dofs());
3598  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3602 
3603  cout<<"dofs after: "<<dh.n_dofs()<<endl;
3604  cout<<"...Done restoring mesh conformity"<<endl;
3605 }
3606 // this routine detects if mesh elements have
3607 // high aspect ratio and performs anisotropic
3608 // refinements until all aspect ratios are below 1.5
3609 
3611 {
3613  cell = tria.begin_active(), endc = tria.end();
3614  unsigned int refinedCellCounter = 1;
3615  unsigned int cycles_counter = 0;
3616  while (refinedCellCounter)
3617  {
3618  refinedCellCounter = 0;
3619  for (cell=tria.begin_active(); cell!= endc; ++cell)
3620  {
3621  //if ( cell->material_id() == free_sur_ID1 ||
3622  // cell->material_id() == free_sur_ID2 ||
3623  // cell->material_id() == free_sur_ID3 )//( cell->center().distance(Point<3>(0.0,0.0,0.0)) <
3624  // fmax(6.0*boat_model.boatWetLength/pow(2.0,double(cycles_counter)),boat_model.boatWetLength) )
3625  // {
3626  if (cell->extent_in_direction(0) > max_aspect_ratio*cell->extent_in_direction(1))
3627  {
3628  cell->set_refine_flag(RefinementCase<2>::cut_axis(0));
3629  refinedCellCounter++;
3630  }
3631  else
3632  {
3633  if (cell->extent_in_direction(1) >max_aspect_ratio*cell->extent_in_direction(0))
3634  {
3635  cell->set_refine_flag(RefinementCase<2>::cut_axis(1));
3636  refinedCellCounter++;
3637  }
3638  }
3639  // }
3640  }
3641  //cout<<refinedCellCounter<<endl;
3645 
3651  ref_points.resize(vector_dh.n_dofs());
3652  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3655 
3656 
3657  make_edges_conformal(false);
3658  make_edges_conformal(false);
3659  make_edges_conformal(false);
3661  cycles_counter++;
3662 
3663  //std::string filename = ( "meshResult_" +
3664  // Utilities::int_to_string(int(round(cycles_counter))) +
3665  // ".inp" );
3666  //std::ofstream logfile(filename.c_str());
3667  //GridOut grid_out;
3668  //grid_out.write_ucd(tria, logfile);
3669 
3670  }
3671 
3672  /*
3673  cell = tria.begin_active();
3674  refinedCellCounter = 1;
3675  cycles_counter = 0;
3676  while(refinedCellCounter)
3677  {
3678  refinedCellCounter = 0;
3679  for (cell=tria.begin_active(); cell!= endc;++cell)
3680  {
3681  if ( cell->material_id() == free_sur_ID1 ||
3682  cell->material_id() == free_sur_ID2 ||
3683  cell->material_id() == free_sur_ID3 )//( cell->center().distance(Point<3>(0.0,0.0,0.0)) <
3684  // fmax(6.0*boat_model.boatWetLength/pow(2.0,double(cycles_counter)),boat_model.boatWetLength) )
3685  {
3686  if (cell->extent_in_direction(0) > max_aspect_ratio*cell->extent_in_direction(1))
3687  {
3688  cell->set_refine_flag(RefinementCase<2>::cut_axis(0));
3689  refinedCellCounter++;
3690  }
3691  else
3692  {
3693  if (cell->extent_in_direction(1) >max_aspect_ratio*cell->extent_in_direction(0))
3694  {
3695  cell->set_refine_flag(RefinementCase<2>::cut_axis(1));
3696  refinedCellCounter++;
3697  }
3698  }
3699  }
3700  }
3701  //cout<<refinedCellCounter<<endl;
3702  tria.execute_coarsening_and_refinement();
3703  dh.distribute_dofs(fe);
3704  vector_dh.distribute_dofs(vector_fe);
3705 
3706  map_points.reinit(vector_dh.n_dofs());
3707  smoothing_map_points.reinit(vector_dh.n_dofs());
3708  old_map_points.reinit(vector_dh.n_dofs());
3709  rigid_motion_map_points.reinit(vector_dh.n_dofs());
3710  initial_map_points.reinit(vector_dh.n_dofs());
3711  ref_points.resize(vector_dh.n_dofs());
3712  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3713  vector_dh, ref_points);
3714  generate_double_nodes_set();
3715  make_edges_conformal(false);
3716  make_edges_conformal(false);
3717  make_edges_conformal(false);
3718  full_mesh_treatment();
3719  cycles_counter++;
3720  }
3721 
3722  */
3723 
3724  /* Triangulation<2,3>::active_cell_iterator
3725  cell = tria.begin_active(), endc = tria.end();
3726  unsigned int refinedCellCounter = 1;
3727  double counter=0;
3728  while(refinedCellCounter)
3729  {
3730  refinedCellCounter = 0;
3731  for (cell=tria.begin_active(); cell!= endc;++cell)
3732  {
3733  if ( (cell->extent_in_direction(0) > 1.5*cell->extent_in_direction(1)) &&
3734  (fabs(cell->center()(1)) < (Ly_domain/4+Lx_boat/2)/pow(2.0,counter)) &&
3735  (cell->material_id() == free_sur_ID1 ||
3736  cell->material_id() == free_sur_ID2 ||
3737  cell->material_id() == free_sur_ID3 ) )
3738  {
3739  cell->set_refine_flag(RefinementCase<2>::cut_axis(0));
3740  refinedCellCounter++;
3741  }
3742  else
3743  {
3744  if ( (cell->extent_in_direction(1) > 1.5*cell->extent_in_direction(0)) &&
3745  (fabs(cell->center()(1)) < (Ly_domain/4+Lx_boat/2)/pow(2.0,counter)) &&
3746  (cell->material_id() == free_sur_ID1 ||
3747  cell->material_id() == free_sur_ID2 ||
3748  cell->material_id() == free_sur_ID3 ) )
3749  {
3750  cell->set_refine_flag(RefinementCase<2>::cut_axis(1));
3751  refinedCellCounter++;
3752  }
3753  }
3754  }
3755  counter = counter+1.0;
3756  tria.execute_coarsening_and_refinement();
3757  dh.distribute_dofs(fe);
3758  vector_dh.distribute_dofs(vector_fe);
3759  map_points.reinit(vector_dh.n_dofs());
3760  smoothing_map_points.reinit(vector_dh.n_dofs());
3761  old_map_points.reinit(vector_dh.n_dofs());
3762  rigid_motion_map_points.reinit(vector_dh.n_dofs());
3763  initial_map_points.reinit(vector_dh.n_dofs());
3764  ref_points.resize(vector_dh.n_dofs());
3765  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3766  vector_dh, ref_points);
3767  generate_double_nodes_set();
3768  make_edges_conformal(false);
3769  make_edges_conformal(false);
3770  full_mesh_treatment();
3771  cout<<"Current dofs number: "<<dh.n_dofs()<<endl;
3772  std::string filename = ( "meshResult_" +
3773  Utilities::int_to_string(int(round(counter))) +
3774  ".vtu" );
3775  std::ofstream logfile(filename.c_str());
3776  GridOut grid_out;
3777  grid_out.write_ucd(tria, logfile);
3778  }
3779 
3780 
3781  cell = tria.begin_active(), endc = tria.end();
3782  refinedCellCounter = 1;
3783  counter=0;
3784  while(refinedCellCounter)
3785  {
3786  std::string filename0 = ( "meshResultZeroth_" +
3787  Utilities::int_to_string(int(round(counter))) +
3788  ".vtu" );
3789  std::ofstream logfile0(filename0.c_str());
3790  GridOut grid_out0;
3791  grid_out0.write_ucd(tria, logfile0);
3792  refinedCellCounter = 0;
3793  for (cell=tria.begin_active(); cell!= endc;++cell)
3794  {
3795  if ( (cell->extent_in_direction(0) > 2.0*cell->extent_in_direction(1)) &&
3796  (cell->material_id() == wall_sur_ID1 ||
3797  cell->material_id() == wall_sur_ID2 ||
3798  cell->material_id() == wall_sur_ID3 ) )
3799  {
3800  cell->set_refine_flag(RefinementCase<2>::cut_axis(0));
3801  refinedCellCounter++;
3802  }
3803  else
3804  {
3805  if ( (cell->extent_in_direction(1) > 2.0*cell->extent_in_direction(0)) &&
3806  (cell->material_id() == wall_sur_ID1 ||
3807  cell->material_id() == wall_sur_ID2 ||
3808  cell->material_id() == wall_sur_ID3 ) )
3809  {
3810  cell->set_refine_flag(RefinementCase<2>::cut_axis(1));
3811  refinedCellCounter++;
3812  }
3813  }
3814  }
3815  counter = counter+1.0;
3816  tria.execute_coarsening_and_refinement();
3817  dh.distribute_dofs(fe);
3818  vector_dh.distribute_dofs(vector_fe);
3819  map_points.reinit(vector_dh.n_dofs());
3820  smoothing_map_points.reinit(vector_dh.n_dofs());
3821  old_map_points.reinit(vector_dh.n_dofs());
3822  rigid_motion_map_points.reinit(vector_dh.n_dofs());
3823  initial_map_points.reinit(vector_dh.n_dofs());
3824  ref_points.resize(vector_dh.n_dofs());
3825  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3826  vector_dh, ref_points);
3827  generate_double_nodes_set();
3828  std::string filename1 = ( "meshResultFirst_" +
3829  Utilities::int_to_string(int(round(counter))) +
3830  ".vtu" );
3831  std::ofstream logfile1(filename1.c_str());
3832  GridOut grid_out1;
3833  grid_out1.write_ucd(tria, logfile1);
3834  make_edges_conformal(false);
3835  make_edges_conformal(false);
3836  full_mesh_treatment();
3837  cout<<"Current dofs number: "<<dh.n_dofs()<<endl;
3838  std::string filename = ( "meshResultSecond_" +
3839  Utilities::int_to_string(int(round(counter))) +
3840  ".vtu" );
3841  std::ofstream logfile(filename.c_str());
3842  GridOut grid_out;
3843  grid_out.write_ucd(tria, logfile);
3844  }
3845  //*/
3846  cout<<"Current dofs number: "<<dh.n_dofs()<<endl;
3847  std::string filename = ( "meshResultSecond.vtu" );
3848  std::ofstream logfile(filename.c_str());
3849  GridOut grid_out;
3850  grid_out.write_ucd(tria, logfile);
3851 
3852 }
3853 
3854 void NumericalTowingTank::refine_global_on_boat(const unsigned int num_refinements)
3855 {
3856  for (unsigned int i=0; i<num_refinements; ++i)
3857  {
3858  std::cout<<"Uniform boat refinement cycle "<<i+1<<" of "<<num_refinements<<std::endl;
3859  if (no_boat)
3860  {
3861  tria_it cell = tria.begin_active(), endc = tria.end();
3862  for (cell=tria.begin_active(); cell!= endc; ++cell)
3863  {
3864  cell->set_refine_flag();
3865  }
3866 
3868 
3869  }
3870  else
3871  {
3872  tria_it cell = tria.begin_active(), endc = tria.end();
3873  for (cell=tria.begin_active(); cell!= endc; ++cell)
3874  {
3875  if ((cell->material_id() == wall_sur_ID1 ||
3876  cell->material_id() == wall_sur_ID2 ||
3877  cell->material_id() == wall_sur_ID3 ))
3878  cell->set_refine_flag();
3879  }
3881  }
3889  ref_points.resize(vector_dh.n_dofs());
3890  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3894 
3895  if (no_boat)
3896  {
3897  make_edges_conformal(false);
3898  make_edges_conformal(false);
3899  }
3900  else
3901  {
3902  make_edges_conformal(true);
3903  make_edges_conformal(true);
3904  }
3905  }
3906 
3907  /*
3908  for (unsigned int i=0; i<3;++i)
3909  {
3910  tria_it cell = tria.begin_active(), endc = tria.end();
3911  for (cell=tria.begin_active(); cell!= endc;++cell)
3912  {
3913  if ( cell->material_id() == inflow_sur_ID1 ||
3914  cell->material_id() == inflow_sur_ID2 )
3915  cell->set_refine_flag();
3916  }
3917  tria.execute_coarsening_and_refinement();
3918  dh.distribute_dofs(fe);
3919  vector_dh.distribute_dofs(vector_fe);
3920  map_points.reinit(vector_dh.n_dofs());
3921  smoothing_map_points.reinit(vector_dh.n_dofs());
3922  old_map_points.reinit(vector_dh.n_dofs());
3923  rigid_motion_map_points.reinit(vector_dh.n_dofs());
3924  initial_map_points.reinit(vector_dh.n_dofs());
3925  ref_points.resize(vector_dh.n_dofs());
3926  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3927  vector_dh, ref_points);
3928  generate_double_nodes_set();
3929  full_mesh_treatment();
3930  make_edges_conformal(true);
3931  make_edges_conformal(true);
3932  }
3933  //*/
3934  /*
3935  for (unsigned int i=0; i<4;++i)
3936  {
3937  tria_it cell = tria.begin_active(), endc = tria.end();
3938  for (cell=tria.begin_active(); cell!= endc;++cell)
3939  {
3940  if ( (cell->material_id() == free_sur_ID1 ||
3941  cell->material_id() == free_sur_ID2 ||
3942  cell->material_id() == free_sur_ID3 ) &&
3943  (cell->center()(0) > -4.10) &&
3944  (cell->center()(0) < 6.10) &&
3945  (cell->center()(1) > -3.5) &&
3946  (cell->center()(1) < 3.5) &&
3947  (cell->diameter()/2.8 > 0.174353) )
3948  cell->set_refine_flag();
3949  }
3950  tria.execute_coarsening_and_refinement();
3951  dh.distribute_dofs(fe);
3952  vector_dh.distribute_dofs(vector_fe);
3953  map_points.reinit(vector_dh.n_dofs());
3954  smoothing_map_points.reinit(vector_dh.n_dofs());
3955  old_map_points.reinit(vector_dh.n_dofs());
3956  rigid_motion_map_points.reinit(vector_dh.n_dofs());
3957  initial_map_points.reinit(vector_dh.n_dofs());
3958  ref_points.resize(vector_dh.n_dofs());
3959  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3960  vector_dh, ref_points);
3961  generate_double_nodes_set();
3962  full_mesh_treatment();
3963  make_edges_conformal(true);
3964  make_edges_conformal(true);
3965  }
3966  //*/
3967 
3968  /*
3969  for (unsigned int k=0; k<1; ++k)
3970  {
3971  Triangulation<2,3>::active_cell_iterator
3972  cell = tria.begin_active(), endc = tria.end();
3973  for (cell=tria.begin_active(); cell!= endc;++cell)
3974  {
3975  if ( (cell->material_id() == wall_sur_ID1 ||
3976  cell->material_id() == wall_sur_ID2 ||
3977  cell->material_id() == wall_sur_ID3 ) &&
3978  (cell->center()(0) > -3.50) &&
3979  (cell->center()(0) < 17.00) &&
3980  (fabs(cell->center()(1)) < 0.363970234*(cell->center()(0)+3.50)) &&
3981  (cell->center()(2) > -0.1) &&
3982  (cell->diameter() > 0.4) )
3983  cell->set_refine_flag();
3984  }
3985  tria.execute_coarsening_and_refinement();
3986  dh.distribute_dofs(fe);
3987  vector_dh.distribute_dofs(vector_fe);
3988  map_points.reinit(vector_dh.n_dofs());
3989  smoothing_map_points.reinit(vector_dh.n_dofs());
3990  old_map_points.reinit(vector_dh.n_dofs());
3991  rigid_motion_map_points.reinit(vector_dh.n_dofs());
3992  initial_map_points.reinit(vector_dh.n_dofs());
3993  ref_points.resize(vector_dh.n_dofs());
3994  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3995  vector_dh, ref_points);
3996  generate_double_nodes_set();
3997  full_mesh_treatment();
3998  make_edges_conformal(true);
3999  make_edges_conformal(true);
4000  }
4001  //*/
4002 }
4003 
4004 
4005 void NumericalTowingTank::extract_boundary_dofs(std::vector<bool> &dofs, unsigned int id,
4006  DoFHandler<2,3> &vector_dh)
4007 {
4008  std::vector<bool> comp_sel(3, true);
4009  std::set<unsigned char> ids;
4010  ids.insert(id);
4011  DoFTools::extract_boundary_dofs(vector_dh, comp_sel, dofs, ids);
4012 }
4013 
4014 
4015 unsigned int NumericalTowingTank::find_point_id(const Point<3> &p, const vector<Point<3> > &ps)
4016 {
4017  //cout<<"numPoints "<<ps.size()<<endl;
4018  for (unsigned int i=0; i<ps.size()/3; ++i)
4019  {
4020  //cout<<"i "<<i<<" p("<<ps[3*i]<<") d "<< p.distance(ps[3*i])<<endl;
4021  if (p.distance(ps[3*i]) < 1e-7)
4022  return (i);
4023  }
4024  return 0;
4025 }
4026 
4027 
4028 Handle(Geom_Curve) NumericalTowingTank::get_curve(const vector<Point<3> > &ps,
4029  const vector<bool> &id,
4030  const Point<3> direction)
4031 {
4032  vector<Point<3> > points;
4033  for (unsigned int i=0; i<ps.size()/3; ++i)
4034  if (id[3*i] == true)
4035  points.push_back(ps[3*i]);
4036 
4037  return interpolation_curve_points_sort(points, direction);
4038 }
4039 
4040 class NumericalTowingTank;
const unsigned int mapping_degree
std::vector< CellData< 1 > > boundary_lines
void update_reference()
Whenever the underlying dh.
DoFHandler< dim-1, dim >::active_cell_iterator cell_it
void set_boundary(const types::manifold_id number, const Boundary< dim, spacedim > &boundary_object)
std::vector< Point< 3 > > node_normals
void write_ucd(const Triangulation< dim, spacedim > &tria, std::ostream &out) const
std::vector< GeometryFlags > cell_flags
Vector< double > initial_map_points
Point< 3 > PointFrontBot
Definition: boat_model.h:55
active_cell_iterator begin_active(const unsigned int level=0) const
ConstraintMatrix vector_constraints
DoFHandler< dim-1, dim > vector_dh
SparsityPattern normals_sparsity_pattern
cell_iterator end() const
unsigned int init_adaptive_boat_refs
bool is_constrained(const size_type index) const
SparseMatrix< double > vector_normals_matrix
unsigned int find_point_id(const Point< 3 > &p, const std::vector< Point< 3 > > &ps)
void apply_curvatures(const Vector< double > &curvatures, const std::vector< bool > boundary_dofs)
OpenCascade::ArclengthProjection * water_line_right
Definition: boat_model.h:129
Vector< double > vector_normals_rhs
Vector< double > smoothing_curvature_vector
std::vector< Point< dim > > support_points
OpenCascade::NormalProjection< 2 > * boat_surface_left
Definition: boat_model.h:109
bool is_transom
Definition: boat_model.h:147
virtual void execute_coarsening_and_refinement()
Point< 3 > PointBackBot
Definition: boat_model.h:64
Triangulation< dim-1, dim > coarse_tria
void distribute(VectorType &vec) const
std::vector< unsigned int > boundary_ids
STL namespace.
numbers::NumberTraits< double >::real_type distance(const Point< dim, double > &p) const
std::set< tria_it > edge_cells
std::vector< std::vector< bool > > boundary_dofs
void refine_and_coarsen_fixed_fraction(Triangulation< dim, spacedim > &tria, const VectorType &criteria, const double top_fraction, const double bottom_fraction, const unsigned int max_n_cells=std::numeric_limits< unsigned int >::max())
#define AssertThrow(cond, exc)
OpenCascade::NormalProjection< 2 > * boat_surface_right
Definition: boat_model.h:107
unsigned int max_couplings_between_dofs() const
Point< 3 > PointBackTop
Definition: boat_model.h:62
Vector< double > smoothing_map_points
std_cxx1x::shared_ptr< Quadrature< dim-1 > > quadrature
unsigned int n_active_cells() const
virtual void reinit(const SparsityPattern &sparsity)
std::string get(const std::string &entry_string) const
Vector< double > vector_normals_solution
bool assigned_axis_projection_and_diff_forms(Point< 3 > &projection, Point< 3 > &normal, double &mean_curvature, const Point< 3 > &origin, const Point< 3 > &assigned_axis) const
virtual void declare_parameters(ParameterHandler &prm)
std::vector< unsigned int > moving_point_ids
std::vector< Point< 3 > > old_iges_normals
virtual void execute_coarsening_and_refinement()
void add(const std::vector< size_type > &indices, const std::vector< OtherNumber > &values)
void make_hanging_node_constraints(const DoFHandlerType &dof_handler, ConstraintMatrix &constraints)
void compute_constraints(ConstraintMatrix &cc)
Point< 3 > PointLeftTransom
Definition: boat_model.h:66
void distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
virtual bool prepare_coarsening_and_refinement()
static::ExceptionBase & ExcMessage(std::string arg1)
const std::vector< Point< spacedim > > & get_quadrature_points() const
std::set< unsigned int > boat_nodes
void partial_mesh_treatment(const double blend_factor)
static void reorder_cells(std::vector< CellData< dim > > &original_cells, const bool use_new_style_ordering=false)
std::vector< GeometryFlags > flags
virtual void parse_parameters(ParameterHandler &prm)
unsigned int number_of_transom_edges
#define Assert(cond, exc)
types::global_dof_index n_dofs() const
NumericalTowingTank(unsigned int, unsigned int)
Vector< double > old_map_points
OpenCascade::ArclengthProjection * boat_keel
Definition: boat_model.h:117
void perform_smoothing(bool full_treatment, const double blend_factor)
OpenCascade::ArclengthProjection * boat_transom_right
Definition: boat_model.h:123
virtual void generate_double_nodes_set()
virtual void declare_parameters(ParameterHandler &prm)
std::vector< unsigned int > base_point_ids
FESystem< dim-1, dim > vector_fe
std::vector< unsigned int > vector_dof_components
std::set< unsigned int > free_surf_and_boat_nodes
std::vector< Point< dim > > vector_support_points
void make_edges_conformal(bool isotropic_ref_on_opposite_side)
std::vector< bool > on_curve_option
void extract_boundary_dofs(const DoFHandlerType &dof_handler, const ComponentMask &component_mask, std::vector< bool > &selected_dofs, const std::set< types::boundary_id > &boundary_ids=std::set< types::boundary_id >())
Vector< double > rigid_motion_map_points
void start_iges_model(std::string igesFileName, double scale, double displacement, double assigned_sink, double assigned_trim, double back_keel_length=0.1, double front_keel_length=0.05, double middle_keel_length=.47, unsigned int number_of_transom_edges=1)
Definition: boat_model.cc:166
void apply_curvatures(const Vector< double > &curvatures, const std::vector< bool > &boundary_dofs)
Apply curvatures at the.
SurfaceSmoothing * surface_smoother
std::vector< double > iges_mean_curvatures
PersistentTriangulation< dim-1, dim > tria
void perform_line_smoothing(unsigned int num_smoothings)
cell_iterator end() const
std::map< cell_it, std::set< cell_it > > elem_to_surr_elems
std::vector< GeometryFlags > vector_flags
std::vector< OpenCascade::LineSmoothing * > line_smoothers
const unsigned int dofs_per_cell
void remove_mesh_anisotropy(Triangulation< 2, 3 > &tria)
OpenCascade::AxisProjection * boat_water_line_right
Definition: boat_model.h:111
const unsigned int n_quadrature_points
void reinit(const size_type m, const size_type n, const unsigned int max_per_row)
Vector< double > edges_length_ratios
const double & shape_value(const unsigned int function_no, const unsigned int point_no) const
OpenCascade::ArclengthProjection * boat_transom_left
Definition: boat_model.h:121
dealii::Point< 3 > Pnt(const gp_Pnt &p)
Convert OpenCascade point into.
Definition: occ_utilities.h:76
std::vector< TopLoc_Location * > smoothers_locations
void refine_global_on_boat(const unsigned int num_refinements)
std::vector< std::set< unsigned int > > vector_double_nodes_set
virtual void refine_and_resize()
Mapping< dim-1, dim > * mapping
void compute_normals_at_nodes(Vector< double > &map_points_used)
void make_sparsity_pattern(const DoFHandlerType &dof_handler, SparsityPatternType &sparsity_pattern, const ConstraintMatrix &constraints=ConstraintMatrix(), const bool keep_constrained_dofs=true, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id)
OpenCascade::ArclengthProjection * water_line_left
Definition: boat_model.h:131
void initialize(const SparsityPattern &sparsity_pattern)
std::pair< unsigned int, unsigned int > system_to_component_index(const unsigned int index) const
void compute_curvatures(Vector< double > &curvatures)
SurfaceSmoothing * restart_surface_smoother
double get_double(const std::string &entry_name) const
virtual void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
void smooth()
Perform the full smoothing.
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
const unsigned int dofs_per_face
void compute_curvatures(Vector< double > &curvatures)
Compute curvatures at the.
bool axis_projection_and_diff_forms(Point< 3 > &projection, Point< 3 > &normal, double &mean_curvature, const Point< 3 > &origin) const
void declare_entry(const std::string &entry, const std::string &default_value, const Patterns::PatternBase &pattern=Patterns::Anything(), const std::string &documentation=std::string())
void delete_unused_vertices(std::vector< Point< spacedim > > &vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata)
We collect in this namespace all utilities which operate on OpenCascade entities which don't need cla...
std::vector< std::set< unsigned int > > double_nodes_set
void normal_projection_and_diff_forms(Point< 3 > &projection, Point< 3 > &normal, double &mean_curvature, const Point< 3 > &origin) const
std::vector< Point< 3 > > moving_points
bool assigned_axis_projection(Point< 3 > &projection, const Point< 3 > &origin, const Point< 3 > &assigned_axis) const
void create_initial_mesh(const Point< 3 > PointFrontTop, const Point< 3 > PointFrontBot, const Point< 3 > PointMidTop, const Point< 3 > PointMidBot, const Point< 3 > PointBackTop, const Point< 3 > PointBackBot, const Point< 3 > PointLeftTransom, const Point< 3 > PointRightTransom, const Point< 3 > PointCenterTransom, Triangulation< 2, 3 > &triangulation)
Handle(Geom_Curve) NumericalTowingTank
void extract_boundary_dofs(std::vector< bool > &dofs, unsigned int id, DoFHandler< 2, 3 > &vector_dh)
std::vector< Point< 3 > > iges_normals
active_cell_iterator begin_active(const unsigned int level=0) const
OpenCascade::AxisProjection * boat_water_line_left
Definition: boat_model.h:113
virtual void parse_parameters(ParameterHandler &prm)
Vector< double > edges_tangents
std::vector< Handle(Geom_Curve)> curves
unsigned int init_global_boat_refs
double boatWetLength
Definition: boat_model.h:81
Point< 3 > PointMidTop
Definition: boat_model.h:58
TopLoc_Location current_loc
Definition: boat_model.h:105
std::vector< Point< 3 > > base_points
Point< 3 > PointMidBot
Definition: boat_model.h:60
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell)
DoFHandler< dim-1, dim > dh
Point< 3 > PointRightTransom
Definition: boat_model.h:68
std::vector< Point< 3 > > ref_points
double JxW(const unsigned int quadrature_point) const
virtual void create_triangulation_compatibility(const std::vector< Point< spacedim > > &vertices, const std::vector< CellData< dim > > &cells, const SubCellData &subcelldata)
Triangulation< dim-1, dim >::active_cell_iterator tria_it
Point< 3 > PointCenterTransom
Definition: boat_model.h:79
OpenCascade::AxisProjection * undist_water_surf
Definition: boat_model.h:115
void update_mapping(const Vector< double > &map_points)
long int get_integer(const std::string &entry_string) const
std::map< unsigned int, std::vector< cell_it > > dof_to_elems
void vmult(Vector< double > &dst, const Vector< double > &src) const
static::ExceptionBase & ExcInternalError()
std::map< unsigned int, std::vector< cell_it > > vector_dof_to_elems
Point< 3 > PointFrontTop
Definition: boat_model.h:53
std::vector< Point< spacedim > > get_normal_vectors() const DEAL_II_DEPRECATED
Handle_Geom_Curve interpolation_curve_points_sort(std::vector< Point< 3 > > &curve_points, Point< 3 > direction)