WaveBEM: Unsteady Nonlinear Potential Flow Solver for Ship-Wave Interaction.
boat_model.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, 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
13 //
14 //---------------------------- step-34.cc ---------------------------
15 
16 
17 // @sect3{Include files}
18 
19 // The program starts with including a bunch
20 // of include files that we will use in the
21 // various parts of the program. Most of them
22 // have been discussed in previous tutorials
23 // already:
24 
25 
26 #include "../include/boat_model.h"
27 #include <gp_Trsf.hxx>
28 #include <BRepBuilderAPI_Transform.hxx>
29 #include <BRepBuilderAPI_GTransform.hxx>
30 
31 #include <TopTools.hxx>
32 #include <Standard_Stream.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopoDS_Edge.hxx>
35 #include <GC_MakeSegment.hxx>
36 
37 #include <IGESControl_Reader.hxx>
38 #include <IGESControl_Controller.hxx>
39 #include <IGESControl_Writer.hxx>
40 #include <TopoDS.hxx>
41 #include <TopoDS_Shape.hxx>
42 #include <TopoDS_Shell.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <BRepTools.hxx>
45 #include <XSControl_Reader.hxx>
46 #include <TopTools_SequenceOfShape.hxx>
47 #include <Handle_Standard_Transient.hxx>
48 #include <TColStd_SequenceOfTransient.hxx>
49 #include <TColStd_HSequenceOfTransient.hxx>
50 #include <TopExp_Explorer.hxx>
51 #include <gp_Pnt.hxx>
52 #include <gp_Vec.hxx>
53 #include <GeomAPI_ProjectPointOnSurf.hxx>
54 #include <GeomAPI_ProjectPointOnCurve.hxx>
55 #include <Standard_Real.hxx>
56 #include <Standard_Integer.hxx>
57 #include <BRep_Tool.hxx>
58 #include <Geom_Surface.hxx>
59 #include <Geom_Plane.hxx>
60 #include <Prs3d_ShapeTool.hxx>
61 #include <Bnd_Box.hxx>
62 #include <gp_Ax3.hxx>
63 #include <gp_Pln.hxx>
64 #include <BRepBuilderAPI_MakeFace.hxx>
65 #include <GeomAPI_IntSS.hxx>
66 #include <TopoDS_Wire.hxx>
67 #include <BRepBuilderAPI_MakePolygon.hxx>
68 #include <Geom_Curve.hxx>
69 #include <Geom_BoundedCurve.hxx>
70 #include <Geom_TrimmedCurve.hxx>
71 #include <TColGeom_Array1OfCurve.hxx>
72 #include <GeomAPI_IntCS.hxx>
73 #include <BRepBuilderAPI_MakeEdge.hxx>
74 #include <GeomLib_Tool.hxx>
75 #include <GCPnts_AbscissaPoint.hxx>
76 #include <GeomConvert_CompCurveToBSplineCurve.hxx>
77 #include <GeomLProp_SLProps.hxx>
78 #include <BRepTools_ReShape.hxx>
79 #include <BRepBuilderAPI_MakePolygon.hxx>
80 #include <BRepBuilderAPI_NurbsConvert.hxx>
81 #include <BRepLib_FindSurface.hxx>
82 #include <TColStd_Array1OfReal.hxx>
83 #include <TColStd_Array1OfInteger.hxx>
84 #include <GeomConvert.hxx>
85 #include <Geom_BSplineSurface.hxx>
86 #include <BRepAdaptor_Curve.hxx>
87 #include <gp_Quaternion.hxx>
88 
91 
92 #include <deal.II/grid/tria.h>
94 #include <deal.II/grid/grid_out.h>
100 #include <deal.II/dofs/dof_tools.h>
102 #include <deal.II/fe/fe_q.h>
103 #include <deal.II/fe/fe_values.h>
104 #include <deal.II/fe/fe_system.h>
106 #include <deal.II/fe/mapping_q.h>
108 
109 
110 using namespace dealii;
111 using namespace OpenCascade;
112 
114  boat_surface_right(NULL),
115  boat_surface_left(NULL),
116  boat_water_line_right(NULL),
117  boat_water_line_left(NULL),
118  boat_keel(NULL),
119  boat_keel_norm(NULL),
120  boat_transom_left(NULL),
121  boat_transom_right(NULL),
122  wake_line_left(NULL),
123  wake_line_right(NULL),
124  water_line_right(NULL),
125  water_line_left(NULL)
126 {
127 }
128 
130 {
131  if (boat_surface_right)
132  delete boat_surface_right;
133  if (boat_surface_left)
134  delete boat_surface_left;
136  delete boat_water_line_right;
138  delete boat_water_line_left;
139  if (boat_keel)
140  delete boat_keel;
141  if (boat_keel_norm)
142  delete boat_keel_norm;
143  if (boat_transom_left)
144  delete boat_transom_left;
145  if (boat_transom_right)
146  delete boat_transom_right;
147  if (water_line_right)
148  delete water_line_right;
149  if (water_line_left)
150  delete water_line_left;
151 }
152 
153 
154 TopoDS_Shape BoatModel::ReverseFaceOrientation(const TopoDS_Shape &shape,
155  const TopoDS_Face &face)
156 {
157  Handle(BRepTools_ReShape) rebuild = new BRepTools_ReShape();
158  rebuild->ModeConsiderOrientation() = Standard_True;
159  TopoDS_Shape newface = face.Complemented();
160  rebuild->Replace(face, newface, Standard_True );
161  TopoDS_Shape newshape = rebuild->Apply(shape, TopAbs_FACE );
162  return newshape;
163 }
164 
165 
166 void BoatModel::start_iges_model(std::string igesFileName,
167  double scale,
168  double displacement,
169  double assigned_sink,
170  double assigned_trim,
171  double back_keel_length,
172  double front_keel_length,
173  double middle_keel_length,
174  unsigned int number_of_transom_edges)
175 {
176  //feature_edges_detection();
177 
178  //let's read the (iges) hull shape from file
179  sh =read_IGES(igesFileName,scale);
180 
181 
182  //TopoDS_Shape shape_transom = read_IGES("/home/amola/workspace/FRANCO_TETGEN/CAD_FRANCO/DTMB_transom_franco.iges",scale);
183  //OpenCascade::NormalProjection<2> transom_proj(shape_transom);;
184  //Point<3> degenerate(3.053863,0.0,-0.022);
185  //Point<3> proj;
187  //double mean_curv;
188  //transom_proj.normal_projection_and_diff_forms(proj, norm, mean_curv,degenerate);
189  //cout<<"****Normal: "<<norm<<endl;
190 
191  //TopoDS_Shape top_edge = keel_edge = extract_xz_edges(shape_top,1e-4,30);
192 
193  //IGESControl_Controller::Init();
194  //IGESControl_Writer ICW ("MM", 0);
195  //Standard_Boolean ok = ICW.AddShape (top_edge);
196  //ICW.ComputeModel();
197  //Standard_Boolean OK = ICW.Write ("top_edge.igs");
198 
199 
200 
201  TopExp_Explorer faceExplorer(sh, TopAbs_FACE);
202  TopoDS_Face face;
203  gp_Pnt Pint;
204  std::vector<bool> to_be_changed;
205  unsigned int face_count = 0;
206  while (faceExplorer.More())
207  {
208  face = TopoDS::Face(faceExplorer.Current());
209  Standard_Real umin, umax, vmin, vmax;
210  BRepTools::UVBounds(face, umin, umax, vmin, vmax); // create surface
211  Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // get surface properties
212  GeomLProp_SLProps props(surf, (umin+umax)/2.0, (vmin+vmax)/2.0, 1, 0.01); // get surface normal
213  gp_Dir norm=props.Normal();
214  if (norm.Y() > 0)
215  {
216  to_be_changed.push_back(true);
217  //cout<<"i "<<face_count<<endl;
218  }
219  else if (norm.Y() == 0)
220  {
221  if (norm.Z() < 0)
222  {
223  to_be_changed.push_back(true);
224  }
225  else
226  {
227  to_be_changed.push_back(false);
228  }
229  }
230  else
231  to_be_changed.push_back(false);
232  faceExplorer.Next();
233  ++face_count;
234  }
235  //cout<<"size "<<to_be_changed.size()<<endl;
236  TopoDS_Shape newShape;
237  for (unsigned int i=0; i<face_count; ++i)
238  {
239  //cout<<"*i "<<i<<" of "<<face_count<<endl;
240  if (to_be_changed.at(i))
241  {
242  //cout<<"**i "<<i<<" of "<<face_count<<endl;
243  faceExplorer.Init(sh,TopAbs_FACE);
244  for (unsigned int j=0; j<i; ++j)
245  faceExplorer.Next();
246  face = TopoDS::Face(faceExplorer.Current());
247  newShape = ReverseFaceOrientation(sh,face);
248  sh = newShape;
249  //cout<<"***i "<<i<<" of "<<face_count<<endl;
250  }
251  //cout<<"****i "<<i<<" of "<<face_count<<endl;
252  }
253 //Standard::Purge();
254  //let's create the reflected side of the hull
255  //this is the y axis definition for planar mirroring
256  gp_Ax2 yAx(gp_Pnt(0.0,0.0,0.0), gp_Dir(0.0,1.0,0.0), gp_Dir(1.0,0.0,0.0));
257  //here we define the y mirroring transformation
258  gp_Trsf y_mirroring;
259  y_mirroring.SetMirror(yAx);
260  //here we apply to the hull the y mirroring transformation
261  BRepBuilderAPI_Transform boat_surface_transformation(sh, y_mirroring);
262  //we use the transformation to define the mirrored shape
263  refl_sh = boat_surface_transformation.Shape();
264 
265 
266  // if displacement is set to 0 we keep the boat position
267  // in the iges file
268  if (displacement > 0)
269  {
270  //here we perform hydrostatic computations to evaluate the
271  //correct hull sinkage
272  double sink;
273  double weight = displacement*9.81;
274  compute_hydrostatic_sink(sink,weight);
275  //now we have to use the computed sink to diplace vertically
276  //the left and right sides of the hull
277 
278  TopoDS_Shape sh_copy(sh);
279  TopoDS_Shape refl_sh_copy(refl_sh);
280  gp_Vec vert_displ(0.0,0.0,-sink);
281  gp_Trsf vert_translation;
282  vert_translation.SetTranslation(vert_displ);
283  BRepBuilderAPI_Transform right_vert_transl(sh_copy, vert_translation);
284  sh = right_vert_transl.Shape();
285  BRepBuilderAPI_Transform left_vert_transl(refl_sh_copy, vert_translation);
286  refl_sh = left_vert_transl.Shape();
287 
288 
289  }
290 
291  Point<3> hs_force = compute_hydrostatic_force(0.0);
292  boat_mass = hs_force(2)/9.81;
293  // let's compute the longitudinal position of the pressure center: we'll
294  // place the the hull baricenter there, because we POSTULATE that the
295  // hull in the CAD file is oriented in the proper way at the dislocation
296  // tested
297 
298  Point<3> hs_moment = compute_hydrostatic_moment(0.0,Point<3>(0.0,0.0,0.0));
299  hydrostatic_hull_baricenter = Point<3>(-hs_moment(1)/hs_force(2),0.0,0.0);
300  cout<<"Computed Hull Baricenter Position: "<<hydrostatic_hull_baricenter<<endl;
301 
302  initial_sink = assigned_sink;
303  initial_trim = assigned_trim;
304  //here we prepare the rotation of the boat of the requested trim angle
305  gp_Pnt rot_center = Pnt(hydrostatic_hull_baricenter);
306  gp_Dir rot_dir(0.0,1.0,0.0);
307  gp_Ax1 rot_axis(rot_center, rot_dir);
308  gp_Trsf rotation;
309  // sign is negative because in "naval-like" reference frame bow-down trim angle is positive
310  // (in our "aero-like" reference frame x axis is aligned with V_inf, not going from stern to bow)
311  rotation.SetRotation(rot_axis,-assigned_trim);
312  //here we prepare the translation of the boat of the requested sink
313  gp_Trsf translation;
314  gp_Vec vrt_displ(0.0,0.0,-assigned_sink);
315  translation.SetTranslation(vrt_displ);
317  reference_hull_baricenter(2) -= assigned_sink;
318  //the rotation and translation are combined in a single transformation
319  gp_Trsf Tcomp = translation*rotation;
320  //the transformation is applied to the two sides of the boat
321  BRepBuilderAPI_Transform right_transf(sh, Tcomp);
322  sh = right_transf.Shape();
323  BRepBuilderAPI_Transform left_transf(refl_sh, Tcomp);
324  refl_sh = left_transf.Shape();
325 
326 
327 
328  cout<<"The hull has been placed in the requested initial position"<<endl;
329  cout<<"Reference Hull Baricenter Position: "<<reference_hull_baricenter<<endl;
330  hs_force = compute_hydrostatic_force(0.0);
332  //now the boat is in the correct position
333 // These lines can be used to dump the keel edge (or other shapes) on an .igs file
334  /*
335  IGESControl_Controller::Init();
336  IGESControl_Writer ICW ("MM", 0);
337  Standard_Boolean ok = ICW.AddShape (sh);
338  ICW.ComputeModel();
339  Standard_Boolean OK = ICW.Write ("shape.igs");
340  //*/
341 
342 
343 
344  //here we extract the keel edge from the hull shape
345  keel_edge = extract_xz_edges(sh,3e-4,100);
346  //here we extract the transom edge from the right hull shape
347  right_transom_edge = extract_transom_edges(sh,number_of_transom_edges,1e-4);
348  //here we extract the transom edge from the right hull shape
349  //by applying
350  //to the right water line the y mirroring transformation
351  BRepBuilderAPI_Transform transom_transformation(right_transom_edge, y_mirroring);
352  //we use the transformation to define the mirrored shape
353  left_transom_edge = transom_transformation.Shape();
354 
355 
356 // These lines can be used to dump the keel edge (or other shapes) on an .igs file
357  /*
358  IGESControl_Controller::Init();
359  IGESControl_Writer ICW ("MM", 0);
360  Standard_Boolean ok = ICW.AddShape (right_transom_edge);
361  ICW.ComputeModel();
362  Standard_Boolean OK = ICW.Write ("transom.igs");
363  //*/
364  //here we extract the undisturbed right water line from
365  //the hull shape
366  intersect_plane(sh,right_undist_water_line,0.0,0.0,1.0,0.0,1e-4); // 1e-2 tolerance for comacina
367  //here we extract the undisturbed left water line from
368  //the hull shape by applying
369  //to the right water line the y mirroring transformation
370  BRepBuilderAPI_Transform waterline_transformation(right_undist_water_line, y_mirroring);
371  //we use the transformation to define the mirrored shape
372  left_undist_water_line = waterline_transformation.Shape();
373 
374 
375  TopLoc_Location L;
376  Standard_Real First;
377  Standard_Real Last;
378  //we get the curve corresponding to right undisturbed
379  // waterline
380  TopExp_Explorer edge1Explorer(right_undist_water_line, TopAbs_EDGE);
381  TopoDS_Edge edge1 = TopoDS::Edge(edge1Explorer.Current());
382  right_undisturbed_waterline_curve = BRep_Tool::Curve(edge1,L,First,Last);
383  //we get the curve corresponding to left undisturbed
384  // waterline
385  TopLoc_Location L2;
386  Standard_Real First2;
387  Standard_Real Last2;
388  TopExp_Explorer edge2Explorer(left_undist_water_line, TopAbs_EDGE);
389  TopoDS_Edge edge2 = TopoDS::Edge(edge2Explorer.Current());
390  left_undisturbed_waterline_curve = BRep_Tool::Curve(edge2,L2,First2,Last2);
391 
392  gp_Vec V1;
393  gp_Pnt P1;
394  gp_Vec V2;
395  gp_Pnt P2;
396  left_undisturbed_waterline_curve->D1(First,P1,V1);
397  left_undisturbed_waterline_curve->D1(Last,P2,V2);
398  double slope = 0;
399  if (P1.X() > P2.X())
400  slope = fabs(V1.Y()/V1.X());
401  else
402  slope = fabs(V2.Y()/V2.X());
403 
404  //we now find the keel intersections with the xy plane
405  std::vector<gp_Pnt> intPoints(2);
406  //this is the xy plane
407  Handle(Geom_Plane) xyPlane = new Geom_Plane(0.,0.,1.,0.);
408 
409  // here we intersect the keel with
410  // the xy plane
411 
412  TopExp_Explorer edgeExplorer(keel_edge, TopAbs_EDGE);
413  TopoDS_Edge edge = TopoDS::Edge(edgeExplorer.Current());
414  edge.Location(keel_edge.Location());
415  this->reference_loc = keel_edge.Location();
416  this->current_loc = keel_edge.Location();
417  BRepAdaptor_Curve gg_curve(edge);
418  equiv_keel_bspline = BRep_Tool::Curve(edge,L,First,Last);
419  gp_Trsf L_transformation = L.Transformation();
420  TopLoc_Location L_inv = L.Inverted();
421  gp_Trsf L_inv_transformation = L_inv.Transformation();
422 
423  xyPlane->Transform(L_inv.Transformation());
424 
425  TopExp_Explorer edge3Explorer(left_transom_edge, TopAbs_EDGE);
426  TopoDS_Edge edge3 = TopoDS::Edge(edge3Explorer.Current());
427  left_transom_bspline = BRep_Tool::Curve(edge3,L,First,Last);
428  //cout<<First<<" "<<Last<<endl;
429  gp_Pnt pntCtrTrsm;
430  if (left_transom_bspline->Value(First).Z() > left_transom_bspline->Value(Last).Z())
431  pntCtrTrsm = left_transom_bspline->Value(Last);
432  else
433  pntCtrTrsm = left_transom_bspline->Value(First);
434  pntCtrTrsm.Transform(L_transformation);
435  PointCenterTransom = Pnt(pntCtrTrsm);
436  //cout<<"TTEESSTT1: "<<Pnt(left_transom_bspline->Value(Last))<<endl;
437  //cout<<"TTEESSTT2: "<<Pnt(left_transom_bspline->Value(First))<<endl;
438 
439 
440  TopExp_Explorer edge4Explorer(right_transom_edge, TopAbs_EDGE);
441  TopoDS_Edge edge4 = TopoDS::Edge(edge4Explorer.Current());
442  right_transom_bspline = BRep_Tool::Curve(edge4,L,First,Last);
443 
444  GeomAPI_IntCS Intersector(equiv_keel_bspline, xyPlane);
445  int npoints = Intersector.NbPoints();
446 
447  gp_Pnt gpFront(0.0,0.0,0.0);
448  gp_Pnt gpBack(0.0,0.0,0.0);
449  gp_Pnt transomLeft(0.0,0.0,0.0);
450  gp_Pnt transomRight(0.0,0.0,0.0);
451 
452  GeomAPI_IntCS IntersectorLeft(left_transom_bspline, xyPlane);
453  GeomAPI_IntCS IntersectorRight(right_transom_bspline, xyPlane);
454 
455 
456  cout<<"Number of keel intersections with xy plane: "<<npoints<<endl;
457 
458  if (npoints == 2)
459  {
460  is_transom = false;
461  gp_Pnt Point1 = Intersector.Point(1);
462  gp_Pnt Point2 = Intersector.Point(2);
463  Point1.Transform(L_transformation);
464  Point2.Transform(L_transformation);
465  if (Point1.X() < Point2.X())
466  {
467  gpFront = Point1;
468  gpBack = Point2;
469  }
470  else
471  {
472  gpFront = Point2;
473  gpBack = Point1;
474  }
475  boatWetLength = fabs(gpBack.X()-gpFront.X());
476  Point<3> far(50*boatWetLength,0.0,0.0);
477  GC_MakeSegment first_wake(Pnt(far), gpBack);
478  left_wake_bspline = first_wake.Value();
479  right_wake_bspline = first_wake.Value();
480  }
481  else if (npoints == 1)
482  {
483 
484  is_transom = true;
485 
486 
487  if ( (IntersectorLeft.NbPoints() != 1) || (IntersectorRight.NbPoints() != 1))
488  AssertThrow((IntersectorLeft.NbPoints() == 1) && (IntersectorRight.NbPoints() == 1),
489  ExcMessage("Transom edges don't possess a single intersection with horizontal plane!"));
490  cout<<"Transom Point Left: "<<Pnt(IntersectorLeft.Point(1))<<endl;
491  cout<<"Transom Point Right: "<<Pnt(IntersectorRight.Point(1))<<endl;
492  cout<<"Transom Point Center: "<<PointCenterTransom<<endl;
493  transomLeft = IntersectorLeft.Point(1);
494  transomLeft.Transform(L_transformation);
495  transomRight = IntersectorRight.Point(1);
496  transomRight.Transform(L_transformation);
497  gpFront = Intersector.Point(1);
498  gpFront.Transform(L_transformation);
499  gpBack = Pnt(PointCenterTransom);
500  boatWetLength = fabs((transomLeft.X()+transomRight.X())/2.0-gpFront.X());
501  Point<3> junction = (Pnt(transomLeft) + Pnt(transomRight))/2.0;
502  junction(1) = 0.0;
503  junction(0) += Pnt(transomLeft).distance(Pnt(transomRight))/slope;
504  cout<<junction<<endl;
505  Point<3> far(50*boatWetLength,0.0,0.0);
506  GC_MakeSegment first_wake(Pnt(far), Pnt(junction));
507  GC_MakeSegment second_wake_left(Pnt(junction), transomLeft);
508  GC_MakeSegment second_wake_right(Pnt(junction), transomRight);
509  Handle(Geom_Curve) first_wake_curve = first_wake.Value();
510  Handle(Geom_Curve) second_wake_left_curve = second_wake_left.Value();
511  Handle(Geom_Curve) second_wake_right_curve = second_wake_right.Value();
512  Handle(Geom_BoundedCurve) first_wake_bcurve = Handle(Geom_BoundedCurve)::DownCast(first_wake_curve);
513  Handle(Geom_BoundedCurve) second_wake_left_bcurve = Handle(Geom_BoundedCurve)::DownCast(second_wake_left_curve);
514  Handle(Geom_BoundedCurve) second_wake_right_bcurve = Handle(Geom_BoundedCurve)::DownCast(second_wake_right_curve);
515  bool check = false;
516  GeomConvert_CompCurveToBSplineCurve convert_left_wake_bspline(first_wake_bcurve,Convert_TgtThetaOver2);
517  GeomConvert_CompCurveToBSplineCurve convert_right_wake_bspline(first_wake_bcurve,Convert_TgtThetaOver2);
518  check = convert_left_wake_bspline.Add(second_wake_left_bcurve,1e-7,0,1,0);
519  if (check == false)
520  cout<<"Failed joining left wake line"<<endl;
521  left_wake_bspline = convert_left_wake_bspline.BSplineCurve();
522  check = convert_right_wake_bspline.Add(second_wake_right_bcurve,1e-7,0,1,0);
523  if (check == false)
524  cout<<"Failed joining left wake line"<<endl;
525  right_wake_bspline = convert_right_wake_bspline.BSplineCurve();
526  }
527  else
528  {
529  AssertThrow((npoints != 1) && (npoints != 2),
530  ExcMessage("Keel and has no intersection or too many intersections with horizontal plane!"));
531  }
532  //we define the keel arclength and normal projection
533  wake_line_left = new ArclengthProjection(BRepBuilderAPI_MakeEdge(left_wake_bspline));
534  wake_line_right = new ArclengthProjection(BRepBuilderAPI_MakeEdge(right_wake_bspline));
535 
536  cout<<"gpFront: "<<Pnt(gpFront)<<endl;
537  cout<<"gpBack:"<<Pnt(gpBack)<<endl;
538  cout<<"Boat Wet Lenght Lpp: "<<boatWetLength<<endl;
539 
540  //we define the hull surface normal projections
543  //we define the hull surface y direction projections
546  //we define the projection on undisturbed free surface
547  //gp_Pln xy_plane(0.,0.,1.,0.);
548  double xdim = 20*boatWetLength, ydim = 20*boatWetLength;
549  BRepBuilderAPI_MakePolygon polygon;
550  polygon.Add(gp_Pnt(-xdim, -ydim, 0));
551  polygon.Add(gp_Pnt(xdim, -ydim, 0));
552  polygon.Add(gp_Pnt(xdim, ydim, 0));
553  polygon.Add(gp_Pnt(-xdim, ydim, 0));
554  polygon.Close();
555 
556  TopoDS_Wire wire = polygon.Wire();
557  BRepBuilderAPI_MakeFace faceBuilder(wire);
558  undisturbed_water_surface_face = faceBuilder.Face();
560  //we define the corresponding waterline arclength and projection
563  //we define the keel arclength and normal projection
566  //we define the left and right transom arclength projection
569 
570 
571  PointFrontTop = Pnt(gpFront);
572 
573  PointBackTop= Pnt(gpBack);
575  back_keel_length);
576 
578  1.0-front_keel_length);
579 
580  PointLeftTransom = Pnt(transomLeft);
581 
582  PointRightTransom = Pnt(transomRight);
583 
585  middle_keel_length);
586 
587 
588  boat_water_line_right->axis_projection(PointMidTop, Point<3>(0.0,0.0,0.0));
589 
590 
591 
592 }
593 
595 {
596  double rho = 1025.1;
597  double g = 9.81;
598 
599  double z_zero = sink;
600  Point<3> hydrostatic_force(0.0,0.0,0.0);
601  double wet_surface = 0.0;
602  // we will need a quadrature
603  QGauss<2> quad(300);
604  // we now loop over all the CAD faces of sh
605  TopExp_Explorer faceExplorer(sh, TopAbs_FACE);
606  TopoDS_Face face;
607  gp_Pnt Pint;
608  std::vector<bool> to_be_changed;
609  unsigned int face_count = 0;
610  while (faceExplorer.More())
611  {
612  face = TopoDS::Face(faceExplorer.Current());
613  Standard_Real umin, umax, vmin, vmax;
614  BRepTools::UVBounds(face, umin, umax, vmin, vmax); // create surface
615  Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // get surface associated with face
616  // creating a 2d triangulation here with a single cell here with points located on the umin, umax, vmin, vmax boundaries
617  Triangulation<2,2> ref_triangulation;
618 
619  std::vector<Point<2> > ref_vertices;
620  std::vector<CellData<2> > ref_cells;
621  SubCellData ref_subcelldata;
622 
623  ref_vertices.resize(4);
624  ref_vertices[0](0)=umin;
625  ref_vertices[0](1)=vmin;
626  ref_vertices[1](0)=umax;
627  ref_vertices[1](1)=vmin;
628  ref_vertices[2](0)=umin;
629  ref_vertices[2](1)=vmax;
630  ref_vertices[3](0)=umax;
631  ref_vertices[3](1)=vmax;
632 
633  ref_cells.resize(1);
634 
635  ref_cells[0].vertices[0]=0;
636  ref_cells[0].vertices[1]=1;
637  ref_cells[0].vertices[2]=3;
638  ref_cells[0].vertices[3]=2;
639  ref_cells[0].material_id = 1;
640 
641  GridTools::delete_unused_vertices (ref_vertices, ref_cells, ref_subcelldata);
643 
644  ref_triangulation.create_triangulation_compatibility(ref_vertices, ref_cells, ref_subcelldata );
645 
646  // with this triangulation we create a and a FE and a FEValues (the jacobian will account for
647  // transformation from [0,1]x[0,1] to [umin,umax]x[vmin,vmax], we'll have to add the other part)
648 
649  FE_Q<2,2> fe(1);
650  DoFHandler<2,2> ref_dh(ref_triangulation);
651  ref_dh.distribute_dofs(fe);
652 
654  update_values |
655  update_quadrature_points |
656  update_JxW_values);
657 
658  ref_fe_v.reinit(ref_dh.begin_active());
659  const unsigned int n_q_points = ref_fe_v.n_quadrature_points;
660 
661  // we now perform the actual pressure integral over the surface patch
662  const std::vector<Point<2> > &quad_nodes = ref_fe_v.get_quadrature_points();
663  for (unsigned int i=0; i<n_q_points; ++i)
664  {
665  gp_Pnt q;
666  gp_Vec Du, Dv, normal;
667  surf->D1(quad_nodes[i](0),quad_nodes[i](1), q, Du, Dv);
668  double jacobian = Du.CrossMagnitude(Dv);
669  normal = Du^ Dv/jacobian;
670  Point<3> Normal(normal.X(),normal.Y(),normal.Z());
671  // adjusting normal orientation
672  if (face.Orientation()==TopAbs_REVERSED)
673  {
674  Normal*=-1.0;
675  }
676  hydrostatic_force += (rho*g*fmax(z_zero-q.Z(),0.0))*Normal*jacobian*ref_fe_v.JxW(i);
677  if (q.Z() <= z_zero)
678  wet_surface += jacobian*ref_fe_v.JxW(i);
679  //cout<<"q("<<Pnt(q)<<") p:"<<(rho*g*fmax(z_zero-q.Z(),0.0))<<" n("<<Normal<<")"<<endl;
680  }
681  /*
682  // LUCA, HERE I PLACED THE PART WHERE I DEFINE THE TRIANGULATION WITH THE BSPLINE SURFACE KNOTS
683  Triangulation<2,2> bspline_triangulation;
684 
685  std::vector<Point<2> > bspline_vertices;
686  std::vector<CellData<2> > bspline_cells;
687  SubCellData bspline_subcelldata;
688  cout<<"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"<<endl;
689  //BRepBuilderAPI_NurbsConvert nurbs_surf(face);
690  cout<<"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"<<endl;
691  //Handle(Geom_Surface) geom_nurbs_surf = BRepLib_FindSurface(nurbs_surf.Shape()).Surface();
692  Handle(Geom_Surface) geom_nurbs_surf = BRep_Tool::Surface(face);
693  Handle(Geom_BSplineSurface) bspline_surface = GeomConvert::SurfaceToBSplineSurface(geom_nurbs_surf);
694  cout<<"IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII"<<endl;
695  // Set knots and multiplicities
696  TColStd_Array1OfReal UK(1, bspline_surface->NbUKnots());
697  TColStd_Array1OfInteger UM(1, bspline_surface->NbUKnots());
698  TColStd_Array1OfReal VK(1, bspline_surface->NbVKnots());
699  TColStd_Array1OfInteger VM(1, bspline_surface->NbVKnots());
700  cout<<"OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"<<endl;
701  // Get all ingredients
702  bspline_surface->UKnots(UK);
703  bspline_surface->UMultiplicities(UM);
704  bspline_surface->VKnots(VK);
705  bspline_surface->VMultiplicities(VM);
706  int UDegree = bspline_surface->UDegree();
707  bool UPeriodic = bspline_surface->IsUPeriodic();
708  int VDegree = bspline_surface->VDegree();
709  bool VPeriodic = bspline_surface->IsVPeriodic();
710  cout<<"UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU"<<endl;
711  for (int i=0; i<bspline_surface->NbUKnots(); ++i)
712  {
713  cout<<"UK("<<i<<")= "<<UK(i+1)<<" U Multiplicity "<<UM(i+1)<<endl;
714  }
715  for (int i=0; i<bspline_surface->NbVKnots(); ++i)
716  {
717  cout<<"VK("<<i<<")= "<<VK(i+1)<<" V Multiplicity "<<VM(i+1)<<endl;
718  }
719  */
720  /*
721  ref_vertices.resize(4);
722  ref_vertices[0](0)=umin; ref_vertices[0](1)=vmin;
723  ref_vertices[1](0)=umax; ref_vertices[1](1)=vmin;
724  ref_vertices[2](0)=umin; ref_vertices[2](1)=vmax;
725  ref_vertices[3](0)=umax; ref_vertices[3](1)=vmax;
726 
727  ref_cells.resize(1);
728 
729  ref_cells[0].vertices[0]=0; ref_cells[0].vertices[1]=1; ref_cells[0].vertices[2]=3; ref_cells[0].vertices[3]=2;
730  ref_cells[0].material_id = 1;
731  */
732 
733 
734 
735 
736  //GeomLProp_SLProps props(surf, (umin+umax)/2.0, (vmin+vmax)/2.0, 1, 0.01); // get surface normal
737  //gp_Dir norm=props.Normal();
738 
739  faceExplorer.Next();
740  ++face_count;
741  //cout<<"Face count: "<<face_count<<endl;
742  }
743 
744  // we now instead loop over all the CAD faces of refl_sh
745  TopExp_Explorer reflFaceExplorer(refl_sh, TopAbs_FACE);
746 
747  face_count = 0;
748  while (reflFaceExplorer.More())
749  {
750  //Point<3> face_force(0.0,0.0,0.0);
751  face = TopoDS::Face(reflFaceExplorer.Current());
752  Standard_Real umin, umax, vmin, vmax;
753  BRepTools::UVBounds(face, umin, umax, vmin, vmax); // create surface
754  Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // get surface associated with face
755  // creating a 2d triangulation here with a single cell here with points located on the umin, umax, vmin, vmax boundaries
756  Triangulation<2,2> ref_triangulation;
757 
758  std::vector<Point<2> > ref_vertices;
759  std::vector<CellData<2> > ref_cells;
760  SubCellData ref_subcelldata;
761 
762  ref_vertices.resize(4);
763  ref_vertices[0](0)=umin;
764  ref_vertices[0](1)=vmin;
765  ref_vertices[1](0)=umax;
766  ref_vertices[1](1)=vmin;
767  ref_vertices[2](0)=umin;
768  ref_vertices[2](1)=vmax;
769  ref_vertices[3](0)=umax;
770  ref_vertices[3](1)=vmax;
771 
772  ref_cells.resize(1);
773 
774  ref_cells[0].vertices[0]=0;
775  ref_cells[0].vertices[1]=1;
776  ref_cells[0].vertices[2]=3;
777  ref_cells[0].vertices[3]=2;
778  ref_cells[0].material_id = 1;
779 
780  GridTools::delete_unused_vertices (ref_vertices, ref_cells, ref_subcelldata);
782 
783  ref_triangulation.create_triangulation_compatibility(ref_vertices, ref_cells, ref_subcelldata );
784 
785  // with this triangulation we create a and a FE and a FEValues (the jacobian will account for
786  // transformation from [0,1]x[0,1] to [umin,umax]x[vmin,vmax], we'll have to add the other part)
787 
788  FE_Q<2,2> fe(1);
789  DoFHandler<2,2> ref_dh(ref_triangulation);
790  ref_dh.distribute_dofs(fe);
791 
793  update_values |
794  update_quadrature_points |
795  update_JxW_values);
796 
797  ref_fe_v.reinit(ref_dh.begin_active());
798  const unsigned int n_q_points = ref_fe_v.n_quadrature_points;
799 
800  // we now perform the actual pressure integral over the surface patch
801  const std::vector<Point<2> > &quad_nodes = ref_fe_v.get_quadrature_points();
802  for (unsigned int i=0; i<n_q_points; ++i)
803  {
804  gp_Pnt q;
805  gp_Vec Du, Dv, normal;
806  surf->D1(quad_nodes[i](0),quad_nodes[i](1), q, Du, Dv);
807  double jacobian = Du.CrossMagnitude(Dv);
808  normal = (Du^Dv)/jacobian;
809  Point<3> Normal(normal.X(),normal.Y(),normal.Z());
810  // adjusting normal orientation
811  if (face.Orientation()==TopAbs_REVERSED)
812  {
813  Normal*=-1.0;
814  }
815  hydrostatic_force += (rho*g*fmax(z_zero-q.Z(),0.0))*Normal*jacobian*ref_fe_v.JxW(i);
816  if (q.Z() <= z_zero)
817  wet_surface += jacobian*ref_fe_v.JxW(i);
818  //face_force += (rho*g*fmax(z_zero-q.Z(),0.0))*Normal*jacobian*ref_fe_v.JxW(i);
819  //cout<<"q("<<Pnt(q)<<") p:"<<(rho*g*fmax(z_zero-q.Z(),0.0))<<" n("<<Normal<<")"<<endl;
820  }
821 
822  //GeomLProp_SLProps props(surf, (umin+umax)/2.0, (vmin+vmax)/2.0, 1, 0.01); // get surface normal
823  //gp_Dir norm=props.Normal();
824 
825  reflFaceExplorer.Next();
826  ++face_count;
827  //cout<<"Face count: "<<face_count<<" Face force: "<<face_force<<endl;
828  }
829 
830 
831  cout<<"Current hydrostatic force: "<<hydrostatic_force<<" Current wet surface: "<<wet_surface<<endl;
832  boatWetSurface = wet_surface;
833  return hydrostatic_force;
834 }
835 
836 gp_Trsf BoatModel::set_current_position(const Point<3> &translation_vect,
837  const double &quaternion_scalar,
838  const Point<3> &quaternion_vect)
839 {
840 
841  //here we prepare the rotation of the boat of the requested trim angle
842  gp_Quaternion rot_quaternion(quaternion_vect(0), quaternion_vect(1), quaternion_vect(2), quaternion_scalar);
843  gp_Trsf rotation;
844  rotation.SetRotation(rot_quaternion);
845  //we first get the reference transformation applied to the shape
846  TopLoc_Location prev_L = reference_loc;
847  gp_Trsf prev_Transf = prev_L.Transformation();
848 
849  //to apply the rotation, we translate the boat so that its baricenter coincides
850  //with the origin of the reference frame
852  gp_Trsf ref_hull_bar_translation;
853  ref_hull_bar_translation.SetTranslation(ref_hull_bar_displ);
854 
855  // here we prepare the translation of the boat of the requested sink
856  gp_Trsf translation;
857  gp_Vec curr_displ(translation_vect(0),translation_vect(1),translation_vect(2));
858  translation.SetTranslation(curr_displ);
859 
860  // the rotation and translation are combined in a single transformation
861  gp_Trsf this_transf = translation*ref_hull_bar_translation*rotation*ref_hull_bar_translation.Inverted();
862 
863  // the rotation and translation are combined in a single transformation
864  gp_Trsf new_Transf = this_transf*prev_Transf;
865  TopLoc_Location new_L(new_Transf);
866 
867  // the transformation is applied to the two sides of the boat
868  sh.Location(new_L);
869  refl_sh.Location(new_L);
870  right_transom_edge.Location(new_L);
871  left_transom_edge.Location(new_L);
872  keel_edge.Location(new_L);
873  current_loc = new_L;
874 
875  // SHOULD WE PRINT THE EULER ANGLES UP HERE? IS THE FACT WE HAVE A X AXIS
876  // DIRECTED BOW TO STERN GOING TO CHANGE SOMETHING?
877  rot_quaternion.GetEulerAngles(gp_YawPitchRoll, yaw_angle, pitch_angle, roll_angle);
878  cout<<"Current Yaw Angle: "<<yaw_angle<<endl;
879  cout<<"Current Pitch Angle: "<<-pitch_angle+initial_trim<<endl;
880  cout<<"Current Roll Angle: "<<-roll_angle<<endl;
881 
882  gp_Pnt ref_hull_bar_pos = Pnt(reference_hull_baricenter);
883  ref_hull_bar_pos.Transform(this_transf);
884  current_hull_baricenter = Pnt(ref_hull_bar_pos);
885  cout<<"Current Baricenter Position: "<<current_hull_baricenter<<endl;
886 
887  if (is_transom)
888  {
889  // we now want to compute the intersection of the transom edges with the
890  // hull in the current configurations
891  Handle(Geom_Plane) xyPlane = new Geom_Plane(0.,0.,1.,0.);
892 
893  xyPlane->Transform(current_loc.Inverted());
894 
895 
896  //cout<<First<<" "<<Last<<endl;
897  gp_Pnt pntCtrTrsm;
898  if (left_transom_bspline->Value(left_transom_bspline->FirstParameter()).Z() >
899  left_transom_bspline->Value(left_transom_bspline->LastParameter()).Z())
900  pntCtrTrsm = left_transom_bspline->Value(left_transom_bspline->LastParameter());
901  else
902  pntCtrTrsm = left_transom_bspline->Value(left_transom_bspline->FirstParameter());
903  pntCtrTrsm.Transform(current_loc);
904  CurrentPointCenterTransom = Pnt(pntCtrTrsm);
905 
906  gp_Pnt transomLeft(0.0,0.0,0.0);
907  gp_Pnt transomRight(0.0,0.0,0.0);
908 
909  GeomAPI_IntCS IntersectorLeft(left_transom_bspline, xyPlane);
910  GeomAPI_IntCS IntersectorRight(right_transom_bspline, xyPlane);
911  if ( (IntersectorLeft.NbPoints() != 1) || (IntersectorRight.NbPoints() != 1))
912  AssertThrow((IntersectorLeft.NbPoints() == 1) && (IntersectorRight.NbPoints() == 1),
913  ExcMessage("Transom edges don't possess a single intersection with horizontal plane: is transom not immersed any more?"));
914  transomLeft = IntersectorLeft.Point(1);
915  transomRight = IntersectorRight.Point(1);
916 
917  double param;
918  double u;
919  double v;
920 
921  IntersectorLeft.Parameters(1, u, v, param);
922  gp_Vec current_left_transom_tangent_vec = left_transom_bspline->DN(param,1);
923  gp_Dir current_left_transom_tangent_dir(current_left_transom_tangent_vec);
924  current_left_transom_tangent_dir.Transform(current_loc);
925  current_left_transom_tangent = Point<3>(current_left_transom_tangent_dir.X(),
926  current_left_transom_tangent_dir.Y(),
927  current_left_transom_tangent_dir.Z());
928 
929  IntersectorRight.Parameters(1, u, v, param);
930  gp_Vec current_right_transom_tangent_vec = right_transom_bspline->DN(param,1);
931  gp_Dir current_right_transom_tangent_dir(current_right_transom_tangent_vec);
932  current_right_transom_tangent_dir.Transform(current_loc);
933  current_right_transom_tangent = Point<3>(current_right_transom_tangent_dir.X(),
934  current_right_transom_tangent_dir.X(),
935  current_right_transom_tangent_dir.Z());
936 
937  transomLeft.Transform(current_loc);
938  transomRight.Transform(current_loc);
939  CurrentPointLeftTransom = Pnt(transomLeft);
940  CurrentPointRightTransom = Pnt(transomRight);
941 
942  cout<<"Curent Hull Transformation Transom Point Left: "<<CurrentPointLeftTransom<<endl;
943  cout<<"Curent Hull Transformation Transom Point Right: "<<CurrentPointRightTransom<<endl;
944  cout<<"Curent Hull Transformation Transom Point Center: "<<CurrentPointCenterTransom<<endl;
945 
946  }
947 
948 
949 
950 
951 
952  return this_transf;//current_loc.Transformation();
953 }
954 
955 
956 
957 
958 Point<3> BoatModel::compute_hydrostatic_moment(const double &sink, const Point<3> moment_center)
959 {
960  double rho = 1025.1;
961  double g = 9.81;
962 
963  double z_zero = sink;
964  Point<3> hydrostatic_moment(0.0,0.0,0.0);
965  Point<3> hydrostatic_force(0.0,0.0,0.0);
966  double wet_surface = 0.0;
967  // we will need a quadrature
968  QGauss<2> quad(300);
969  // we now loop over all the CAD faces of sh
970  TopExp_Explorer faceExplorer(sh, TopAbs_FACE);
971  TopoDS_Face face;
972  gp_Pnt Pint;
973  std::vector<bool> to_be_changed;
974  unsigned int face_count = 0;
975  while (faceExplorer.More())
976  {
977  face = TopoDS::Face(faceExplorer.Current());
978  Standard_Real umin, umax, vmin, vmax;
979  BRepTools::UVBounds(face, umin, umax, vmin, vmax); // create surface
980  Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // get surface associated with face
981  // creating a 2d triangulation here with a single cell here with points located on the umin, umax, vmin, vmax boundaries
982  Triangulation<2,2> ref_triangulation;
983 
984  std::vector<Point<2> > ref_vertices;
985  std::vector<CellData<2> > ref_cells;
986  SubCellData ref_subcelldata;
987 
988  ref_vertices.resize(4);
989  ref_vertices[0](0)=umin;
990  ref_vertices[0](1)=vmin;
991  ref_vertices[1](0)=umax;
992  ref_vertices[1](1)=vmin;
993  ref_vertices[2](0)=umin;
994  ref_vertices[2](1)=vmax;
995  ref_vertices[3](0)=umax;
996  ref_vertices[3](1)=vmax;
997 
998  ref_cells.resize(1);
999 
1000  ref_cells[0].vertices[0]=0;
1001  ref_cells[0].vertices[1]=1;
1002  ref_cells[0].vertices[2]=3;
1003  ref_cells[0].vertices[3]=2;
1004  ref_cells[0].material_id = 1;
1005 
1006  GridTools::delete_unused_vertices (ref_vertices, ref_cells, ref_subcelldata);
1008 
1009  ref_triangulation.create_triangulation_compatibility(ref_vertices, ref_cells, ref_subcelldata);
1010 
1011  // with this triangulation we create a DH and a FE and a FEValues (the jacobian will account for
1012  // transformation from [0,1]x[0,1] to [umin,umax]x[vmin,vmax], we'll have to add the other part)
1013 
1014  FE_Q<2,2> fe(1);
1015  DoFHandler<2,2> ref_dh(ref_triangulation);
1016  ref_dh.distribute_dofs(fe);
1017 
1018  FEValues<2,2> ref_fe_v(StaticMappingQ1<2,2>::mapping, fe,quad,
1019  update_values |
1020  update_quadrature_points |
1021  update_JxW_values);
1022 
1023  ref_fe_v.reinit(ref_dh.begin_active());
1024  const unsigned int n_q_points = ref_fe_v.n_quadrature_points;
1025 
1026  // we now perform the actual pressure integral over the surface patch
1027  const std::vector<Point<2> > &quad_nodes = ref_fe_v.get_quadrature_points();
1028  for (unsigned int i=0; i<n_q_points; ++i)
1029  {
1030  gp_Pnt q;
1031  gp_Vec Du, Dv, normal;
1032  surf->D1(quad_nodes[i](0),quad_nodes[i](1), q, Du, Dv);
1033  double jacobian = Du.CrossMagnitude(Dv);
1034  normal = Du^ Dv/jacobian;
1035  Point<3> Normal(normal.X(),normal.Y(),normal.Z());
1036  // adjusting normal orientation
1037  if (face.Orientation()==TopAbs_REVERSED)
1038  {
1039  Normal*=-1.0;
1040  }
1041  Point<3> Q(q.X()-moment_center(0),q.Y()-moment_center(1),q.Z()-moment_center(2));
1042  Point<3> Kross(Q(1)*Normal(2)-Q(2)*Normal(1),Q(2)*Normal(0)-Q(0)*Normal(2),Q(0)*Normal(1)-Q(1)*Normal(0));
1043  hydrostatic_moment += (rho*g*fmax(z_zero-q.Z(),0.0))*Kross*jacobian*ref_fe_v.JxW(i);
1044  hydrostatic_force += (rho*g*fmax(z_zero-q.Z(),0.0))*Normal*jacobian*ref_fe_v.JxW(i);
1045  //cout<<"q("<<Pnt(q)<<") p:"<<(rho*g*fmax(z_zero-q.Z(),0.0))<<" n("<<Normal<<")"<<endl;
1046  }
1047 
1048 
1049 
1050  //GeomLProp_SLProps props(surf, (umin+umax)/2.0, (vmin+vmax)/2.0, 1, 0.01); // get surface normal
1051  //gp_Dir norm=props.Normal();
1052 
1053  faceExplorer.Next();
1054  ++face_count;
1055  //cout<<"Face count: "<<face_count<<endl;
1056  }
1057 
1058  // we now instead loop over all the CAD faces of refl_sh
1059  TopExp_Explorer reflFaceExplorer(refl_sh, TopAbs_FACE);
1060 
1061  face_count = 0;
1062  while (reflFaceExplorer.More())
1063  {
1064  //Point<3> face_force(0.0,0.0,0.0);
1065  face = TopoDS::Face(reflFaceExplorer.Current());
1066  Standard_Real umin, umax, vmin, vmax;
1067  BRepTools::UVBounds(face, umin, umax, vmin, vmax); // create surface
1068  Handle(Geom_Surface) surf=BRep_Tool::Surface(face); // get surface associated with face
1069  // creating a 2d triangulation here with a single cell here with points located on the umin, umax, vmin, vmax boundaries
1070  Triangulation<2,2> ref_triangulation;
1071 
1072  std::vector<Point<2> > ref_vertices;
1073  std::vector<CellData<2> > ref_cells;
1074  SubCellData ref_subcelldata;
1075 
1076  ref_vertices.resize(4);
1077  ref_vertices[0](0)=umin;
1078  ref_vertices[0](1)=vmin;
1079  ref_vertices[1](0)=umax;
1080  ref_vertices[1](1)=vmin;
1081  ref_vertices[2](0)=umin;
1082  ref_vertices[2](1)=vmax;
1083  ref_vertices[3](0)=umax;
1084  ref_vertices[3](1)=vmax;
1085 
1086  ref_cells.resize(1);
1087 
1088  ref_cells[0].vertices[0]=0;
1089  ref_cells[0].vertices[1]=1;
1090  ref_cells[0].vertices[2]=3;
1091  ref_cells[0].vertices[3]=2;
1092  ref_cells[0].material_id = 1;
1093 
1094  GridTools::delete_unused_vertices (ref_vertices, ref_cells, ref_subcelldata);
1096 
1097  ref_triangulation.create_triangulation_compatibility(ref_vertices, ref_cells, ref_subcelldata );
1098 
1099  // with this triangulation we create a and a FE and a FEValues (the jacobian will account for
1100  // transformation from [0,1]x[0,1] to [umin,umax]x[vmin,vmax], we'll have to add the other part)
1101 
1102  FE_Q<2,2> fe(1);
1103  DoFHandler<2,2> ref_dh(ref_triangulation);
1104  ref_dh.distribute_dofs(fe);
1105 
1106  FEValues<2,2> ref_fe_v(StaticMappingQ1<2,2>::mapping, fe,quad,
1107  update_values |
1108  update_quadrature_points |
1109  update_JxW_values);
1110 
1111  ref_fe_v.reinit(ref_dh.begin_active());
1112  const unsigned int n_q_points = ref_fe_v.n_quadrature_points;
1113 
1114  // we now perform the actual pressure integral over the surface patch
1115  const std::vector<Point<2> > &quad_nodes = ref_fe_v.get_quadrature_points();
1116  for (unsigned int i=0; i<n_q_points; ++i)
1117  {
1118  gp_Pnt q;
1119  gp_Vec Du, Dv, normal;
1120  surf->D1(quad_nodes[i](0),quad_nodes[i](1), q, Du, Dv);
1121  double jacobian = Du.CrossMagnitude(Dv);
1122  normal = (Du^Dv)/jacobian;
1123  Point<3> Normal(normal.X(),normal.Y(),normal.Z());
1124 
1125  // adjusting normal orientation
1126  if (face.Orientation()==TopAbs_REVERSED)
1127  {
1128  Normal*=-1.0;
1129  }
1130  Point<3> Q(q.X()-moment_center(0),q.Y()-moment_center(1),q.Z()-moment_center(2));
1131  Point<3> Kross(Q(1)*Normal(2)-Q(2)*Normal(1),Q(2)*Normal(0)-Q(0)*Normal(2),Q(0)*Normal(1)-Q(1)*Normal(0));
1132  hydrostatic_moment += (rho*g*fmax(z_zero-q.Z(),0.0))*Kross*jacobian*ref_fe_v.JxW(i);
1133  hydrostatic_force += (rho*g*fmax(z_zero-q.Z(),0.0))*Normal*jacobian*ref_fe_v.JxW(i);
1134 
1135  //face_force += (rho*g*fmax(z_zero-q.Z(),0.0))*Normal*jacobian*ref_fe_v.JxW(i);
1136  //cout<<"q("<<Pnt(q)<<") p:"<<(rho*g*fmax(z_zero-q.Z(),0.0))<<" n("<<Normal<<")"<<endl;
1137  }
1138 
1139  //GeomLProp_SLProps props(surf, (umin+umax)/2.0, (vmin+vmax)/2.0, 1, 0.01); // get surface normal
1140  //gp_Dir norm=props.Normal();
1141 
1142  reflFaceExplorer.Next();
1143  ++face_count;
1144  //cout<<"Face count: "<<face_count<<" Face force: "<<face_force<<endl;
1145  }
1146 
1147 
1148  cout<<"Current hydrostatic moment: "<<hydrostatic_moment<<endl;
1149  cout<<"(Force is): "<<hydrostatic_force<<endl;
1150  return hydrostatic_moment;
1151 }
1152 
1153 
1154 void BoatModel::compute_hydrostatic_sink(double &sink, const double &weight)
1155 {
1156  double delta_sink = 0.001;
1157  double delta_z;
1158  Point<3> hydrostatic_force;
1159  Point<3> hydrostatic_force_n_minus_2 = compute_hydrostatic_force(0.0);
1160  Point<3> hydrostatic_force_n_minus_1 = compute_hydrostatic_force(delta_sink);
1161  double z;
1162  double z_n_minus_1 = delta_sink;
1163  double z_n_minus_2 = 0.0;
1164 
1165  while (fabs(hydrostatic_force(2)-weight)/weight > 1e-7)
1166  {
1167  double slope = (hydrostatic_force_n_minus_1(2)-hydrostatic_force_n_minus_2(2))/(z_n_minus_1-z_n_minus_2);
1168  z = z_n_minus_1 - (hydrostatic_force_n_minus_1(2)-weight)/slope;
1169  z_n_minus_2 = z_n_minus_1;
1170  z_n_minus_1 = z;
1171  hydrostatic_force = compute_hydrostatic_force(z);
1172  hydrostatic_force_n_minus_2 = hydrostatic_force_n_minus_1;
1173  hydrostatic_force_n_minus_1 = hydrostatic_force;
1174 //cout<<"z: "<<z<<" hydrostatic force: "<<hydrostatic_force<<" check: "<<fabs(hydrostatic_force(2)-weight)/weight<<endl;
1175  }
1176 
1177  sink = z;
1178 
1179 
1180 
1181  cout<<"z: "<<z<<" hydrostatic force (out): "<<hydrostatic_force<<" (weight: "<<weight<<")"<<endl;
1182 }
1183 
1184 class BoatModel;
Point< 3 > hydrostatic_hull_baricenter
Definition: boat_model.h:156
Point< 3 > current_hull_baricenter
Definition: boat_model.h:162
double boat_mass
Definition: boat_model.h:149
TopLoc_Location reference_loc
Definition: boat_model.h:102
double roll_angle
Definition: boat_model.h:170
Point< 3 > PointFrontBot
Definition: boat_model.h:55
active_cell_iterator begin_active(const unsigned int level=0) const
Handle(Geom_Curve) equiv_keel_bspline
OpenCascade::ArclengthProjection * water_line_right
Definition: boat_model.h:129
Point< 3 > CurrentPointCenterTransom
Definition: boat_model.h:70
OpenCascade::NormalProjection< 2 > * boat_surface_left
Definition: boat_model.h:109
bool is_transom
Definition: boat_model.h:147
Point< 3 > PointBackBot
Definition: boat_model.h:64
Point< 3 > arclength_projection(const Point< 3 > &p0, const Point< 3 > &p1, const double distance=.5) const
OpenCascade::NormalProjection< 1 > * boat_keel_norm
Definition: boat_model.h:119
double boatWetSurface
Definition: boat_model.h:83
#define AssertThrow(cond, exc)
OpenCascade::NormalProjection< 2 > * boat_surface_right
Definition: boat_model.h:107
OpenCascade::ArclengthProjection * wake_line_right
Definition: boat_model.h:127
Point< 3 > PointBackTop
Definition: boat_model.h:62
Point< 3 > reference_hull_baricenter
Definition: boat_model.h:159
double initial_trim
Definition: boat_model.h:166
Point< 3 > CurrentPointLeftTransom
Definition: boat_model.h:73
Point< 3 > PointLeftTransom
Definition: boat_model.h:66
static::ExceptionBase & ExcMessage(std::string arg1)
const std::vector< Point< spacedim > > & get_quadrature_points() const
Point< 3 > compute_hydrostatic_moment(const double &sink, const Point< 3 > moment_center)
Definition: boat_model.cc:958
static void reorder_cells(std::vector< CellData< dim > > &original_cells, const bool use_new_style_ordering=false)
TopoDS_Shape right_undist_water_line
Definition: boat_model.h:95
OpenCascade::ArclengthProjection * boat_keel
Definition: boat_model.h:117
OpenCascade::ArclengthProjection * boat_transom_right
Definition: boat_model.h:123
Point< 3 > CurrentPointRightTransom
Definition: boat_model.h:76
TopoDS_Shape undisturbed_water_surface_face
Definition: boat_model.h:99
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
TopoDS_Shape left_transom_edge
Definition: boat_model.h:93
double pitch_angle
Definition: boat_model.h:169
OpenCascade::AxisProjection * boat_water_line_right
Definition: boat_model.h:111
const unsigned int n_quadrature_points
gp_Trsf set_current_position(const Point< 3 > &translation_vect, const double &quaternion_scalar, const Point< 3 > &quaternion_vect)
Definition: boat_model.cc:836
double norm(const FEValuesBase< dim > &fe, const VectorSlice< const std::vector< std::vector< Tensor< 1, dim > > > > &Du)
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
OpenCascade::ArclengthProjection * water_line_left
Definition: boat_model.h:131
TopoDS_Shape right_transom_edge
Definition: boat_model.h:91
Point< 3 > current_right_transom_tangent
Definition: boat_model.h:153
virtual void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
double initial_sink
Definition: boat_model.h:164
void delete_unused_vertices(std::vector< Point< spacedim > > &vertices, std::vector< CellData< dim > > &cells, SubCellData &subcelldata)
TopoDS_Shape extract_transom_edges(const TopoDS_Shape &in_shape, const unsigned int num_transom_edges, const double tolerance)
TopoDS_Shape refl_sh
Definition: boat_model.h:87
We collect in this namespace all utilities which operate on OpenCascade entities which don't need cla...
TopoDS_Shape read_IGES(string filename, double scale_factor)
Read IGES files and translate.
double yaw_angle
Definition: boat_model.h:168
void compute_hydrostatic_sink(double &sink, const double &weight)
Definition: boat_model.cc:1154
TopoDS_Shape left_undist_water_line
Definition: boat_model.h:97
OpenCascade::AxisProjection * boat_water_line_left
Definition: boat_model.h:113
Point< 3 > compute_hydrostatic_force(const double &sink)
Definition: boat_model.cc:594
TopoDS_Shape ReverseFaceOrientation(const TopoDS_Shape &shape, const TopoDS_Face &face)
Definition: boat_model.cc:154
void intersect_plane(const TopoDS_Shape &in_shape, TopoDS_Shape &out_shape, const double c_x, const double c_y, const double c_z, const double c, const double tolerance)
Perform the intersection of the.
double boatWetLength
Definition: boat_model.h:81
Point< 3 > PointMidTop
Definition: boat_model.h:58
TopLoc_Location current_loc
Definition: boat_model.h:105
Point< 3 > PointMidBot
Definition: boat_model.h:60
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell)
void L2(Vector< number > &result, const FEValuesBase< dim > &fe, const std::vector< double > &input, const double factor=1.)
Point< 3 > PointRightTransom
Definition: boat_model.h:68
TopoDS_Shape sh
Definition: boat_model.h:85
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)
TopoDS_Shape extract_xz_edges(const TopoDS_Shape &in_shape, const double tolerance, const unsigned int max_num_edges)
Point< 3 > PointCenterTransom
Definition: boat_model.h:79
OpenCascade::AxisProjection * undist_water_surf
Definition: boat_model.h:115
Point< 3 > current_left_transom_tangent
Definition: boat_model.h:151
TopoDS_Shape keel_edge
Definition: boat_model.h:89
Point< 3 > PointFrontTop
Definition: boat_model.h:53
OpenCascade::ArclengthProjection * wake_line_left
Definition: boat_model.h:125