WaveBEM: Unsteady Nonlinear Potential Flow Solver for Ship-Wave Interaction.
free_surface.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, Andrea Mola
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 
27 //#include <deal.II/lac/vector.h>
28 //#include <deal.II/lac/sparse_direct.h>
29 //#include <deal.II/lac/constraint_matrix.h>
30 //#include <deal.II/lac/solver_cg.h>
31 //#include <deal.II/lac/vector_view.h>
32 //#include <deal.II/grid/grid_refinement.h>
33 //#include <deal.II/numerics/matrices.h>
34 
35 #include <Sacado.hpp>
36 #include "../include/free_surface.h"
37 #include "../include/restart_nonlinear_problem_diff.h"
38 #include "../include/restart_nonlinear_problem_alg.h"
39 #include "newton_solver.h"
40 
43 
44 #include <GeomPlate_BuildPlateSurface.hxx>
45 #include <GeomPlate_PointConstraint.hxx>
46 #include <GeomPlate_MakeApprox.hxx>
47 #include <Geom_Surface.hxx>
48 #include <BRepBuilderAPI_MakeFace.hxx>
49 #include <GeomPlate_Surface.hxx>
50 #include <BRepAdaptor_Curve.hxx>
51 
52 typedef Sacado::Fad::DFad<double> fad_double;
53 
54 using namespace dealii;
55 using namespace OpenCascade;
56 
57 
58 template <int dim>
60 {
61 
62  prm.declare_entry("Output file name", "waveResult", Patterns::Anything());
63  prm.declare_entry("Remeshing period", "1", Patterns::Double());
64  prm.declare_entry("Dumping period", "1", Patterns::Double());
65  prm.declare_entry("Restore from file", "", Patterns::Anything());
66  prm.declare_entry("Keep BEM in sync with geometry", "true", Patterns::Bool());
67 
68  prm.declare_entry("Is x-translation imposed", "true", Patterns::Bool());
69  prm.enter_subsection("Hull x-axis translation");
70  {
72  prm.set("Function expression", "0");
73  }
74  prm.leave_subsection();
75 
76  prm.declare_entry("Is y-translation imposed", "true", Patterns::Bool());
77  prm.enter_subsection("Hull y-axis translation");
78  {
80  prm.set("Function expression", "0");
81  }
82  prm.leave_subsection();
83 
84  prm.declare_entry("Is z-translation imposed", "true", Patterns::Bool());
85  prm.enter_subsection("Hull z-axis translation");
86  {
88  prm.set("Function expression", "0");
89  }
90  prm.leave_subsection();
91 
92  prm.enter_subsection("Wind function 2d");
93  {
95  prm.set("Function expression", "1; 1");
96  }
97  prm.leave_subsection();
98 
99  prm.enter_subsection("Wind function 3d");
100  {
102  prm.set("Function expression", "1; 1; 1");
103  }
104  prm.leave_subsection();
105 
106  prm.enter_subsection("Initial Wave Shape 2d");
107  {
109  prm.set("Function expression", "0");
110  }
111  prm.leave_subsection();
112 
113  prm.enter_subsection("Initial Wave Shape 3d");
114  {
116  prm.set("Function expression", "0");
117  }
118  prm.leave_subsection();
119 
120  prm.enter_subsection("Initial Wave Potential 2d");
121  {
123  prm.set("Function expression", "0");
124  }
125  prm.leave_subsection();
126 
127  prm.enter_subsection("Initial Wave Potential 3d");
128  {
130  prm.set("Function expression", "0");
131  }
132  prm.leave_subsection();
133 
134  prm.enter_subsection("Initial Wave Normal Potential Gradient 2d");
135  {
137  prm.set("Function expression", "0");
138  }
139  prm.leave_subsection();
140 
141  prm.enter_subsection("Initial Wave Normal Potential Gradient 3d");
142  {
144  prm.set("Function expression", "0");
145  }
146  prm.leave_subsection();
147 
148  prm.enter_subsection("Inflow Normal Potential Gradient 2d");
149  {
151  prm.set("Function expression", "0");
152  }
153  prm.leave_subsection();
154 
155  prm.enter_subsection("Inflow Normal Potential Gradient 3d");
156  {
158  prm.set("Function expression", "0");
159  }
160  prm.leave_subsection();
161 
162  prm.declare_entry("Node displacement type", "lagrangian",
163  Patterns::Selection("lagrangian|semilagrangian"));
164 
165 
166  prm.enter_subsection("Local Refinement");
167 
168  prm.declare_entry("Maximum number of dofs", "4500",
170 
171  prm.declare_entry("Coarsening fraction", ".1",
172  Patterns::Double());
173 
174  prm.declare_entry("Refinement fraction", ".3",
175  Patterns::Double());
176 
177  prm.declare_entry("Adaptive refinement limit", "2.0",
178  Patterns::Double());
179 
180  prm.leave_subsection();
181 
182 
183  prm.enter_subsection("Solver");
185  prm.leave_subsection();
186 
187 }
188 
189 template <int dim>
191 {
192 
193  output_file_name = prm.get("Output file name");
194  remeshing_period = prm.get_double("Remeshing period");
195  dumping_period = prm.get_double("Dumping period");
196 
197  restore_filename = prm.get("Restore from file");
198  initial_condition_from_dump = (restore_filename != "");
199 
200  sync_bem_with_geometry = prm.get_bool("Keep BEM in sync with geometry");
201 
202  prm.enter_subsection(std::string("Wind function ")+
203  Utilities::int_to_string(dim)+std::string("d"));
204  {
205  wind.parse_parameters(prm);
206  }
207  prm.leave_subsection();
208 
209  is_hull_x_translation_imposed = prm.get_bool("Is x-translation imposed");
210  prm.enter_subsection("Hull x-axis translation");
211  {
212  hull_x_axis_translation.parse_parameters(prm);
213  }
214  prm.leave_subsection();
215 
216  is_hull_y_translation_imposed = prm.get_bool("Is y-translation imposed");
217  prm.enter_subsection("Hull y-axis translation");
218  {
219  hull_y_axis_translation.parse_parameters(prm);
220  }
221  prm.leave_subsection();
222 
223  is_hull_z_translation_imposed = prm.get_bool("Is z-translation imposed");
224  prm.enter_subsection("Hull z-axis translation");
225  {
226  hull_z_axis_translation.parse_parameters(prm);
227  }
228  prm.leave_subsection();
229 
230  prm.enter_subsection(std::string("Initial Wave Shape ")+
231  Utilities::int_to_string(dim)+std::string("d"));
232  {
233  initial_wave_shape.parse_parameters(prm);
234  }
235  prm.leave_subsection();
236 
237  prm.enter_subsection(std::string("Initial Wave Potential ")+
238  Utilities::int_to_string(dim)+std::string("d"));
239  {
240  initial_wave_potential.parse_parameters(prm);
241  }
242  prm.leave_subsection();
243 
244  prm.enter_subsection(std::string("Initial Wave Normal Potential Gradient ")+
245  Utilities::int_to_string(dim)+std::string("d"));
246  {
247  initial_norm_potential_grad.parse_parameters(prm);
248  }
249  prm.leave_subsection();
250 
251  prm.enter_subsection(std::string("Inflow Normal Potential Gradient ")+
252  Utilities::int_to_string(dim)+std::string("d"));
253  {
254  inflow_norm_potential_grad.parse_parameters(prm);
255  }
256  prm.leave_subsection();
257 
258  node_displacement_type = prm.get("Node displacement type");
259 
260  prm.enter_subsection("Solver");
261  solver_control.parse_parameters(prm);
262  prm.leave_subsection();
263 
264 
265  prm.enter_subsection("Local Refinement");
266 
267  max_number_of_dofs = prm.get_integer("Maximum number of dofs");
268  coarsening_fraction = prm.get_double("Coarsening fraction");
269  refinement_fraction = prm.get_double("Refinement fraction");
270  adaptive_ref_limit = prm.get_double("Adaptive refinement limit");
271 
272  prm.leave_subsection();
273 
274 }
275 
276 
277 template <int dim>
279 {
280 
281  dofs_number = comp_dom.vector_dh.n_dofs() + // nodes positions
282  comp_dom.dh.n_dofs() + // nodes potential
283  comp_dom.dh.n_dofs() + // nodes normal potential grandient
284  6 + // these are the dofs needed for hull rigid velocities and displacements
285  7; // these are the dofs needed for hull rigid angular velocities and quaternions
286 
287  DXDt_and_DphiDt_vector.reinit(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
288 
289 
290  // we initialize here all the
291  // sparsity patterns
292 
293  compute_constraints(constraints, vector_constraints);
294 
295  DphiDt_sparsity_pattern.reinit (comp_dom.dh.n_dofs(),
296  comp_dom.dh.n_dofs(),
297  comp_dom.dh.max_couplings_between_dofs());
298  vector_sparsity_pattern.reinit (comp_dom.vector_dh.n_dofs(),
299  comp_dom.vector_dh.n_dofs(),
300  comp_dom.vector_dh.max_couplings_between_dofs());
301 
302 
303  DoFTools::make_sparsity_pattern (comp_dom.dh, DphiDt_sparsity_pattern, constraints);
304  DphiDt_sparsity_pattern.compress();
305 
306  DoFTools::make_sparsity_pattern (comp_dom.vector_dh, vector_sparsity_pattern, vector_constraints);
307  vector_sparsity_pattern.compress();
308 
309 
310  working_map_points.reinit (comp_dom.vector_dh.n_dofs());
311  working_nodes_velocities.reinit(comp_dom.vector_dh.n_dofs());
312  nodes_pos_res.reinit(comp_dom.vector_dh.n_dofs());
313  nodes_ref_surf_dist.reinit(comp_dom.vector_dh.n_dofs());
314  nodes_diff_jac_x_delta.reinit(dofs_number);
315  nodes_alg_jac_x_delta.reinit(dofs_number);
316  dae_nonlin_residual.reinit(dofs_number);
317  dae_linear_step_residual.reinit(dofs_number);
318  current_sol.reinit(dofs_number);
319  current_sol_dot.reinit(dofs_number);
320  bem_residual.reinit(comp_dom.dh.n_dofs());
321  bem_phi.reinit(comp_dom.dh.n_dofs());
322  bem_dphi_dn.reinit(comp_dom.dh.n_dofs());
323  temp_src.reinit(comp_dom.vector_dh.n_dofs());
324  break_wave_press.reinit(comp_dom.dh.n_dofs());
325  // we initialize the rhs evaluations counter
326  rhs_evaluations_counter = 0;
327 }
328 
329 
330 template <int dim>
332 {
333 
334  // da trattare il caso di dumped solution (continuazione conto salvato)
335  initial_time = 0.0;
336  initial_wave_shape.set_time(initial_time);
337  initial_wave_potential.set_time(initial_time);
338  initial_norm_potential_grad.set_time(initial_time);
339  inflow_norm_potential_grad.set_time(initial_time);
340  wind.set_time(initial_time);
341 
342  dst.reinit(dofs_number);
343 
344  Point<1> time(initial_time);
345  Point<1> delta_t(1e-5);
346 
347  if (is_hull_x_translation_imposed)
348  {
349  restart_hull_displacement(0) = hull_x_axis_translation.value(time);
350  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3) = restart_hull_displacement(0);
351  //double vel = ( hull_x_axis_translation.value(time+delta_t) -
352  // hull_x_axis_translation.value(time+(-1.0*delta_t)) ) / 2.0 / delta_t(0);
353  double vel = 0.0;
354  cout<<"VELX: "<<vel<<endl;
355  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()) = vel;
356  }
357  else
358  restart_hull_displacement(0) = 0.0;
359 
360  if (is_hull_y_translation_imposed)
361  {
362  restart_hull_displacement(1) = hull_y_axis_translation.value(time);
363  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+4) = restart_hull_displacement(1);
364  //double vel = ( hull_y_axis_translation.value(time+delta_t) -
365  // hull_y_axis_translation.value(time+(-1.0*delta_t)) ) / 2.0 / delta_t(0);
366  double vel = 0.0;
367  cout<<"VELY: "<<vel<<endl;
368  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+1) = vel;
369  }
370  else
371  restart_hull_displacement(1) = 0.0;
372 
373  if (is_hull_z_translation_imposed)
374  {
375  restart_hull_displacement(2) = hull_z_axis_translation.value(time);
376  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+5) = restart_hull_displacement(2);
377  double vel = ( hull_z_axis_translation.value(time+delta_t) -
378  hull_z_axis_translation.value(time+(-1.0*delta_t)) ) / 2.0 / delta_t(0);
379  //double vel = 0.0; //0.01*2.0*dealii::numbers::PI*cos(2.0*dealii::numbers::PI*initial_time);
380  cout<<"VELZ: "<<vel<<endl;
381  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+2) = vel;
382  }
383  else
384  restart_hull_displacement(2) = 0.0;
385 
386  Point<3> init_omega(0.0,0.0,0.0);
387  Point<3> quaternion_vect(0.0,0,0.0);
388  double quaternion_scalar = 1.0;
389  for (unsigned int d=0; d<3; ++d)
390  {
391  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d) = init_omega(d);
392  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d) = quaternion_vect(d);
393  }
394  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12) = quaternion_scalar;
395 
396  gp_Trsf curr_transf = comp_dom.boat_model.set_current_position(restart_hull_displacement,
397  quaternion_scalar,
398  quaternion_vect);
399 
400  restart_hull_location = curr_transf;
401  restart_transom_center_point = comp_dom.boat_model.CurrentPointCenterTransom;
402  restart_transom_left_point = comp_dom.boat_model.CurrentPointLeftTransom;
403  restart_transom_right_point = comp_dom.boat_model.CurrentPointRightTransom;
404  restart_transom_left_tangent = comp_dom.boat_model.current_left_transom_tangent;
405  restart_transom_right_tangent = comp_dom.boat_model.current_right_transom_tangent;
406 
407 
408  Vector<double> instantWindValue(dim);
409  Point<dim> zero(0,0,0);
410  wind.vector_value(zero,instantWindValue);
411  Point<dim> Vinf;
412  for (unsigned int i = 0; i < dim; i++)
413  Vinf(i) = instantWindValue(i);
414  std::cout<<std::endl<<"Initial conditions: simulation time= "<<initial_time<<" Vinf= ";
415  instantWindValue.print(std::cout,4,false,true);
416 
417  std::vector<Point<dim> > support_points(comp_dom.dh.n_dofs());
418  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.dh, support_points);
419  std::vector<Point<dim> > vector_support_points(comp_dom.vector_dh.n_dofs());
420  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.vector_dh, vector_support_points);
421 
422 
423  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
424  {
425  if ((comp_dom.flags[i] & water) ||
426  (comp_dom.flags[i] & near_water) )
427  comp_dom.map_points(3*i+2) = initial_wave_shape.value(vector_support_points[3*i]);
428  }
429 
430  unsigned int j = dim-1;
431  Vector<double> geom_res(comp_dom.vector_dh.n_dofs());
432  if (!comp_dom.no_boat)
433  comp_dom.evaluate_ref_surf_distances(geom_res,false);
434 
435  //enforce_full_geometry_constraints(); //*********************
436  //comp_dom.update_support_points(); //*******************
437 
438  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
439  {
440  comp_dom.map_points(i) -= geom_res(i);
441  }
442 
443  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom)
444  {
445  comp_dom.update_support_points();
446 
447  double transom_draft = fabs(comp_dom.boat_model.CurrentPointCenterTransom(2));
448  double transom_aspect_ratio = (fabs(comp_dom.boat_model.CurrentPointLeftTransom(1))+
449  fabs(comp_dom.boat_model.CurrentPointRightTransom(1)))/transom_draft;
450 
451  wind.set_time(100000000.0);
452  Vector<double> instantWindValueTinf(dim);
453  Point<dim> zero(0,0,0);
454  wind.vector_value(zero,instantWindValueTinf);
455  Point<dim> VinfTinf;
456  for (unsigned int i = 0; i < dim; i++)
457  VinfTinf(i) = instantWindValueTinf(i);
458  wind.set_time(initial_time);
459 
460  double FrT = sqrt(VinfTinf*VinfTinf)/sqrt(9.81*transom_draft);
461  double ReT = sqrt(9.81*pow(transom_draft,3.0))/1.307e-6;
462  double eta_dry = fmin(0.05*pow(FrT,2.834)*pow(transom_aspect_ratio,0.1352)*pow(ReT,0.01338),1.0);
463  double lh = 0.0;
464  //if (eta_dry < 1.0)
465  lh = 5.0;
466  //lh = 0.1135*pow(FrT,3.025)*pow(transom_aspect_ratio,0.4603)*pow(ReT,-0.1514);
467  //lh = 0.3265*pow(FrT,3.0) - 1.7216*pow(FrT,2.0) + 2.7593*FrT;
468  cout<<"FrT: "<<FrT<<" Tar: "<<transom_aspect_ratio<<" ReT: "<<ReT<<endl;
469  cout<<"****eta_dry: "<<eta_dry<<endl;
470 
471 
472  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
473  {
474  if ( (comp_dom.support_points[i](1) < comp_dom.boat_model.CurrentPointRightTransom(1)) &&
475  (comp_dom.support_points[i](1) >= 0.0) &&
476  (comp_dom.support_points[i](0) > comp_dom.boat_model.CurrentPointCenterTransom(0)-fabs(comp_dom.boat_model.CurrentPointCenterTransom(2)) ) &&
477  (comp_dom.support_points[i](0) < comp_dom.boat_model.CurrentPointCenterTransom(0)+lh*fabs(comp_dom.boat_model.CurrentPointCenterTransom(2)) ) &&
478  (comp_dom.support_points[i](2) > 2.0*comp_dom.boat_model.CurrentPointCenterTransom(2)) )
479  {
480  Point <3> dP0 = comp_dom.support_points[i];
481  Point <3> dP;
482  //this is the vertical plane
483  Handle(Geom_Plane) vertPlane = new Geom_Plane(0.,1.,0.,-dP0(1));
484  vertPlane->Transform(comp_dom.boat_model.current_loc.Inverted());
485  Handle(Geom_Curve) curve = comp_dom.boat_model.right_transom_bspline;
486 
487  GeomAPI_IntCS Intersector(curve, vertPlane);
488  int npoints = Intersector.NbPoints();
489  AssertThrow((npoints != 0), ExcMessage("Transom curve is not intersecting with vertical plane!"));
490  //cout<<"Number of intersections: "<<npoints<<endl;
491  double minDistance=1e7;
492  for (int j=0; j<npoints; ++j)
493  {
494  gp_Pnt int_point = Intersector.Point(j+1);
495  int_point.Transform(comp_dom.boat_model.current_loc);
496  Point<3> inters = Pnt(int_point);
497 
498  if (dP0.distance(inters) < minDistance)
499  {
500  minDistance = dP0.distance(inters);
501  dP = inters;
502  }
503  }
504 
505  if ( (comp_dom.support_points[i](0) > dP(0)+comp_dom.min_diameter/20.0) &&
506  (comp_dom.support_points[i](0) < dP(0)+lh*fabs(dP(2))+comp_dom.min_diameter/20.0) )
507  {
508  //cout<<"££££ "<<dP<<endl;
509  double mean_curvature;
510  Point<3> normal;
511  Point<3> projection;
512  comp_dom.boat_model.boat_surface_right->normal_projection_and_diff_forms(projection,
513  normal,
514  mean_curvature,
515  dP);
516  //cout<<dP0<<" curve--> "<<dP<<" surface--> "<<projection<<" ("<<dP.distance(projection)<<")"<<endl;
517  AssertThrow((dP.distance(projection) < 1e-4*comp_dom.boat_model.boatWetLength), ExcMessage("Normal projection for surface normal evaluation went wrong!"));
518  double transom_slope = -normal(0)/normal(2);
519  double a = -transom_slope/(lh*fabs(dP(2))) - 1/dP(2)/lh/lh;
520  double x = comp_dom.support_points[i](0)-dP(0);
521  comp_dom.initial_map_points(3*i+2) = a*x*x + transom_slope*x + dP(2);
522  comp_dom.map_points(3*i+2) = comp_dom.initial_map_points(3*i+2);
523  //cout<<"****** "<<comp_dom.initial_map_points(3*i+2)<<" TS: "<<transom_slope<<" a "<<a<<" x "<<x<<endl;
524  }
525  }
526  else if ( (comp_dom.support_points[i](1) > comp_dom.boat_model.CurrentPointLeftTransom(1)) &&
527  (comp_dom.support_points[i](1) < 0.0) &&
528  (comp_dom.support_points[i](0) > comp_dom.boat_model.CurrentPointCenterTransom(0)-fabs(comp_dom.boat_model.CurrentPointCenterTransom(2))) &&
529  (comp_dom.support_points[i](0) < comp_dom.boat_model.CurrentPointCenterTransom(0)+lh*fabs(comp_dom.boat_model.CurrentPointCenterTransom(2))) &&
530  (comp_dom.support_points[i](2) > 2.0*comp_dom.boat_model.CurrentPointCenterTransom(2)) )
531  {
532  Point <3> dP0 = comp_dom.support_points[i];
533  Point <3> dP;
534  //this is the vertical plane
535  Handle(Geom_Plane) vertPlane = new Geom_Plane(0.,1.,0.,-dP0(1));
536  vertPlane->Transform(comp_dom.boat_model.current_loc.Inverted());
537  Handle(Geom_Curve) curve = comp_dom.boat_model.left_transom_bspline;
538 
539  GeomAPI_IntCS Intersector(curve, vertPlane);
540  int npoints = Intersector.NbPoints();
541  AssertThrow((npoints != 0), ExcMessage("Transom curve is not intersecting with vertical plane!"));
542  //cout<<"Number of intersections: "<<npoints<<endl;
543  double minDistance=1e7;
544  for (int j=0; j<npoints; ++j)
545  {
546  gp_Pnt int_point = Intersector.Point(j+1);
547  int_point.Transform(comp_dom.boat_model.current_loc);
548  Point<3> inters = Pnt(int_point);
549 
550  if (dP0.distance(inters) < minDistance)
551  {
552  minDistance = dP0.distance(inters);
553  dP = inters;
554  }
555  }
556  if ( (comp_dom.support_points[i](0) > dP(0)+comp_dom.min_diameter/20.0) &&
557  (comp_dom.support_points[i](0) < dP(0)+lh*fabs(dP(2))+comp_dom.min_diameter/20.0) )
558  {
559  double mean_curvature;
560  Point<3> normal;
561  Point<3> projection;
562  comp_dom.boat_model.boat_surface_left->normal_projection_and_diff_forms(projection,
563  normal,
564  mean_curvature,
565  dP);
566  AssertThrow((dP.distance(projection) < 1e-4*comp_dom.boat_model.boatWetLength), ExcMessage("Normal projection for surface normal evaluation went wrong!"));
567  double transom_slope = -normal(0)/normal(2);
568  double a = -transom_slope/(lh*fabs(dP(2))) - 1/dP(2)/lh/lh;
569  double x = comp_dom.support_points[i](0)-dP(0);
570  comp_dom.initial_map_points(3*i+2) = a*x*x + transom_slope*x + dP(2);
571  comp_dom.map_points(3*i+2) = comp_dom.initial_map_points(3*i+2);
572  //cout<<"@@@@@@ "<<comp_dom.initial_map_points(3*i+2)<<" TS: "<<transom_slope<<" a "<<a<<" x "<<x<<endl;
573  }
574  }
575  }
576  comp_dom.vector_constraints.distribute(comp_dom.initial_map_points);
577  comp_dom.vector_constraints.distribute(comp_dom.map_points);
578 
579  }
580 
581 
582 
583 
584  double min_diameter = 1000000000;
585  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
586  update_JxW_values);
587  const unsigned int DphiDt_n_q_points = fe_v.n_quadrature_points;
588  cell_it
589  cell = comp_dom.dh.begin_active(),
590  endc = comp_dom.dh.end();
591 
592  for (; cell!=endc; ++cell)
593  {
594  if ((cell->material_id() == comp_dom.free_sur_ID1 ||
595  cell->material_id() == comp_dom.free_sur_ID2 ||
596  cell->material_id() == comp_dom.free_sur_ID3 ))
597  {
598  fe_v.reinit(cell);
599  double area=0;
600  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
601  {
602  area += fe_v.JxW(q);
603  }
604  min_diameter = fmin(min_diameter,2*sqrt(area/3.1415));
605  }
606  }
607 
608  cout<<"Min Diameter Corrected: "<<min_diameter<<endl;
609 
610  std::vector<Point<dim> > displaced_support_points(comp_dom.dh.n_dofs());
611  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.dh, displaced_support_points);
612 
613  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
614  {
615  dst(i+comp_dom.vector_dh.n_dofs()) = initial_wave_potential.value(displaced_support_points[i]);
616  //std::cout<<i+comp_dom.vector_dh.n_dofs()<<" "<<dst(i+comp_dom.vector_dh.n_dofs())<<std::endl;
617  }
618 
619  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
620  {
621  dst(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) =
622  initial_norm_potential_grad.value(displaced_support_points[i]);
623  //std::cout<<i+comp_dom.vector_dh.n_dofs()<<" "<<dst(i+comp_dom.vector_dh.n_dofs())<<std::endl;
624  }
625 
627  Vector<double> bem_phi(comp_dom.dh.n_dofs());
628  Vector<double> bem_dphi_dn(comp_dom.dh.n_dofs());
629 
630 
631 
632 
633  //cout<<"AFTER "<<endl;
634  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
635  // if (constraints.is_constrained(i))
636  // cout<<i<<" "<<src_yy(i+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs())<<endl;
637 
638 
639  Vector<double> surface_nodes_backup = comp_dom.surface_nodes;
640  Vector<double> other_nodes_backup = comp_dom.other_nodes;
641 
642  comp_dom.surface_nodes = 0.0;
643  comp_dom.other_nodes = 1.0;
644 
645  comp_dom.compute_normals_at_nodes(comp_dom.map_points);
646  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
647  {
648  if ((comp_dom.flags[i] & water) || (comp_dom.flags[i] & boat))
649  {
650  bem_dphi_dn(i) = -comp_dom.node_normals[i]*Vinf;
651  if ( comp_dom.flags[i] & transom_on_water )
652  {
653  comp_dom.surface_nodes(i) = 0;
654  comp_dom.other_nodes(i) = 1;
655  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
656  duplicates.erase(i);
657  double bem_bc = 0;
658 
659  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
660  {
661  bem_bc += bem_dphi_dn(*pos)/duplicates.size();
662  }
663  bem_dphi_dn(i) = bem_bc;
664  }
665  }
666  else if
667  (comp_dom.flags[i] & inflow)
668  {
669  bem_dphi_dn(i) = inflow_norm_potential_grad.value(support_points[i]);
670  //cout<<i<<" "<<" Point: "<<support_points[i]<<" BC Val: "<<inflow_norm_potential_grad.value(support_points[i])<<endl;
671  }
672  else
673  {
674  comp_dom.surface_nodes(i) = 1.0;
675  comp_dom.other_nodes(i) = 0.0;
676  bem_phi(i) = 0.0;
677  }
678  }
679  Vector<double> bem_bc(bem_dphi_dn);
680 
681 
682  bem.solve(bem_phi, bem_dphi_dn, bem_bc);
683 
684  comp_dom.surface_nodes = surface_nodes_backup;
685  comp_dom.other_nodes = other_nodes_backup;
686 
687  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
688  {
689  dst(i+comp_dom.vector_dh.n_dofs()) = bem_phi(i);
690  dst(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = bem_dphi_dn(i);
691  }
692 
693 
695 
696 
697 
698 
699 //*/
700  comp_dom.initial_map_points = comp_dom.map_points;
701  vector_constraints.distribute(comp_dom.map_points);
702 
703 
704  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
705  {
706  dst(i) = comp_dom.map_points(i);
707  //std::cout<<i<<" "<<dst(i)<<std::endl;
708  }
709 
710 
711  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
712  {
713  if ( ((comp_dom.flags[i] & boat) &&
714  !(comp_dom.flags[i] & near_water) ) ||
715  (comp_dom.flags[i] & transom_on_water) )
716  {
717  dst(3*i) -= restart_hull_displacement(0);
718  dst(3*i+1) -= restart_hull_displacement(1);
719  dst(3*i+2) -= restart_hull_displacement(2);
720  }
721  }
722 
723 
724 
725 
726 
727 // on the boat surface the normal potential must respect the boundary conditions (dphi_dn=-Vinf*n)
728  std::vector<unsigned int> local_dof_indices (comp_dom.fe.dofs_per_cell);
729 
730  cell = comp_dom.dh.begin_active(),
731  endc = comp_dom.dh.end();
732 
733  for (; cell!=endc; ++cell)
734  {
735  cell->get_dof_indices(local_dof_indices);
736  if (cell->material_id() == comp_dom.wall_sur_ID1 ||
737  cell->material_id() == comp_dom.wall_sur_ID2 ||
738  cell->material_id() == comp_dom.wall_sur_ID3 )
739  for (unsigned int j=0; j<comp_dom.fe.dofs_per_cell; ++j)
740  {
741  unsigned int id=local_dof_indices[j];
743  // needs to be changed
744  //Point<3> original(displaced_support_points[id](0),fabs(displaced_support_points[id](1)),displaced_support_points[id](2));
745  //Point<3> projection;
746  //Point<3> normal;
747  //double mean_curvature;
748  //comp_dom.boat_model.boat_water_line_right->axis_projection_and_diff_forms(projection, normal, mean_curvature, original);
749  //double b = displaced_support_points[id](1) < 0.0 ? -1.0 : 1.0;
750  //projection(1)*=b;
751  //normal(1)*=b;
752 
753  //BoatSurface<3> boat_surface;
754  //Point<3> normal2 = boat_surface.HullNormal(displaced_support_points[id]);
755  //std::cout<<std::endl;
756  //std::cout<<"Point "<<displaced_support_points[id]<<std::endl;
757  //std::cout<<"NormalNew "<<normal<<std::endl;
758  //std::cout<<"NormalExact "<<normal2<<std::endl;
760  //dst(id+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = -comp_dom.iges_normals[id]*Vinf;
761  Point<3> Vhull(dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()),
762  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+1),
763  dst(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+2));
764  dst(id+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = -comp_dom.node_normals[id]*(Vinf-Vhull);
765  }
766  }
767 
768 
769 
770  max_x_coor_value = 0;
771  max_y_coor_value = 0;
772  max_z_coor_value = 0;
773  for (unsigned int i=0; i < comp_dom.dh.n_dofs(); i++)
774  {
775  //for printout
776  //std::cout<<"Node "<<i<< "["<<support_points(i)<<"] "<<std::endl;
777  max_x_coor_value = std::max(max_x_coor_value,std::abs(displaced_support_points[i](0)));
778  max_y_coor_value = std::max(max_y_coor_value,std::abs(displaced_support_points[i](1)));
779  max_z_coor_value = std::max(max_z_coor_value,std::abs(displaced_support_points[i](2)));
780  }
781 
782  DphiDt_sys_solution.reinit (comp_dom.dh.n_dofs());
783  DphiDt_sys_solution_2.reinit (comp_dom.dh.n_dofs());
784  DphiDt_sys_solution_3.reinit (comp_dom.dh.n_dofs());
785  break_wave_press.reinit (comp_dom.dh.n_dofs());
786 
787  vector_sys_solution.reinit (comp_dom.vector_dh.n_dofs());
788  vector_sys_solution_2.reinit (comp_dom.vector_dh.n_dofs());
789 
790  Vector<double> dummy_sol_dot(dst.size());
791 
792 
793 
794 
795  std::string filename = ( output_file_name + "_" +
797  ".vtu" );
798  //Vector<double> dummy_sol_dot(dst.size());
799  output_results(filename, 0, dst, dummy_sol_dot);
800 
801  comp_dom.old_map_points = comp_dom.map_points;
802  comp_dom.rigid_motion_map_points = 0;
803 
804  last_remesh_time = 0;
805 
806  current_sol = dst;
807  current_sol_dot = 0.0;
808  current_time = 0.0;
809 
810 
811 
812  restart_flag = false;
813 
814 
815  // we have to compute the reference transom wet surface with the new mesh here
816  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom)
817  {
818  double transom_wet_surface = 0;
819  std::vector<Point<3> > vertices;
820  std::vector<CellData<2> > cells;
821  for (tria_it elem=comp_dom.tria.begin_active(); elem!= comp_dom.tria.end(); ++elem)
822  {
823  if ((elem->material_id() == comp_dom.wall_sur_ID1 ||
824  elem->material_id() == comp_dom.wall_sur_ID2 ||
825  elem->material_id() == comp_dom.wall_sur_ID3 ))
826  {
827  if (elem->at_boundary())
828  {
829  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
830  if ( elem->face(f)->boundary_id() == 32 ||
831  elem->face(f)->boundary_id() == 37 )
832  {
833  unsigned int index_0 = comp_dom.find_point_id(elem->face(f)->vertex(0),comp_dom.ref_points);
834  unsigned int index_1 = comp_dom.find_point_id(elem->face(f)->vertex(1),comp_dom.ref_points);
835  if (comp_dom.ref_points[3*index_1](1) < comp_dom.ref_points[3*index_0](1))
836  {
837  vertices.push_back(comp_dom.ref_points[3*index_0]);
838  vertices.push_back(comp_dom.ref_points[3*index_1]);
839  vertices.push_back(comp_dom.ref_points[3*index_1]+
840  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_1](2)));
841  vertices.push_back(comp_dom.support_points[index_0]+
842  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_0](2)));
843  cells.resize(cells.size()+1);
844  cells[cells.size()-1].vertices[0]=4*(cells.size()-1)+0;
845  cells[cells.size()-1].vertices[1]=4*(cells.size()-1)+1;
846  cells[cells.size()-1].vertices[2]=4*(cells.size()-1)+2;
847  cells[cells.size()-1].vertices[3]=4*(cells.size()-1)+3;
848  }
849  else
850  {
851  vertices.push_back(comp_dom.support_points[index_1]);
852  vertices.push_back(comp_dom.support_points[index_0]);
853  vertices.push_back(comp_dom.support_points[index_0]+
854  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_0](2)));
855  vertices.push_back(comp_dom.support_points[index_1]+
856  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_1](2)));
857  cells.resize(cells.size()+1);
858  cells[cells.size()-1].vertices[0]=4*(cells.size()-1)+0;
859  cells[cells.size()-1].vertices[1]=4*(cells.size()-1)+1;
860  cells[cells.size()-1].vertices[2]=4*(cells.size()-1)+2;
861  cells[cells.size()-1].vertices[3]=4*(cells.size()-1)+3;
862  }
863  }
864  }
865  }
866  }
867 
868 
869  SubCellData subcelldata;
870  Triangulation<dim-1, dim> transom_tria;
871  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
873  transom_tria.create_triangulation_compatibility(vertices, cells, subcelldata );
874  FE_Q<dim-1,dim> transom_fe(1);
875  DoFHandler<dim-1,dim> transom_dh(transom_tria);
876  transom_dh.distribute_dofs(transom_fe);
877 
878  FEValues<dim-1,dim> transom_fe_v(transom_fe, *comp_dom.quadrature,
879  update_values | update_gradients |
880  update_cell_normal_vectors |
881  update_quadrature_points |
882  update_JxW_values);
883 
884  const unsigned int transom_n_q_points = transom_fe_v.n_quadrature_points;
885 
886 
887  std::vector<double> transom_pressure_quad_values(transom_n_q_points);
888  for (cell_it cell = transom_dh.begin_active(); cell!=transom_dh.end(); ++cell)
889  {
890  transom_fe_v.reinit(cell);
891 
892  for (unsigned int q=0; q<transom_n_q_points; ++q)
893  {
894  transom_wet_surface += 1 * transom_fe_v.JxW(q);
895  }
896  }
897  ref_transom_wet_surface = transom_wet_surface;
898  }
899 
900  // here we finally compute the reference cell areas, which are needed
901  // to evaluate boat cell deformations and possibly activate smoothing
902  //FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
903  // update_JxW_values);
904  //const unsigned int DphiDt_n_q_points = fe_v.n_quadrature_points;
905  ref_cell_areas.reinit(comp_dom.tria.n_active_cells());
906  cell = comp_dom.dh.begin_active(),
907  endc = comp_dom.dh.end();
908 
909  unsigned int count=0;
910  for (; cell!=endc; ++cell)
911  {
912  if ((cell->material_id() == comp_dom.wall_sur_ID1 ||
913  cell->material_id() == comp_dom.wall_sur_ID2 ||
914  cell->material_id() == comp_dom.wall_sur_ID3 ))
915  {
916  fe_v.reinit(cell);
917  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
918  {
919  ref_cell_areas(count) += 1.0 * fe_v.JxW(q);
920  }
921  }
922  ++count;
923  }
924 
925  cout<<"££££2 "<<comp_dom.map_points[2067]<<endl;
926 
927 }
928 
929 
930 template <int dim>
931 unsigned int FreeSurface<dim>:: n_dofs() const
932 {
933 
934  return dofs_number;
935 
936 }
937 
938 template <int dim>
940  const unsigned int step_number)
941 {
942  std::cout<<"iteration: "<<step_number<<std::endl;
943  std::cout<<std::endl;
944 
945  std::string filename = ( output_file_name + "_" +
946  Utilities::int_to_string(step_number+1) +
947  ".vtu" );
948  output_results(filename, current_time, solution, current_sol_dot);
949 
950  ofstream waterLineFile;
951  waterLineFile.open ((output_file_name+"_water_line.txt").c_str());
952  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
953  if ((comp_dom.flags[i] & water) && (comp_dom.flags[i] & near_boat) && (!(comp_dom.flags[i] & transom_on_water)))
954  waterLineFile<<comp_dom.support_points[i]<<endl;
955  waterLineFile.close();
956 
957 }
958 
959 
960 template <int dim>
962  Vector<double> &solution_dot,
963  const double t,
964  const unsigned int step_number,
965  const double h)
966 {
967  std::cout<<"t = "<<t<<" TS = "<<step_number<<std::endl;
968  std::cout<<std::endl;
969 
970  std::string filename = ( output_file_name + "_" +
971  Utilities::int_to_string(step_number+1) +
972  ".vtu" );
973  output_results(filename, t, solution, solution_dot);
974 
975  ofstream waterLineFile;
976  waterLineFile.open ((output_file_name+"_water_line.txt").c_str());
977  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
978  if ((comp_dom.flags[i] & water) && (comp_dom.flags[i] & near_boat) && (!(comp_dom.flags[i] & transom_on_water)))
979  waterLineFile<<comp_dom.support_points[i]<<endl;
980  waterLineFile.close();
981 
982 }
983 
984 
985 
986 typedef std::pair<double,unsigned int> mypair;
987 bool comparator ( const mypair &l, const mypair &r)
988 {
989  return l.first < r.first;
990 }
991 
992 template <int dim>
994  Vector<double> &solution_dot,
995  const double t,
996  const unsigned int step_number,
997  const double h)
998 {
999 
1000 
1001 
1002  static unsigned int remeshing_counter = 1;
1003  static unsigned int dumping_counter = 1;
1004 
1005  if ( t>=dumping_period*dumping_counter )
1006  {
1007  std::string fname = output_file_name + "_dump_" +
1008  Utilities::int_to_string(dumping_counter);
1009  ++dumping_counter;
1010  dump_solution(solution, solution_dot, fname);
1011  }
1012 
1013  if ( t>=remeshing_period*remeshing_counter && comp_dom.dh.n_dofs() < max_number_of_dofs )
1014  {
1015  ++remeshing_counter;
1016  std::cout<<"Checking and updating mesh..."<<std::endl;
1017 
1018 
1019  // first thing to do is update the geometry to the current positon
1020  Point<3> current_hull_displacement;
1021  Point<3> current_hull_displacement_dot;
1022  Point<3> current_hull_velocity;
1023  Point<3> current_hull_velocity_dot;
1024  Point<3> current_hull_ang_velocity;
1025  Point<3> current_hull_ang_velocity_dot;
1026  Point<3> current_hull_quat_vector;
1027  Point<3> current_hull_quat_vector_dot;
1028  for (unsigned int k=0; k<3; ++k)
1029  {
1030  current_hull_displacement(k) = solution(k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1031  current_hull_displacement_dot(k) = solution_dot(k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1032  current_hull_velocity(k) = solution(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1033  current_hull_velocity_dot(k) = solution_dot(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1034  current_hull_ang_velocity(k) = solution(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1035  current_hull_ang_velocity_dot(k) = solution_dot(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1036  current_hull_quat_vector(k) = solution(k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1037  current_hull_quat_vector_dot(k) = solution_dot(k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1038  }
1039  double current_hull_quat_scalar = solution(12+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1040  double current_hull_quat_scalar_dot = solution_dot(12+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
1041 
1042  restart_hull_displacement(0) = current_hull_displacement(0);
1043  restart_hull_displacement(1) = current_hull_displacement(1);
1044  restart_hull_displacement(2) = current_hull_displacement(2);
1045  restart_hull_quat_vector(0) = current_hull_quat_vector(0);
1046  restart_hull_quat_vector(1) = current_hull_quat_vector(1);
1047  restart_hull_quat_vector(2) = current_hull_quat_vector(2);
1048  restart_hull_quat_scalar = current_hull_quat_scalar;
1049 
1050 
1051  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
1052  // mesh (all nodes except for the free surface ones)
1053  Vector<double> rigid_motion_velocities(comp_dom.vector_dh.n_dofs());
1054 
1055  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
1056  // mesh (all nodes except for the free surface ones)
1057  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
1058  {
1059  if ( ((comp_dom.flags[i] & boat) &&
1060  !(comp_dom.flags[i] & near_water) ) ||
1061  (comp_dom.flags[i] & transom_on_water) )
1062  {
1063  //if (fabs(t-0.2) <1e-5)
1064  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
1065  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
1066  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
1067  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
1068  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
1069  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
1070  gp_Pnt boat_mesh_point = original_boat_mesh_point;
1071  // we first take this point (which is in the RESTART hull location) and transform it to be in the
1072  // REFERENCE configuration
1073  boat_mesh_point.Transform(restart_hull_location.Inverted());
1074 
1075  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
1076  // the 7 dofs associated to the rigid linear and angular displacements
1077 
1078  double s_x = restart_hull_displacement(0);
1079  double s_y = restart_hull_displacement(1);
1080  double s_z = restart_hull_displacement(2);
1081  double v_x = restart_hull_quat_vector(0);
1082  double v_y = restart_hull_quat_vector(1);
1083  double v_z = restart_hull_quat_vector(2);
1084  double s = restart_hull_quat_scalar;
1085 
1086  Point<3> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
1087  comp_dom.boat_model.reference_hull_baricenter(1),
1088  comp_dom.boat_model.reference_hull_baricenter(2));
1089 
1090  Point<3> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
1091  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
1092  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
1093 
1094  Point<3> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
1095  Point<3> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
1096  Point<3> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
1097 
1098  Point<3> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
1099  Point<3> rigid_lin_displ(s_x,s_y,s_z);
1100  Point<3> target_point_pos(RotMatRow1*(ref_point_pos+(-1.0)*ref_baricenter_pos),
1101  RotMatRow2*(ref_point_pos+(-1.0)*ref_baricenter_pos),
1102  RotMatRow3*(ref_point_pos+(-1.0)*ref_baricenter_pos));
1103  target_point_pos += baricenter_pos;
1104  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
1105  //boat_mesh_point.Transform(reference_to_current_transformation);
1106  // the rigid motion map points is the difference between the reference point position and the
1107  // current (rigidly displaced) node position
1108  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0)-ref_point_pos(0);
1109  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1)-ref_point_pos(1);
1110  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2)-ref_point_pos(2);
1111 
1112  rigid_motion_velocities(3*i) = current_hull_velocity(0)+
1113  current_hull_ang_velocity(1)*(target_point_pos(2)-baricenter_pos(2))-
1114  current_hull_ang_velocity(2)*(target_point_pos(1)-baricenter_pos(1));
1115  rigid_motion_velocities(3*i+1) = current_hull_velocity(1)+
1116  current_hull_ang_velocity(2)*(target_point_pos(0)-baricenter_pos(0))-
1117  current_hull_ang_velocity(0)*(target_point_pos(2)-baricenter_pos(2));
1118  rigid_motion_velocities(3*i+2) = current_hull_velocity(2)+
1119  current_hull_ang_velocity(0)*(target_point_pos(1)-baricenter_pos(1))-
1120  current_hull_ang_velocity(1)*(target_point_pos(0)-baricenter_pos(0));
1121 
1122 
1123  //if (fabs(t-0.2) <1e-5)
1124  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
1125  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
1126  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
1127  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
1128  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
1129  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
1130  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
1131  }
1132  }
1133 
1134  restart_hull_location = comp_dom.boat_model.set_current_position(restart_hull_displacement,
1135  restart_hull_quat_scalar,
1136  restart_hull_quat_vector);
1137  restart_transom_center_point = comp_dom.boat_model.CurrentPointCenterTransom;
1138  restart_transom_left_point = comp_dom.boat_model.CurrentPointLeftTransom;
1139  restart_transom_right_point = comp_dom.boat_model.CurrentPointRightTransom;
1140  restart_transom_left_tangent = comp_dom.boat_model.current_left_transom_tangent;
1141  restart_transom_right_tangent = comp_dom.boat_model.current_right_transom_tangent;
1142 
1143  //std::string filename1 = ( "preRemesh.vtu" );
1144  //output_results(filename1, t, solution, solution_dot);
1145 
1146  Triangulation<dim-1, dim> &tria = comp_dom.tria;
1147  DoFHandler<dim-1, dim> &dh = comp_dom.dh;
1148  DoFHandler<dim-1, dim> &vector_dh = comp_dom.vector_dh;
1149 
1150  std::vector<Point<dim> > support_points(comp_dom.dh.n_dofs());
1151  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.dh, support_points);
1152 
1153  Vector <double> disp_vector(comp_dom.vector_dh.n_dofs());
1154  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
1155  {
1156  for (unsigned int j=0; j<dim; ++j)
1157  disp_vector(i*dim+j) = support_points[i][j];
1158  }
1159 
1160  VectorView<double> Phi(dh.n_dofs(), solution.begin()+vector_dh.n_dofs());
1161  VectorView<double> Phi_dot(dh.n_dofs(), solution_dot.begin()+vector_dh.n_dofs());
1162  VectorView<double> dphi_dn(dh.n_dofs(), solution.begin()+vector_dh.n_dofs()+dh.n_dofs());
1163  VectorView<double> dphi_dn_dot(dh.n_dofs(), solution_dot.begin()+vector_dh.n_dofs()+dh.n_dofs());
1164 
1165  std::vector<Point<3> > old_points(dh.n_dofs());
1166  old_points = support_points;
1167 
1168  Vector<double> curvatures(vector_dh.n_dofs());
1169  comp_dom.compute_curvatures(curvatures);
1170 
1171 
1172  Vector<float> estimated_error_per_cell(tria.n_active_cells());
1173 
1174  QGauss<dim-2> quad(2);
1175 
1176  VectorView<double> displacements(vector_dh.n_dofs(), solution.begin());
1177  Vector <double> elevations(dh.n_dofs());
1178 
1179  for (unsigned int i=0; i<dh.n_dofs(); ++i)
1180  if (comp_dom.flags[i] & water)
1181  elevations(i) = displacements(3*i+2);
1182 // KellyErrorEstimator<dim-1,dim>::estimate (dh,
1183 // quad,
1184 // typename FunctionMap<dim>::type(),
1185 // elevations,
1186 // estimated_error_per_cell);
1187 
1188 
1189 // if (t>4.5)
1190 // comp_dom.n_cycles = 0;
1191 
1192  if (t < 0.0)
1193  {
1194  VectorView<double> displacements_dot(vector_dh.n_dofs(), solution_dot.begin());
1196  quad,
1197  typename FunctionMap<dim>::type(),
1198  (const Vector<double> &)displacements_dot,
1199  estimated_error_per_cell);
1200  }
1201  else
1202  {
1203 // KellyErrorEstimator<dim-1,dim>::estimate (vector_dh,
1204 // quad,
1205 // typename FunctionMap<dim>::type(),
1206 // (const Vector<double>&)displacements,
1207 // estimated_error_per_cell);
1209  quad,
1210  typename FunctionMap<dim>::type(),
1211  elevations,
1212  estimated_error_per_cell);
1213  }
1214 
1215 
1216  double max_boat_error = 0;
1217  double max_other_error = 0;
1218  unsigned int counter=0;
1219  for (cell_it elem=dh.begin_active(); elem!= dh.end(); ++elem)
1220  {
1221  if ((elem->material_id() == comp_dom.wall_sur_ID1 ||
1222  elem->material_id() == comp_dom.wall_sur_ID2 ||
1223  elem->material_id() == comp_dom.wall_sur_ID3 ))
1224  {
1225  max_boat_error = fmax(max_boat_error,estimated_error_per_cell(counter));
1226  }
1227  else
1228  max_other_error = fmax(max_other_error,estimated_error_per_cell(counter));
1229  ++counter;
1230  }
1231 
1232  counter = 0;
1233  for (cell_it elem=dh.begin_active(); elem!= dh.end(); ++elem)
1234  {
1235  if ((elem->material_id() == comp_dom.wall_sur_ID1 ||
1236  elem->material_id() == comp_dom.wall_sur_ID2 ||
1237  elem->material_id() == comp_dom.wall_sur_ID3 ))
1238  estimated_error_per_cell(counter) /= fmax(max_boat_error,1e-6);
1239  else
1240  estimated_error_per_cell(counter) /= fmax(max_other_error,1e-6);
1241  ++counter;
1242  }
1243 
1244 
1245  SolutionTransfer<dim-1, Vector<double>, DoFHandler<dim-1, dim> > soltrans(dh);
1246 
1247 
1248  Vector<double> positions_x(comp_dom.dh.n_dofs());
1249  Vector<double> positions_y(comp_dom.dh.n_dofs());
1250  Vector<double> positions_z(comp_dom.dh.n_dofs());
1251  Vector<double> positions_dot_x(comp_dom.dh.n_dofs());
1252  Vector<double> positions_dot_y(comp_dom.dh.n_dofs());
1253  Vector<double> positions_dot_z(comp_dom.dh.n_dofs());
1254 
1255  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
1256  {
1257  positions_x(i) = solution(3*i+0)+comp_dom.rigid_motion_map_points(3*i+0)+comp_dom.ref_points[3*i](0);
1258  positions_y(i) = solution(3*i+1)+comp_dom.rigid_motion_map_points(3*i+1)+comp_dom.ref_points[3*i](1);
1259  positions_z(i) = solution(3*i+2)+comp_dom.rigid_motion_map_points(3*i+2)+comp_dom.ref_points[3*i](2);
1260  positions_dot_x(i) = solution_dot(3*i+0)+rigid_motion_velocities(3*i+0);
1261  positions_dot_y(i) = solution_dot(3*i+1)+rigid_motion_velocities(3*i+1);
1262  positions_dot_z(i) = solution_dot(3*i+2)+rigid_motion_velocities(3*i+2);
1263  }
1264 
1265 
1266  std::vector<Vector<double> > all_in;
1267  all_in.push_back((Vector<double>)Phi);
1268  all_in.push_back((Vector<double>)Phi_dot);
1269  all_in.push_back((Vector<double>)dphi_dn);
1270  all_in.push_back((Vector<double>)dphi_dn_dot);
1271  all_in.push_back(positions_x);
1272  all_in.push_back(positions_y);
1273  all_in.push_back(positions_z);
1274  all_in.push_back(positions_dot_x);
1275  all_in.push_back(positions_dot_y);
1276  all_in.push_back(positions_dot_z);
1277 
1278 
1280  estimated_error_per_cell,
1281  refinement_fraction,
1282  coarsening_fraction,
1283  max_number_of_dofs);
1284 // GridRefinement::refine_and_coarsen_optimize (tria,
1285 // estimated_error_per_cell);
1286 
1287 
1288 
1289  // here we compute the cell diameters, which are needed
1290  // to limit cell refinement to bigger cells
1291  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
1292  update_JxW_values);
1293  const unsigned int n_q_points = fe_v.n_quadrature_points;
1294  Vector<double> cell_diameters(comp_dom.tria.n_active_cells());
1295  cell_it
1296  cell = comp_dom.dh.begin_active(),
1297  endc = comp_dom.dh.end();
1298 
1299  counter=0;
1300  for (; cell!=endc; ++cell)
1301  {
1302  fe_v.reinit(cell);
1303  for (unsigned int q=0; q<n_q_points; ++q)
1304  {
1305  cell_diameters(counter) += fe_v.JxW(q);
1306  }
1307  cell_diameters(counter) = 2*sqrt(cell_diameters(counter)/3.1415);
1308  ++counter;
1309  }
1310 
1311  counter=0;
1312  if (comp_dom.n_cycles == 0)
1313  {
1314  for (cell_it elem=dh.begin_active(); elem!= dh.end(); ++elem)
1315  {
1316  if (cell_diameters(counter)*8.0/2.0 < comp_dom.min_diameter)
1317  elem->clear_refine_flag();
1318 
1319  if (fabs(elem->center()(0)) > 20.0)
1320  elem->clear_refine_flag();
1321 
1322  if ((elem->material_id() != comp_dom.wall_sur_ID1) &&
1323  (elem->material_id() != comp_dom.wall_sur_ID2) &&
1324  (elem->material_id() != comp_dom.wall_sur_ID3) &&
1325  (elem->material_id() != comp_dom.free_sur_ID1) &&
1326  (elem->material_id() != comp_dom.free_sur_ID2) &&
1327  (elem->material_id() != comp_dom.free_sur_ID3))
1328  {
1329  elem->clear_refine_flag();
1330  elem->clear_coarsen_flag();
1331  }
1332 
1333  if ((elem->material_id() == comp_dom.free_sur_ID1 ||
1334  elem->material_id() == comp_dom.free_sur_ID2 ||
1335  elem->material_id() == comp_dom.free_sur_ID3 ))
1336  {
1337  if ((elem->center().distance(Point<3>(0.0,0.0,0.0)) > 10.0) &&
1338  elem->at_boundary() )
1339  elem->clear_refine_flag();
1340  elem->clear_coarsen_flag();
1341  }
1342  counter++;
1343  }
1344 
1345  typedef typename Triangulation<dim-1, dim>::active_cell_iterator tria_it;
1346  typename std::map<tria_it, tria_it>::iterator it;
1347  for (it = comp_dom.boat_to_water_edge_cells.begin();
1348  it != comp_dom.boat_to_water_edge_cells.end(); ++it)
1349  {
1350  if ( it->first->refine_flag_set() &&
1351  !it->second->refine_flag_set() )
1352  {
1353  for (unsigned int i=0; i<it->second->parent()->n_children(); ++i)
1354  //if(!it->second->parent()->child(i).has_children())
1355  it->second->parent()->child(i)->clear_coarsen_flag();
1356  it->second->set_refine_flag();
1357  }
1358  else if ( it->second->refine_flag_set() &&
1359  !it->first->refine_flag_set() )
1360  {
1361  for (unsigned int i=0; i<it->first->parent()->n_children(); ++i)
1362  //if(!it->first->parent()->child(i).has_children())
1363  it->first->parent()->child(i)->clear_coarsen_flag();
1364  it->first->set_refine_flag();
1365  }
1366  else if ( it->first->coarsen_flag_set() &&
1367  !it->second->coarsen_flag_set() )
1368  {
1369  for (unsigned int i=0; i<it->first->parent()->n_children(); ++i)
1370  //if(!it->first->parent()->child(i).has_children())
1371  it->first->parent()->child(i)->clear_coarsen_flag();
1372  }
1373  else if ( it->second->coarsen_flag_set() &&
1374  !it->first->coarsen_flag_set() )
1375  {
1376  for (unsigned int i=0; i<it->second->parent()->n_children(); ++i)
1377  //if(!it->second->parent()->child(i).has_children())
1378  it->second->parent()->child(i)->clear_coarsen_flag();
1379  }
1380  }
1381  }
1382  else
1383  for (cell_it elem=dh.begin_active(); elem!= dh.end(); ++elem)
1384  {
1385 
1386  if (cell_diameters(counter)/(adaptive_ref_limit) < comp_dom.min_diameter)
1387  {
1388  elem->clear_refine_flag();
1389  }
1390 
1391  if (fabs(elem->center()(0)) > comp_dom.boat_model.boatWetLength*5.0)
1392  elem->clear_refine_flag();
1393 
1394  if ((elem->material_id() == comp_dom.wall_sur_ID1 ||
1395  elem->material_id() == comp_dom.wall_sur_ID2 ||
1396  elem->material_id() == comp_dom.wall_sur_ID3 ))
1397  {
1398  elem->clear_refine_flag();
1399  elem->clear_coarsen_flag();
1400  }
1401 
1402  if ((elem->material_id() == comp_dom.free_sur_ID1 ||
1403  elem->material_id() == comp_dom.free_sur_ID2 ||
1404  elem->material_id() == comp_dom.free_sur_ID3 ))
1405  {
1406  if (elem->at_boundary())
1407  {
1408  bool clear = true;
1409  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
1410  if ( elem->face(f)->boundary_id() == 40 ||
1411  elem->face(f)->boundary_id() == 41 ||
1412  elem->face(f)->boundary_id() == 26 || //this allows for refinement of waterline cells on water side
1413  elem->face(f)->boundary_id() == 27 || //this allows for refinement of waterline cells on water side
1414  elem->face(f)->boundary_id() == 28 || //this allows for refinement of waterline cells on water side
1415  elem->face(f)->boundary_id() == 29 //this allows for refinement of waterline cells on water side
1416  )
1417  {
1418  clear = false;
1419  //if ( ( elem->face(f)->boundary_id() == 26 || //this blocks last step of refinement of waterline cells if close to stern
1420  // elem->face(f)->boundary_id() == 27 || //this blocks last step of refinement of waterline cells if close to stern
1421  // elem->face(f)->boundary_id() == 28 || //this blocks last step of refinement of waterline cells if close to stern
1422  // elem->face(f)->boundary_id() == 29 ) && //this blocks last step of refinement of waterline cells if close to stern
1423  // (elem->center()(0) > 1.70) &&
1424  // (elem->diameter()/4.0 < comp_dom.min_diameter) )
1425  // clear = true;
1426  }
1427  if (clear)
1428  {
1429  elem->clear_refine_flag();
1430  elem->clear_coarsen_flag();
1431  }
1432  }
1433  }
1434  else
1435  {
1436  elem->clear_refine_flag();
1437  elem->clear_coarsen_flag();
1438  }
1439 
1440  counter++;
1441  }
1442 
1443 
1444  // prepare the triangulation,
1445  tria.prepare_coarsening_and_refinement();
1446  soltrans.prepare_for_coarsening_and_refinement(all_in);
1447 
1448 
1449 
1450  tria.execute_coarsening_and_refinement();
1451 
1452 
1453  dh.distribute_dofs(comp_dom.fe);
1454  vector_dh.distribute_dofs(comp_dom.vector_fe);
1455  comp_dom.map_points.reinit(vector_dh.n_dofs());
1456  comp_dom.smoothing_map_points.reinit(vector_dh.n_dofs());
1457  comp_dom.old_map_points.reinit(vector_dh.n_dofs());
1458  comp_dom.rigid_motion_map_points.reinit(vector_dh.n_dofs());
1459  comp_dom.initial_map_points.reinit(vector_dh.n_dofs());
1460  comp_dom.ref_points.resize(vector_dh.n_dofs());
1461  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
1462  comp_dom.vector_dh, comp_dom.ref_points);
1463  comp_dom.generate_double_nodes_set();
1464 
1465 
1466  compute_constraints(constraints, vector_constraints);
1467 
1468 
1469  this->dofs_number = vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()+13;
1470 
1471  //DoFRenumbering::Cuthill_McKee(dh);
1472  //DoFRenumbering::Cuthill_McKee(vector_dh);
1473  std::cout<<"Total number of dofs after refinement: "<<dh.n_dofs()<<std::endl;
1474 
1475 
1476  Vector<double> new_curvatures(vector_dh.n_dofs());
1477 
1478  Vector<double> new_Phi(dh.n_dofs());
1479  Vector<double> new_Phi_dot(dh.n_dofs());
1480 
1481  Vector <double> new_dphi_dn(dh.n_dofs());
1482  Vector <double> new_dphi_dn_dot(dh.n_dofs());
1483 
1484  Vector<double> new_positions_x(dh.n_dofs());
1485  Vector<double> new_positions_y(dh.n_dofs());
1486  Vector<double> new_positions_z(dh.n_dofs());
1487  Vector<double> new_positions_dot_x(dh.n_dofs());
1488  Vector<double> new_positions_dot_y(dh.n_dofs());
1489  Vector<double> new_positions_dot_z(dh.n_dofs());
1490 
1491  std::vector<Vector<double> > all_out;
1492  all_out.push_back(new_Phi);
1493  all_out.push_back(new_Phi_dot);
1494  all_out.push_back(new_dphi_dn);
1495  all_out.push_back(new_dphi_dn_dot);
1496  all_out.push_back(new_positions_x);
1497  all_out.push_back(new_positions_y);
1498  all_out.push_back(new_positions_z);
1499  all_out.push_back(new_positions_dot_x);
1500  all_out.push_back(new_positions_dot_y);
1501  all_out.push_back(new_positions_dot_z);
1502 
1503  soltrans.interpolate(all_in, all_out);
1504 
1505  solution.reinit(dofs_number);
1506  solution_dot.reinit(dofs_number);
1507 
1508  constraints.distribute(all_out[0]);
1509  constraints.distribute(all_out[1]);
1510  constraints.distribute(all_out[2]);
1511  constraints.distribute(all_out[3]);
1512  constraints.distribute(all_out[4]);
1513  constraints.distribute(all_out[5]);
1514  constraints.distribute(all_out[6]);
1515  constraints.distribute(all_out[7]);
1516  constraints.distribute(all_out[8]);
1517  constraints.distribute(all_out[9]);
1518 
1519  // we have to compute rigid_motion_map_points and rigid_motion_velocities on the new mesh
1520  rigid_motion_velocities.reinit(comp_dom.vector_dh.n_dofs());
1521 
1522  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
1523  // mesh (all nodes except for the free surface ones)
1524  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
1525  {
1526  if ( ((comp_dom.flags[i] & boat) &&
1527  !(comp_dom.flags[i] & near_water) ) ||
1528  (comp_dom.flags[i] & transom_on_water) )
1529  {
1530  //if (fabs(t-0.2) <1e-5)
1531  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
1532  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
1533  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
1534  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
1535  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
1536  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
1537  gp_Pnt boat_mesh_point = original_boat_mesh_point;
1538  // we first take this point (which is in the RESTART hull location) and transform it to be in the
1539  // REFERENCE configuration
1540  boat_mesh_point.Transform(restart_hull_location.Inverted());
1541 
1542  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
1543  // the 7 dofs associated to the rigid linear and angular displacements
1544 
1545  double s_x = restart_hull_displacement(0);
1546  double s_y = restart_hull_displacement(1);
1547  double s_z = restart_hull_displacement(2);
1548  double v_x = restart_hull_quat_vector(0);
1549  double v_y = restart_hull_quat_vector(1);
1550  double v_z = restart_hull_quat_vector(2);
1551  double s = restart_hull_quat_scalar;
1552 
1553  Point<3> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
1554  comp_dom.boat_model.reference_hull_baricenter(1),
1555  comp_dom.boat_model.reference_hull_baricenter(2));
1556 
1557  Point<3> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
1558  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
1559  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
1560 
1561  Point<3> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
1562  Point<3> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
1563  Point<3> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
1564 
1565  Point<3> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
1566  Point<3> rigid_lin_displ(s_x,s_y,s_z);
1567  Point<3> target_point_pos(RotMatRow1*(ref_point_pos+(-1.0)*ref_baricenter_pos),
1568  RotMatRow2*(ref_point_pos+(-1.0)*ref_baricenter_pos),
1569  RotMatRow3*(ref_point_pos+(-1.0)*ref_baricenter_pos));
1570  target_point_pos += baricenter_pos;
1571  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
1572  //boat_mesh_point.Transform(reference_to_current_transformation);
1573  // the rigid motion map points is the difference between the reference point position and the
1574  // current (rigidly displaced) node position
1575  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0)-ref_point_pos(0);
1576  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1)-ref_point_pos(1);
1577  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2)-ref_point_pos(2);
1578 
1579  rigid_motion_velocities(3*i) = current_hull_velocity(0)+
1580  current_hull_ang_velocity(1)*(target_point_pos(2)-baricenter_pos(2))-
1581  current_hull_ang_velocity(2)*(target_point_pos(1)-baricenter_pos(1));
1582  rigid_motion_velocities(3*i+1) = current_hull_velocity(1)+
1583  current_hull_ang_velocity(2)*(target_point_pos(0)-baricenter_pos(0))-
1584  current_hull_ang_velocity(0)*(target_point_pos(2)-baricenter_pos(2));
1585  rigid_motion_velocities(3*i+2) = current_hull_velocity(2)+
1586  current_hull_ang_velocity(0)*(target_point_pos(1)-baricenter_pos(1))-
1587  current_hull_ang_velocity(1)*(target_point_pos(0)-baricenter_pos(0));
1588 
1589 
1590  //if (fabs(t-0.2) <1e-5)
1591  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
1592  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
1593  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
1594  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
1595  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
1596  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
1597  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
1598  }
1599  }
1600 
1601 
1602  for (unsigned int i=0; i<dh.n_dofs(); ++i)
1603  {
1604  solution(3*i+0) = all_out[4](i)-comp_dom.rigid_motion_map_points(3*i)-comp_dom.ref_points[3*i](0);
1605  solution(3*i+1) = all_out[5](i)-comp_dom.rigid_motion_map_points(3*i+1)-comp_dom.ref_points[3*i](1);
1606  solution(3*i+2) = all_out[6](i)-comp_dom.rigid_motion_map_points(3*i+2)-comp_dom.ref_points[3*i](2);
1607  solution_dot(3*i+0) = all_out[7](i)-rigid_motion_velocities(3*i);
1608  solution_dot(3*i+1) = all_out[8](i)-rigid_motion_velocities(3*i+1);
1609  solution_dot(3*i+2) = all_out[9](i)-rigid_motion_velocities(3*i+2);
1610  solution(i+vector_dh.n_dofs()) = all_out[0](i);
1611  solution_dot(i+vector_dh.n_dofs()) = all_out[1](i);
1612  solution(i+vector_dh.n_dofs()+dh.n_dofs()) = all_out[2](i);
1613  solution_dot(i+vector_dh.n_dofs()+dh.n_dofs()) = all_out[3](i);
1614  }
1615 
1616 
1617  for (unsigned int k=0; k<3; ++k)
1618  {
1619  solution(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_velocity(k);
1620  solution_dot(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_velocity_dot(k);
1621  solution(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_displacement(k);
1622  solution_dot(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_displacement_dot(k);
1623  solution(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_ang_velocity(k);
1624  solution_dot(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_ang_velocity_dot(k);
1625  solution(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_vector(k);
1626  solution_dot(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_vector_dot(k);
1627  }
1628  solution(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_scalar;
1629  solution_dot(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_scalar_dot;
1630 
1631 
1632 
1633  for (unsigned int i=0; i<vector_dh.n_dofs(); ++i)
1634  {
1635  comp_dom.map_points(i) = solution(i)+comp_dom.rigid_motion_map_points(i);
1636  }
1637 
1638 
1639 
1640  DXDt_and_DphiDt_vector.reinit(vector_dh.n_dofs()+dh.n_dofs());
1641 
1642  DphiDt_sparsity_pattern.reinit (comp_dom.dh.n_dofs(),
1643  comp_dom.dh.n_dofs(),
1644  comp_dom.dh.max_couplings_between_dofs());
1645  vector_sparsity_pattern.reinit (comp_dom.vector_dh.n_dofs(),
1646  comp_dom.vector_dh.n_dofs(),
1647  comp_dom.vector_dh.max_couplings_between_dofs());
1648 
1649  DoFTools::make_sparsity_pattern (comp_dom.dh, DphiDt_sparsity_pattern, constraints);
1650  DphiDt_sparsity_pattern.compress();
1651 
1652  DoFTools::make_sparsity_pattern (comp_dom.vector_dh, vector_sparsity_pattern, vector_constraints);
1653  vector_sparsity_pattern.compress();
1654 
1655  working_map_points.reinit (comp_dom.vector_dh.n_dofs());
1656  working_nodes_velocities.reinit(comp_dom.vector_dh.n_dofs());
1657  nodes_pos_res.reinit(comp_dom.vector_dh.n_dofs());
1658  nodes_ref_surf_dist.reinit(comp_dom.vector_dh.n_dofs());
1659  nodes_diff_jac_x_delta.reinit(dofs_number);
1660  nodes_alg_jac_x_delta.reinit(dofs_number);
1661  dae_nonlin_residual.reinit(dofs_number);
1662  dae_linear_step_residual.reinit(dofs_number);
1663  current_sol.reinit(dofs_number);
1664  current_sol_dot.reinit(dofs_number);
1665  bem_residual.reinit (comp_dom.dh.n_dofs());
1666  bem_phi.reinit(comp_dom.dh.n_dofs());
1667  bem_dphi_dn.reinit(comp_dom.dh.n_dofs());
1668  temp_src.reinit(comp_dom.vector_dh.n_dofs());
1669  break_wave_press.reinit(comp_dom.dh.n_dofs());
1670 
1671 
1672 
1673 
1674  bem.reinit();
1675 
1676  support_points.resize(dh.n_dofs());
1677  DoFTools::map_dofs_to_support_points<2, 3>( *comp_dom.mapping, dh, support_points);
1678  std::vector<bool> new_boundary_dofs(vector_dh.n_dofs());
1679  std::vector< bool > comp_sel(3, true);
1680  DoFTools::extract_boundary_dofs(vector_dh, comp_sel, new_boundary_dofs);
1681  for (unsigned int i=0; i<dh.n_dofs(); ++i)
1682  for (unsigned int j=0; j<old_points.size(); ++j)
1683  if (old_points[j].distance(support_points[i]) < 1e-5)
1684  {
1685  new_boundary_dofs[3*i] = 1;
1686  new_boundary_dofs[3*i+1] = 1;
1687  new_boundary_dofs[3*i+2] = 1;
1688  }
1689 
1690 
1691  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
1692  {
1693  comp_dom.map_points(i) = solution(i)+comp_dom.rigid_motion_map_points(i);
1694  //cout<<"* "<<i<<" "<<comp_dom.map_points(i)<<endl;
1695  }
1696 
1697 
1698  make_edges_conformal(solution, solution_dot, t, step_number, h);
1699  make_edges_conformal(solution, solution_dot, t, step_number, h);
1700  remove_transom_hanging_nodes(solution, solution_dot, t, step_number, h);
1701  make_edges_conformal(solution, solution_dot, t, step_number, h);
1702  make_edges_conformal(solution, solution_dot, t, step_number, h);
1703 
1704 
1705 
1706  for (unsigned int k=0; k<3; ++k)
1707  {
1708  solution(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_velocity(k);
1709  solution_dot(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_velocity_dot(k);
1710  solution(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_displacement(k);
1711  solution_dot(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_displacement_dot(k);
1712  solution(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_ang_velocity(k);
1713  solution_dot(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_ang_velocity_dot(k);
1714  solution(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_vector(k);
1715  solution_dot(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_vector_dot(k);
1716  }
1717  solution(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_scalar;
1718  solution_dot(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = current_hull_quat_scalar_dot;
1719 
1720 //cout<<"First save "<<endl;
1721 // std::string filename2 = ( "postRemesh1.vtu" );
1722 // output_results(filename2, t, solution, solution_dot);
1723  if (!comp_dom.no_boat)
1724  comp_dom.evaluate_ref_surf_distances(nodes_ref_surf_dist,false);
1725  comp_dom.map_points -= nodes_ref_surf_dist;
1726  comp_dom.update_support_points();
1727  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
1728  {
1729  solution(i) = comp_dom.map_points(i)-comp_dom.rigid_motion_map_points(i);
1730  }
1731 
1732 
1733 
1734 //cout<<"Second save "<<endl;
1735  //std::string filename20 = ( "postRemesh20.vtu" );
1736  //output_results(filename20, t, solution, solution_dot);
1737 
1738  // in particular we must get the position of the nodes (in terms of curvilinear length)
1739  // on the smoothing lines, and the corresponding potential and horizontal velcoity values, in order to
1740  // interpolate the new values to be assigned at the restart of the simulation
1741 
1742  for (unsigned smooth_id=0; smooth_id<comp_dom.line_smoothers.size(); ++smooth_id)
1743  {
1744  Vector<double> &old_lengths = comp_dom.line_smoothers[smooth_id]->get_lengths_before_smoothing();
1745  Vector<double> &new_lengths = comp_dom.line_smoothers[smooth_id]->get_lengths_after_smoothing();
1746  std::vector<unsigned int> &indices = comp_dom.line_smoothers[smooth_id]->get_node_indices();
1747  Vector<double> old_potentials(old_lengths.size());
1748  Vector<double> old_vx(old_lengths.size());
1749  Vector<double> old_vy(old_lengths.size());
1750  //Vector<double> new_potentials(old_lengths.size());
1751  for (unsigned int i=0; i<old_lengths.size(); ++i)
1752  {
1753  old_potentials(i) = solution(indices[i]+vector_dh.n_dofs());
1754  old_vx(i) = solution_dot(3*indices[i]);
1755  old_vy(i) = solution_dot(3*indices[i]+1);
1756  //cout<<i<<"("<<indices[i]<<"->"<<round(indices[i]/3)<<") "<<old_lengths(i)<<" vs "<<new_lengths(i)<<" pot: "<<old_potentials(i)<<endl;
1757  //cout<<indices[i]<<" "<<comp_dom.support_points[indices[i]]<<endl;
1758  }
1759  //new_potentials(0) = old_potentials(0);
1760  //new_potentials(old_lengths.size()-1) = old_potentials(old_lengths.size()-1);
1761  for (unsigned int i=1; i<old_lengths.size()-1; ++i)
1762  {
1763  unsigned int jj=1000000;
1764  for (unsigned int j=1; j<old_lengths.size(); ++j)
1765  {
1766  if (new_lengths(i) < old_lengths(j))
1767  {
1768  jj = j;
1769  break;
1770  }
1771  }
1772  double fraction = (new_lengths(i)-old_lengths(jj-1))/(old_lengths(jj)-old_lengths(jj-1));
1773  solution(indices[i]+vector_dh.n_dofs()) = old_potentials(jj-1)+(old_potentials(jj)-old_potentials(jj-1))*fraction;
1774  //solution_dot(3*indices[i]) = old_vx(jj-1)+(old_vx(jj)-old_vx(jj-1))*fraction;
1775  //solution_dot(3*indices[i]+1) = old_vy(jj-1)+(old_vy(jj)-old_vy(jj-1))*fraction;
1776  //cout<<i<<" ---> "<<jj<<" "<<fraction<<" "<<old_potentials(jj-1)<<" "<<old_potentials(jj)<<" "<<new_potentials(i)<<endl;
1777  }
1778  }
1779 
1780  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
1781  {
1782  if ( (!(comp_dom.flags[i] & near_boat)==0) &&
1783  (!(comp_dom.flags[i] & near_water)==0))
1784  {
1785  solution_dot(3*i) = 0;
1786  solution_dot(3*i+1) = 0;
1787  }
1788  }
1789 
1790 
1791 
1792  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom)
1793  {
1794  comp_dom.update_support_points();
1795  double transom_draft = fabs(comp_dom.boat_model.CurrentPointCenterTransom(2));
1796  //double transom_draft = ref_transom_wet_surface/(fabs(comp_dom.boat_model.PointLeftTransom(1))+
1797  // fabs(comp_dom.boat_model.PointRightTransom(1)));
1798  double transom_aspect_ratio = (fabs(comp_dom.boat_model.CurrentPointLeftTransom(1))+
1799  fabs(comp_dom.boat_model.CurrentPointRightTransom(1)))/transom_draft;
1800 
1801  wind.set_time(100000000.0);
1802  Vector<double> instantWindValueTinf(dim);
1803  Point<dim> zero(0,0,0);
1804  wind.vector_value(zero,instantWindValueTinf);
1805  Point<dim> VinfTinf;
1806  for (unsigned int i = 0; i < dim; i++)
1807  VinfTinf(i) = instantWindValueTinf(i);
1808  wind.set_time(initial_time);
1809 
1810  double FrT = sqrt(VinfTinf*VinfTinf)/sqrt(9.81*transom_draft);
1811  double ReT = sqrt(9.81*pow(transom_draft,3.0))/1.307e-6;
1812  double eta_dry = fmin(0.05*pow(FrT,2.834)*pow(transom_aspect_ratio,0.1352)*pow(ReT,0.01338),1.0);
1813  double lh = 0.0;
1814  //if (eta_dry < 1.0)
1815  lh = 5.0;
1816  //lh = 0.1135*pow(FrT,3.025)*pow(transom_aspect_ratio,0.4603)*pow(ReT,-0.1514);
1817  //lh = 0.3265*pow(FrT,3.0) - 1.7216*pow(FrT,2.0) + 2.7593*FrT;
1818 
1819  cout<<"****eta_dry: "<<eta_dry<<endl;
1820 
1821 
1822  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
1823  {
1824  comp_dom.initial_map_points(3*i+2) = 0.0;
1825  }
1826 
1827  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
1828  {
1829  if ( (comp_dom.support_points[i](1) < comp_dom.boat_model.PointRightTransom(1)) &&
1830  (comp_dom.support_points[i](1) >= 0.0) &&
1831  (comp_dom.support_points[i](0) > comp_dom.boat_model.PointCenterTransom(0)-fabs(comp_dom.boat_model.PointCenterTransom(2)) ) &&
1832  (comp_dom.support_points[i](0) < comp_dom.boat_model.PointCenterTransom(0)+lh*fabs(comp_dom.boat_model.PointCenterTransom(2)) ) &&
1833  (comp_dom.support_points[i](2) > 2.0*comp_dom.boat_model.CurrentPointCenterTransom(2)) )
1834  {
1835  Point <3> dP0 = comp_dom.support_points[i];
1836  Point <3> dP;
1837  //this is the vertical plane
1838  Handle(Geom_Plane) vertPlane = new Geom_Plane(0.,1.,0.,-dP0(1));
1839  vertPlane->Transform(comp_dom.boat_model.current_loc.Inverted());
1840  Handle(Geom_Curve) curve = comp_dom.boat_model.right_transom_bspline;
1841 
1842  GeomAPI_IntCS Intersector(curve, vertPlane);
1843  int npoints = Intersector.NbPoints();
1844  AssertThrow((npoints != 0), ExcMessage("Transom curve is not intersecting with vertical plane!"));
1845  //cout<<"Number of intersections: "<<npoints<<endl;
1846  double minDistance=1e7;
1847  for (int j=0; j<npoints; ++j)
1848  {
1849  gp_Pnt int_point = Intersector.Point(j+1);
1850  int_point.Transform(comp_dom.boat_model.current_loc);
1851  Point<3> inters = Pnt(int_point);
1852 
1853  if (dP0.distance(inters) < minDistance)
1854  {
1855  minDistance = dP0.distance(inters);
1856  dP = inters;
1857  }
1858  }
1859 
1860  if ( (comp_dom.ref_points[i](0) > dP(0)+comp_dom.min_diameter/20.0) &&
1861  (comp_dom.ref_points[i](0) < dP(0)+lh*fabs(dP(2))+comp_dom.min_diameter/20.0) )
1862  {
1863  double mean_curvature;
1864  Point<3> normal;
1865  Point<3> projection;
1866  comp_dom.boat_model.boat_surface_right->normal_projection_and_diff_forms(projection,
1867  normal,
1868  mean_curvature,
1869  dP);
1870 
1871  AssertThrow((dP.distance(projection) < 1e-4*comp_dom.boat_model.boatWetLength), ExcMessage("Normal projection for surface normal evaluation went wrong!"));
1872  double transom_slope = -normal(0)/normal(2);
1873  double a = -transom_slope/(lh*fabs(dP(2))) - 1/dP(2)/lh/lh;
1874  double x = comp_dom.support_points[i](0)-dP(0);
1875  comp_dom.initial_map_points(3*i+2) = a*x*x + transom_slope*x + dP(2);
1876  //cout<<"a="<<a<<" t_s="<<transom_slope<<" dP(2)="<<dP(2)<<endl;
1877  //cout<<"x="<<x<<" z_in="<<comp_dom.initial_map_points(3*i+2)<<endl;
1878  }
1879  }
1880  else if ( (comp_dom.support_points[i](1) > comp_dom.boat_model.PointLeftTransom(1)) &&
1881  (comp_dom.support_points[i](1) < 0.0) &&
1882  (comp_dom.support_points[i](0) > comp_dom.boat_model.PointCenterTransom(0)-fabs(comp_dom.boat_model.PointCenterTransom(2))) &&
1883  (comp_dom.support_points[i](0) < comp_dom.boat_model.PointCenterTransom(0)+lh*fabs(comp_dom.boat_model.PointCenterTransom(2))) &&
1884  (comp_dom.support_points[i](2) > 2.0*comp_dom.boat_model.CurrentPointCenterTransom(2)) )
1885  {
1886  Point <3> dP0 = comp_dom.support_points[i];
1887  Point <3> dP;
1888  //this is the vertical plane
1889  Handle(Geom_Plane) vertPlane = new Geom_Plane(0.,1.,0.,-dP0(1));
1890  vertPlane->Transform(comp_dom.boat_model.current_loc.Inverted());
1891  Handle(Geom_Curve) curve = comp_dom.boat_model.left_transom_bspline;
1892 
1893  GeomAPI_IntCS Intersector(curve, vertPlane);
1894  int npoints = Intersector.NbPoints();
1895  AssertThrow((npoints != 0), ExcMessage("Transom curve is not intersecting with vertical plane!"));
1896  //cout<<"Number of intersections: "<<npoints<<endl;
1897  double minDistance=1e7;
1898  for (int j=0; j<npoints; ++j)
1899  {
1900  gp_Pnt int_point = Intersector.Point(j+1);
1901  int_point.Transform(comp_dom.boat_model.current_loc);
1902  Point<3> inters = Pnt(int_point);
1903 
1904  if (dP0.distance(inters) < minDistance)
1905  {
1906  minDistance = dP0.distance(inters);
1907  dP = inters;
1908  }
1909  }
1910  if ( (comp_dom.ref_points[i](0) > dP(0)+comp_dom.min_diameter/20.0) &&
1911  (comp_dom.ref_points[i](0) < dP(0)+lh*fabs(dP(2))+comp_dom.min_diameter/20.0) )
1912  {
1913  double mean_curvature;
1914  Point<3> normal;
1915  Point<3> projection;
1916  comp_dom.boat_model.boat_surface_left->normal_projection_and_diff_forms(projection,
1917  normal,
1918  mean_curvature,
1919  dP);
1920 
1921  AssertThrow((dP.distance(projection) < 1e-4*comp_dom.boat_model.boatWetLength), ExcMessage("Normal projection for surface normal evaluation went wrong!"));
1922  double transom_slope = -normal(0)/normal(2);
1923  double a = -transom_slope/(lh*fabs(dP(2))) - 1/dP(2)/lh/lh;
1924  double x = comp_dom.support_points[i](0)-dP(0);
1925  comp_dom.initial_map_points(3*i+2) = a*x*x + transom_slope*x + dP(2);
1926  }
1927  }
1928  }
1929 
1930  comp_dom.vector_constraints.distribute(comp_dom.initial_map_points);
1931 
1932  }
1933 
1934 
1935  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
1936  {
1937  solution(i) = comp_dom.map_points(i)-comp_dom.rigid_motion_map_points(i);
1938  }
1939 
1940 
1941 
1942  wind.set_time(t);
1943  Vector<double> instantWindValue(dim);
1944  Point<dim> zero(0,0,0);
1945  wind.vector_value(zero,instantWindValue);
1946  Point<dim> Vinf;
1947  for (unsigned int i = 0; i < dim; i++)
1948  Vinf(i) = instantWindValue(i);
1949  Point<dim> Vh(0.0,0.0,0.01*2*dealii::numbers::PI*cos(2*dealii::numbers::PI*t));
1950 
1951  for (unsigned int i=0; i<dh.n_dofs(); ++i)
1952  {
1953  if ( comp_dom.flags[i] & boat )
1954  //solution(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = -comp_dom.iges_normals[i]*Vinf;
1955  solution(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = comp_dom.node_normals[i]*(Vh-Vinf);
1956  }
1957 
1958  differential_components();
1959 
1960  current_time = t;
1961  current_sol = solution;
1962  current_sol_dot = solution_dot;
1963  last_remesh_time = t;
1964  comp_dom.old_map_points = comp_dom.map_points;
1965  comp_dom.rigid_motion_map_points = 0;
1966 
1967 
1968  prepare_restart(t, solution, solution_dot,true);
1969  //std::string filename3 = ( "postPostRemesh.vtu" );
1970  //output_results(filename3, t, solution, solution_dot);
1971 //*/
1972 
1973  // we have to compute the reference transom wet surface with the new mesh here
1974  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom)
1975  {
1976  double transom_wet_surface = 0;
1977  std::vector<Point<3> > vertices;
1978  std::vector<CellData<2> > cells;
1979  for (tria_it elem=comp_dom.tria.begin_active(); elem!= comp_dom.tria.end(); ++elem)
1980  {
1981  if ((elem->material_id() == comp_dom.wall_sur_ID1 ||
1982  elem->material_id() == comp_dom.wall_sur_ID2 ||
1983  elem->material_id() == comp_dom.wall_sur_ID3 ))
1984  {
1985  if (elem->at_boundary())
1986  {
1987  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
1988  if ( elem->face(f)->boundary_id() == 32 ||
1989  elem->face(f)->boundary_id() == 37 )
1990  {
1991  unsigned int index_0 = comp_dom.find_point_id(elem->face(f)->vertex(0),comp_dom.ref_points);
1992  unsigned int index_1 = comp_dom.find_point_id(elem->face(f)->vertex(1),comp_dom.ref_points);
1993  if (comp_dom.ref_points[3*index_1](1) < comp_dom.ref_points[3*index_0](1))
1994  {
1995  vertices.push_back(comp_dom.ref_points[3*index_0]);
1996  vertices.push_back(comp_dom.ref_points[3*index_1]);
1997  vertices.push_back(comp_dom.ref_points[3*index_1]+
1998  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_1](2)));
1999  vertices.push_back(comp_dom.support_points[index_0]+
2000  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_0](2)));
2001  cells.resize(cells.size()+1);
2002  cells[cells.size()-1].vertices[0]=4*(cells.size()-1)+0;
2003  cells[cells.size()-1].vertices[1]=4*(cells.size()-1)+1;
2004  cells[cells.size()-1].vertices[2]=4*(cells.size()-1)+2;
2005  cells[cells.size()-1].vertices[3]=4*(cells.size()-1)+3;
2006  }
2007  else
2008  {
2009  vertices.push_back(comp_dom.support_points[index_1]);
2010  vertices.push_back(comp_dom.support_points[index_0]);
2011  vertices.push_back(comp_dom.support_points[index_0]+
2012  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_0](2)));
2013  vertices.push_back(comp_dom.support_points[index_1]+
2014  -1.0*Point<3>(0.0,0.0,comp_dom.ref_points[3*index_1](2)));
2015  cells.resize(cells.size()+1);
2016  cells[cells.size()-1].vertices[0]=4*(cells.size()-1)+0;
2017  cells[cells.size()-1].vertices[1]=4*(cells.size()-1)+1;
2018  cells[cells.size()-1].vertices[2]=4*(cells.size()-1)+2;
2019  cells[cells.size()-1].vertices[3]=4*(cells.size()-1)+3;
2020  }
2021  }
2022  }
2023  }
2024  }
2025 
2026 
2027  SubCellData subcelldata;
2028  Triangulation<dim-1, dim> transom_tria;
2029  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
2031  transom_tria.create_triangulation_compatibility(vertices, cells, subcelldata );
2032  FE_Q<dim-1,dim> transom_fe(1);
2033  DoFHandler<dim-1,dim> transom_dh(transom_tria);
2034  transom_dh.distribute_dofs(transom_fe);
2035 
2036  FEValues<dim-1,dim> transom_fe_v(transom_fe, *comp_dom.quadrature,
2037  update_values | update_gradients |
2038  update_cell_normal_vectors |
2039  update_quadrature_points |
2040  update_JxW_values);
2041 
2042  const unsigned int transom_n_q_points = transom_fe_v.n_quadrature_points;
2043 
2044 
2045  std::vector<double> transom_pressure_quad_values(transom_n_q_points);
2046  for (cell_it cell = transom_dh.begin_active(); cell!=transom_dh.end(); ++cell)
2047  {
2048  transom_fe_v.reinit(cell);
2049 
2050  for (unsigned int q=0; q<transom_n_q_points; ++q)
2051  {
2052  transom_wet_surface += 1 * transom_fe_v.JxW(q);
2053  }
2054  }
2055  ref_transom_wet_surface = transom_wet_surface;
2056  }
2057 
2058  // here we finally compute the reference cell areas, which are needed
2059  // to evaluate boat cell deformations and possibly activate smoothing
2060 
2061  const unsigned int DphiDt_n_q_points = fe_v.n_quadrature_points;
2062  ref_cell_areas.reinit(comp_dom.tria.n_active_cells());
2063  cell = comp_dom.dh.begin_active(),
2064  endc = comp_dom.dh.end();
2065 
2066  unsigned int count=0;
2067  for (; cell!=endc; ++cell)
2068  {
2069  if ((cell->material_id() == comp_dom.wall_sur_ID1 ||
2070  cell->material_id() == comp_dom.wall_sur_ID2 ||
2071  cell->material_id() == comp_dom.wall_sur_ID3 ))
2072  {
2073  fe_v.reinit(cell);
2074  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
2075  {
2076  ref_cell_areas(count) += 1.0 * fe_v.JxW(q);
2077  }
2078  }
2079  ++count;
2080  }
2081 
2082 
2083 
2084 
2085 
2086  std::cout<<"...done checking and updating mesh"<<std::endl;
2087 
2088 
2089  return true;
2090 
2091  }
2092 
2093  // this is what happens if max number of nodes has already been reached: nothing
2094  else if ( (t>=remeshing_period*remeshing_counter && comp_dom.dh.n_dofs() > max_number_of_dofs) )
2095  {
2096  current_time = t;
2097  current_sol = solution;
2098  current_sol_dot = solution_dot;
2099  return false;
2100  }
2101  // in normal situations (no remesh) we just check that the boat mesh is ok (no bad quality cells)
2102  // and adjust it in case quality is bad. IMPORTANT: the restart procedure has to be improved
2103  // for this case, bacause the blend_factor used to obtain the last available horizontal displacement
2104  // field on the free surface is not the one used at restart time. as the difference is very small (1e-4~1e-5)
2105  // it doesn't seem to harm the restart, but with faster dynamics and ramps restarts might be problematic. thus,
2106  // we might consider adding nodes horizontal coordinates dofs to algebraic nonlinear restart problem class.
2107  else
2108  {
2109  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
2110  update_JxW_values);
2111  const unsigned int DphiDt_n_q_points = fe_v.n_quadrature_points;
2112  Vector<double> cell_areas(comp_dom.tria.n_active_cells());
2113  cell_areas=0;
2114  cell_it
2115  cell = comp_dom.dh.begin_active(),
2116  endc = comp_dom.dh.end();
2117 
2118  unsigned int count=0;
2119  bool smooth=false;
2120  double min_ratio =1.0;
2121  for (; cell!=endc; ++cell)
2122  {
2123  if ((cell->material_id() == comp_dom.wall_sur_ID1 ||
2124  cell->material_id() == comp_dom.wall_sur_ID2 ||
2125  cell->material_id() == comp_dom.wall_sur_ID3 ))
2126  {
2127  fe_v.reinit(cell);
2128  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
2129  {
2130  cell_areas(count) += 1.0 * fe_v.JxW(q);
2131  }
2132  }
2133  min_ratio = fmin(min_ratio,cell_areas(count)/ref_cell_areas(count));
2134  if (cell_areas(count)/ref_cell_areas(count) < 0.5)
2135  {
2136  smooth=true;
2137  break;
2138  }
2139  ++count;
2140  }
2141  cout<<"Min Areas Ratio For Smoothing: "<<min_ratio<<endl;
2142 
2143  if (smooth)
2144  {
2145  // first thing to do is update the geometry to the current positon
2146  Point<3> current_hull_displacement;
2147  Point<3> current_hull_displacement_dot;
2148  Point<3> current_hull_velocity;
2149  Point<3> current_hull_velocity_dot;
2150  Point<3> current_hull_ang_velocity;
2151  Point<3> current_hull_ang_velocity_dot;
2152  Point<3> current_hull_quat_vector;
2153  Point<3> current_hull_quat_vector_dot;
2154  for (unsigned int k=0; k<3; ++k)
2155  {
2156  current_hull_displacement(k) = solution(k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2157  current_hull_displacement_dot(k) = solution_dot(k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2158  current_hull_velocity(k) = solution(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2159  current_hull_velocity_dot(k) = solution_dot(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2160  current_hull_ang_velocity(k) = solution(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2161  current_hull_ang_velocity_dot(k) = solution_dot(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2162  current_hull_quat_vector(k) = solution(k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2163  current_hull_quat_vector_dot(k) = solution_dot(k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2164  }
2165  double current_hull_quat_scalar = solution(12+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2166  double current_hull_quat_scalar_dot = solution_dot(12+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
2167 
2168  restart_hull_displacement(0) = current_hull_displacement(0);
2169  restart_hull_displacement(1) = current_hull_displacement(1);
2170  restart_hull_displacement(2) = current_hull_displacement(2);
2171  restart_hull_quat_vector(0) = current_hull_quat_vector(0);
2172  restart_hull_quat_vector(1) = current_hull_quat_vector(1);
2173  restart_hull_quat_vector(2) = current_hull_quat_vector(2);
2174  restart_hull_quat_scalar = current_hull_quat_scalar;
2175 
2176  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
2177  // mesh (all nodes except for the free surface ones)
2178  Vector<double> rigid_motion_velocities(comp_dom.vector_dh.n_dofs());
2179  restart_hull_location = comp_dom.boat_model.set_current_position(restart_hull_displacement,
2180  restart_hull_quat_scalar,
2181  restart_hull_quat_vector);
2182 
2183 
2184 
2185  //std::string filename4 = ( "beforeSurfaceRemesh.vtu" );
2186  //output_results(filename4, t, solution, solution_dot);
2187  nodes_ref_surf_dist = 0.0;
2188  if (!comp_dom.no_boat)
2189  comp_dom.evaluate_ref_surf_distances(nodes_ref_surf_dist,true);
2190  differential_components();
2191  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2192  if ( ((comp_dom.flags[i] & boat) &&
2193  !(comp_dom.flags[i] & near_water) ) ||
2194  (comp_dom.flags[i] & transom_on_water) )
2195  {
2196  for (unsigned int d=0; d<3; ++d)
2197  {
2198  comp_dom.map_points(3*i+d) -= nodes_ref_surf_dist(3*i+d);
2199  comp_dom.old_map_points(3*i+d) = comp_dom.map_points(3*i+d);
2200  }
2201  if (constraints.is_constrained(i))
2202  for (unsigned int d=0; d<3; ++d)
2203  solution(i) = comp_dom.map_points(i);
2204  else
2205  {
2206  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
2207  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
2208  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
2209  gp_Pnt boat_mesh_point = original_boat_mesh_point;
2210  // we first take this point (which is in the RESTART hull location) and transform it to be in the
2211  // REFERENCE configuration
2212  boat_mesh_point.Transform(restart_hull_location.Inverted());
2213  Point<3> rigid_displ = Pnt(boat_mesh_point)+(-1.0*Pnt(original_boat_mesh_point));
2214  for (unsigned int d=0; d<3; ++d)
2215  comp_dom.rigid_motion_map_points(3*i+d) = rigid_displ(d);
2216  for (unsigned int d=0; d<3; ++d)
2217  solution(3*i+d) = comp_dom.map_points(3*i+d)-comp_dom.rigid_motion_map_points(3*i+d);
2218  }
2219  //cout<<i<<" "<<nodes_ref_surf_dist(i)<<endl;
2220  }
2221 
2222  current_time = t;
2223  current_sol = solution;
2224  current_sol_dot = solution_dot;
2225  //std::string filename5 = ( "surfaceRemesh.vtu" );
2226  //output_results(filename5, t, solution, solution_dot);
2227 
2228  prepare_restart(t, solution, solution_dot,false);
2229 
2230  // compute new ref_cell_areas
2231  ref_cell_areas = 0.0;
2232  cell = comp_dom.dh.begin_active(),
2233  endc = comp_dom.dh.end();
2234 
2235  unsigned int count=0;
2236  for (; cell!=endc; ++cell)
2237  {
2238  if ((cell->material_id() == comp_dom.wall_sur_ID1 ||
2239  cell->material_id() == comp_dom.wall_sur_ID2 ||
2240  cell->material_id() == comp_dom.wall_sur_ID3 ))
2241  {
2242  fe_v.reinit(cell);
2243  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
2244  {
2245  ref_cell_areas(count) += 1.0 * fe_v.JxW(q);
2246  }
2247  }
2248  ++count;
2249  }
2250 
2251  return true;
2252  }
2253  else
2254  {
2255  return false;
2256  }
2257 
2258  }
2259 
2260 
2261 
2262  return false;
2263 }
2264 
2265 
2266 // this routine detects if mesh is not
2267 // conformal at edges (because of double
2268 // nodes) and makes the refinements needed
2269 // to make it conformal. in free surface
2270 // it also has to deal with interpolation
2271 // of the solution
2272 
2273 template <int dim>
2275  Vector<double> &solution_dot,
2276  const double t,
2277  const unsigned int step_number,
2278  const double h)
2279 {
2280  std::cout<<"Restoring mesh conformity..."<<std::endl;
2281 
2282 
2283 
2284  Point<3> hull_lin_vel;
2285  Point<3> hull_lin_displ;
2286  Point<3> hull_lin_vel_dot;
2287  Point<3> hull_lin_displ_dot;
2288  Point<3> hull_ang_vel;
2289  Point<3> hull_ang_vel_dot;
2290  Point<3> hull_quat_vect;
2291  Point<3> hull_quat_vect_dot;
2292  double hull_quat_scal;
2293  double hull_quat_scal_dot;
2294  for (unsigned int d=0; d<3; ++d)
2295  {
2296  hull_lin_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
2297  hull_lin_displ(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
2298  hull_lin_vel_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
2299  hull_lin_displ_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
2300  hull_ang_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
2301  hull_ang_vel_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
2302  hull_quat_vect(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
2303  hull_quat_vect_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
2304  }
2305  hull_quat_scal = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
2306  hull_quat_scal_dot = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
2307 
2308  cout<<"*Hull Rigid Displacement: "<<hull_lin_displ<<endl;
2309  cout<<"*Hull Rigid Velocity: "<<hull_lin_vel<<endl;
2310  cout<<"*Hull Angualr Velocity: "<<hull_lin_vel<<endl;
2311 
2312 
2313  Vector<double> rigid_motion_velocities(comp_dom.vector_dh.n_dofs());
2314 
2315  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
2316  // mesh (all nodes except for the free surface ones)
2317  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2318  {
2319  if ( ((comp_dom.flags[i] & boat) &&
2320  !(comp_dom.flags[i] & near_water) ) ||
2321  (comp_dom.flags[i] & transom_on_water) )
2322  {
2323  //if (fabs(t-0.2) <1e-5)
2324  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
2325  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
2326  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
2327  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
2328  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
2329  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
2330  gp_Pnt boat_mesh_point = original_boat_mesh_point;
2331  // we first take this point (which is in the RESTART hull location) and transform it to be in the
2332  // REFERENCE configuration
2333  boat_mesh_point.Transform(restart_hull_location.Inverted());
2334 
2335  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
2336  // the 7 dofs associated to the rigid linear and angular displacements
2337 
2338  double s_x = hull_lin_displ(0);
2339  double s_y = hull_lin_displ(1);
2340  double s_z = hull_lin_displ(2);
2341  double v_x = hull_quat_vect(0);
2342  double v_y = hull_quat_vect(1);
2343  double v_z = hull_quat_vect(2);
2344  double s = hull_quat_scal;
2345 
2346  Point<3> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
2347  comp_dom.boat_model.reference_hull_baricenter(1),
2348  comp_dom.boat_model.reference_hull_baricenter(2));
2349 
2350  Point<3> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
2351  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
2352  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
2353 
2354  Point<3> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
2355  Point<3> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
2356  Point<3> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
2357 
2358  Point<3> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
2359  Point<3> rigid_lin_displ(s_x,s_y,s_z);
2360  Point<3> target_point_pos(RotMatRow1*(ref_point_pos+(-1.0)*ref_baricenter_pos),
2361  RotMatRow2*(ref_point_pos+(-1.0)*ref_baricenter_pos),
2362  RotMatRow3*(ref_point_pos+(-1.0)*ref_baricenter_pos));
2363  target_point_pos += baricenter_pos;
2364  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
2365  //boat_mesh_point.Transform(reference_to_current_transformation);
2366  // the rigid motion map points is the difference between the reference point position and the
2367  // current (rigidly displaced) node position
2368  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0)-ref_point_pos(0);
2369  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1)-ref_point_pos(1);
2370  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2)-ref_point_pos(2);
2371 
2372  rigid_motion_velocities(3*i) = hull_lin_vel(0)+
2373  hull_ang_vel(1)*(target_point_pos(2)-baricenter_pos(2))-
2374  hull_ang_vel(2)*(target_point_pos(1)-baricenter_pos(1));
2375  rigid_motion_velocities(3*i+1) = hull_lin_vel(1)+
2376  hull_ang_vel(2)*(target_point_pos(0)-baricenter_pos(0))-
2377  hull_ang_vel(0)*(target_point_pos(2)-baricenter_pos(2));
2378  rigid_motion_velocities(3*i+2) = hull_lin_vel(2)+
2379  hull_ang_vel(0)*(target_point_pos(1)-baricenter_pos(1))-
2380  hull_ang_vel(1)*(target_point_pos(0)-baricenter_pos(0));
2381 
2382 
2383 
2384  //if (fabs(t-0.2) <1e-5)
2385  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
2386  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
2387  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
2388  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
2389  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
2390  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
2391  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
2392  }
2393  }
2394 
2395 
2396 
2397  Triangulation<dim-1, dim> &tria = comp_dom.tria;
2398  DoFHandler<dim-1, dim> &dh = comp_dom.dh;
2399  DoFHandler<dim-1, dim> &vector_dh = comp_dom.vector_dh;
2400 
2401 
2402  std::vector<Point<dim> > support_points(dh.n_dofs());
2403  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, dh, support_points);
2404 
2405 
2406 
2407  VectorView<double> Phi(dh.n_dofs(), solution.begin()+vector_dh.n_dofs());
2408  VectorView<double> Phi_dot(dh.n_dofs(), solution_dot.begin()+vector_dh.n_dofs());
2409  VectorView<double> dphi_dn(dh.n_dofs(), solution.begin()+vector_dh.n_dofs()+dh.n_dofs());
2410  VectorView<double> dphi_dn_dot(dh.n_dofs(), solution_dot.begin()+vector_dh.n_dofs()+dh.n_dofs());
2411 
2412  std::vector<Point<3> > old_points(dh.n_dofs());
2413  old_points = support_points;
2414 
2415  Vector<double> curvatures(vector_dh.n_dofs());
2416  comp_dom.surface_smoother->compute_curvatures(curvatures);
2417 
2418  // Get support points in the
2419  // reference configuration
2420  std::vector<Point<3> > ref_points(dh.n_dofs());
2421  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
2422  dh, ref_points);
2423  double tol=1e-7;
2424  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2425  {
2426  if ((comp_dom.flags[i] & edge) &&
2427  (comp_dom.double_nodes_set[i].size() == 1) )
2428  {
2429  //we identify here the two vertices of the parent cell on the considered side
2430  //(which is the one with the non conformal node)
2431  std::vector<Point<3> > nodes(2);
2432  for (unsigned int kk=0; kk<2; ++kk)
2433  {
2434  DoFHandler<2,3>::cell_iterator cell = comp_dom.dof_to_elems[i][kk];
2435  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
2436  {
2437  if (cell->face(f)->at_boundary())
2438  {
2439  if (ref_points[i].distance(cell->face(f)->vertex(0)) <tol)
2440  nodes[kk] = cell->face(f)->vertex(1);
2441  else if (ref_points[i].distance(cell->face(f)->vertex(1)) <tol)
2442  nodes[kk] = cell->face(f)->vertex(0);
2443  }
2444  }
2445  }
2446  // we can now compute the center of the parent cell face
2447  Point<3> parent_face_center = 0.5*(nodes[0]+nodes[1]);
2448  // now we look for the opposite side cell that has a face on an edge, having the same center
2449  DoFHandler<2,3>::cell_iterator cell1 = comp_dom.dof_to_elems[i][0]->parent();
2450  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
2451  if (cell1->face(f)->at_boundary())
2452  {
2453  for (typename std::set<tria_it>::iterator jt=comp_dom.edge_cells.begin(); jt != comp_dom.edge_cells.end(); ++jt)
2454  for (unsigned int d=0; d<GeometryInfo<2>::faces_per_cell; ++d)
2455  if ((*jt)->face(d)->at_boundary())
2456  if ( parent_face_center.distance((*jt)->face(d)->center()) < tol)
2457  {
2458  //(*jt)->set_refine_flag();
2459  if ((d==0) || (d==1))
2460  (*jt)->set_refine_flag(RefinementCase<2>::cut_axis(1));
2461  else
2462  (*jt)->set_refine_flag(RefinementCase<2>::cut_axis(0));
2463  }
2464  }
2465  }
2466  }
2467 
2468  SolutionTransfer<dim-1, Vector<double>, DoFHandler<dim-1, dim> > soltrans(dh);
2469 
2470  Vector<double> positions_x(comp_dom.dh.n_dofs());
2471  Vector<double> positions_y(comp_dom.dh.n_dofs());
2472  Vector<double> positions_z(comp_dom.dh.n_dofs());
2473  Vector<double> positions_dot_x(comp_dom.dh.n_dofs());
2474  Vector<double> positions_dot_y(comp_dom.dh.n_dofs());
2475  Vector<double> positions_dot_z(comp_dom.dh.n_dofs());
2476 
2477  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2478  {
2479  positions_x(i) = solution(3*i+0)+comp_dom.rigid_motion_map_points(3*i+0)+comp_dom.ref_points[3*i](0);
2480  positions_y(i) = solution(3*i+1)+comp_dom.rigid_motion_map_points(3*i+1)+comp_dom.ref_points[3*i](1);
2481  positions_z(i) = solution(3*i+2)+comp_dom.rigid_motion_map_points(3*i+2)+comp_dom.ref_points[3*i](2);
2482  positions_dot_x(i) = solution_dot(3*i+0);
2483  positions_dot_y(i) = solution_dot(3*i+1);
2484  positions_dot_z(i) = solution_dot(3*i+2);
2485  }
2486 
2487  std::vector<Vector<double> > all_in;
2488  all_in.push_back((Vector<double>)Phi);
2489  all_in.push_back((Vector<double>)Phi_dot);
2490  all_in.push_back((Vector<double>)dphi_dn);
2491  all_in.push_back((Vector<double>)dphi_dn_dot);
2492  all_in.push_back(positions_x);
2493  all_in.push_back(positions_y);
2494  all_in.push_back(positions_z);
2495  all_in.push_back(positions_dot_x);
2496  all_in.push_back(positions_dot_y);
2497  all_in.push_back(positions_dot_z);
2498 
2499  tria.prepare_coarsening_and_refinement();
2500  soltrans.prepare_for_coarsening_and_refinement(all_in);
2501 
2502 
2503 
2504  //std::cout << "Refined counter: " << refinedCellCounter << std::endl;
2505  tria.execute_coarsening_and_refinement();
2506  dh.distribute_dofs(comp_dom.fe);
2507  vector_dh.distribute_dofs(comp_dom.vector_fe);
2508  comp_dom.map_points.reinit(vector_dh.n_dofs());
2509  comp_dom.smoothing_map_points.reinit(vector_dh.n_dofs());
2510  comp_dom.old_map_points.reinit(vector_dh.n_dofs());
2511  comp_dom.rigid_motion_map_points.reinit(vector_dh.n_dofs());
2512  comp_dom.initial_map_points.reinit(vector_dh.n_dofs());
2513  comp_dom.ref_points.resize(vector_dh.n_dofs());
2514  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
2515  comp_dom.vector_dh, comp_dom.ref_points);
2516  comp_dom.generate_double_nodes_set();
2517 
2518  compute_constraints(constraints, vector_constraints);
2519 
2520  dofs_number = vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()+13;
2521 
2522  std::cout<<"Total number of dofs after restoring edges conformity: "<<dh.n_dofs()<<std::endl;
2523 
2524 
2525  Vector<double> new_Phi(dh.n_dofs());
2526  Vector<double> new_Phi_dot(dh.n_dofs());
2527 
2528  Vector <double> new_dphi_dn(dh.n_dofs());
2529  Vector <double> new_dphi_dn_dot(dh.n_dofs());
2530 
2531  Vector<double> new_positions_x(dh.n_dofs());
2532  Vector<double> new_positions_y(dh.n_dofs());
2533  Vector<double> new_positions_z(dh.n_dofs());
2534  Vector<double> new_positions_dot_x(dh.n_dofs());
2535  Vector<double> new_positions_dot_y(dh.n_dofs());
2536  Vector<double> new_positions_dot_z(dh.n_dofs());
2537 
2538  std::vector<Vector<double> > all_out;
2539  all_out.push_back(new_Phi);
2540  all_out.push_back(new_Phi_dot);
2541  all_out.push_back(new_dphi_dn);
2542  all_out.push_back(new_dphi_dn_dot);
2543  all_out.push_back(new_positions_x);
2544  all_out.push_back(new_positions_y);
2545  all_out.push_back(new_positions_z);
2546  all_out.push_back(new_positions_dot_x);
2547  all_out.push_back(new_positions_dot_y);
2548  all_out.push_back(new_positions_dot_z);
2549 
2550  soltrans.interpolate(all_in, all_out);
2551 
2552  solution.reinit(dofs_number);
2553  solution_dot.reinit(dofs_number);
2554 
2555 
2556  constraints.distribute(all_out[0]);
2557  constraints.distribute(all_out[1]);
2558  constraints.distribute(all_out[2]);
2559  constraints.distribute(all_out[3]);
2560  constraints.distribute(all_out[4]);
2561  constraints.distribute(all_out[5]);
2562  constraints.distribute(all_out[6]);
2563  constraints.distribute(all_out[7]);
2564  constraints.distribute(all_out[8]);
2565  constraints.distribute(all_out[9]);
2566 
2567 
2568  // we have to compute rigid_motion_map_points and rigid_motion_velocities on the new mesh
2569 
2570  rigid_motion_velocities.reinit(comp_dom.vector_dh.n_dofs());
2571 
2572 
2573  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
2574  // mesh (all nodes except for the free surface ones)
2575  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2576  {
2577  if ( ((comp_dom.flags[i] & boat) &&
2578  !(comp_dom.flags[i] & near_water) ) ||
2579  (comp_dom.flags[i] & transom_on_water) )
2580  {
2581  //if (fabs(t-0.2) <1e-5)
2582  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
2583  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
2584  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
2585  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
2586  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
2587  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
2588  gp_Pnt boat_mesh_point = original_boat_mesh_point;
2589  // we first take this point (which is in the RESTART hull location) and transform it to be in the
2590  // REFERENCE configuration
2591  boat_mesh_point.Transform(restart_hull_location.Inverted());
2592 
2593  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
2594  // the 7 dofs associated to the rigid linear and angular displacements
2595 
2596  double s_x = hull_lin_displ(0);
2597  double s_y = hull_lin_displ(1);
2598  double s_z = hull_lin_displ(2);
2599  double v_x = hull_quat_vect(0);
2600  double v_y = hull_quat_vect(1);
2601  double v_z = hull_quat_vect(2);
2602  double s = hull_quat_scal;
2603 
2604  Point<3> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
2605  comp_dom.boat_model.reference_hull_baricenter(1),
2606  comp_dom.boat_model.reference_hull_baricenter(2));
2607 
2608  Point<3> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
2609  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
2610  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
2611 
2612  Point<3> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
2613  Point<3> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
2614  Point<3> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
2615 
2616  Point<3> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
2617  Point<3> rigid_lin_displ(s_x,s_y,s_z);
2618  Point<3> target_point_pos(RotMatRow1*(ref_point_pos+(-1.0)*ref_baricenter_pos),
2619  RotMatRow2*(ref_point_pos+(-1.0)*ref_baricenter_pos),
2620  RotMatRow3*(ref_point_pos+(-1.0)*ref_baricenter_pos));
2621  target_point_pos += baricenter_pos;
2622  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
2623  //boat_mesh_point.Transform(reference_to_current_transformation);
2624  // the rigid motion map points is the difference between the reference point position and the
2625  // current (rigidly displaced) node position
2626  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0)-ref_point_pos(0);
2627  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1)-ref_point_pos(1);
2628  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2)-ref_point_pos(2);
2629 
2630  rigid_motion_velocities(3*i) = hull_lin_vel(0)+
2631  hull_ang_vel(1)*(target_point_pos(2)-baricenter_pos(2))-
2632  hull_ang_vel(2)*(target_point_pos(1)-baricenter_pos(1));
2633  rigid_motion_velocities(3*i+1) = hull_lin_vel(1)+
2634  hull_ang_vel(2)*(target_point_pos(0)-baricenter_pos(0))-
2635  hull_ang_vel(0)*(target_point_pos(2)-baricenter_pos(2));
2636  rigid_motion_velocities(3*i+2) = hull_lin_vel(2)+
2637  hull_ang_vel(0)*(target_point_pos(1)-baricenter_pos(1))-
2638  hull_ang_vel(1)*(target_point_pos(0)-baricenter_pos(0));
2639 
2640 
2641 
2642  //if (fabs(t-0.2) <1e-5)
2643  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
2644  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
2645  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
2646  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
2647  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
2648  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
2649  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
2650  }
2651  }
2652 
2653 
2654  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2655  {
2656  solution(3*i+0) = all_out[4](i)-comp_dom.rigid_motion_map_points(3*i)-comp_dom.ref_points[3*i](0);
2657  solution(3*i+1) = all_out[5](i)-comp_dom.rigid_motion_map_points(3*i+1)-comp_dom.ref_points[3*i](1);
2658  solution(3*i+2) = all_out[6](i)-comp_dom.rigid_motion_map_points(3*i+2)-comp_dom.ref_points[3*i](2);
2659  solution_dot(3*i+0) = all_out[7](i)-rigid_motion_velocities(3*i);
2660  solution_dot(3*i+1) = all_out[8](i)-rigid_motion_velocities(3*i+1);
2661  solution_dot(3*i+2) = all_out[9](i)-rigid_motion_velocities(3*i+2);
2662  solution(i+vector_dh.n_dofs()) = all_out[0](i);
2663  solution_dot(i+vector_dh.n_dofs()) = all_out[1](i);
2664  solution(i+vector_dh.n_dofs()+dh.n_dofs()) = all_out[2](i);
2665  solution_dot(i+vector_dh.n_dofs()+dh.n_dofs()) = all_out[3](i);
2666  }
2667 
2668  for (unsigned int k=0; k<3; ++k)
2669  {
2670  solution(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_displ(k);
2671  solution_dot(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_displ_dot(k);
2672  solution(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_vel(k);
2673  solution_dot(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_vel_dot(k);
2674  solution(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_ang_vel(k);
2675  solution_dot(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_ang_vel_dot(k);
2676  solution(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_vect(k);
2677  solution_dot(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_vect_dot(k);
2678  }
2679  solution(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_scal;
2680  solution_dot(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_scal_dot;
2681 
2682 
2683  DXDt_and_DphiDt_vector.reinit(vector_dh.n_dofs()+dh.n_dofs());
2684 
2685  DphiDt_sparsity_pattern.reinit (dh.n_dofs(),
2686  dh.n_dofs(),
2687  dh.max_couplings_between_dofs());
2688  vector_sparsity_pattern.reinit (vector_dh.n_dofs(),
2689  vector_dh.n_dofs(),
2690  vector_dh.max_couplings_between_dofs());
2691 
2692  DoFTools::make_sparsity_pattern (dh, DphiDt_sparsity_pattern, constraints);
2693  DphiDt_sparsity_pattern.compress();
2694 
2695  DoFTools::make_sparsity_pattern (vector_dh, vector_sparsity_pattern, vector_constraints);
2696  vector_sparsity_pattern.compress();
2697 
2698  working_map_points.reinit(comp_dom.vector_dh.n_dofs());
2699  working_nodes_velocities.reinit(comp_dom.vector_dh.n_dofs());
2700  nodes_pos_res.reinit(comp_dom.vector_dh.n_dofs());
2701  nodes_ref_surf_dist.reinit(comp_dom.vector_dh.n_dofs());
2702  nodes_diff_jac_x_delta.reinit(dofs_number);
2703  nodes_alg_jac_x_delta.reinit(dofs_number);
2704  dae_nonlin_residual.reinit(dofs_number);
2705  dae_linear_step_residual.reinit(dofs_number);
2706  current_sol.reinit(dofs_number);
2707  current_sol_dot.reinit(dofs_number);
2708  bem_residual.reinit(comp_dom.dh.n_dofs());
2709  bem_phi.reinit(comp_dom.dh.n_dofs());
2710  bem_dphi_dn.reinit(comp_dom.dh.n_dofs());
2711  temp_src.reinit(comp_dom.vector_dh.n_dofs());
2712  break_wave_press.reinit(comp_dom.dh.n_dofs());
2713 
2714 
2715 
2716  bem.reinit();
2717 
2718  support_points.resize(dh.n_dofs());
2719  DoFTools::map_dofs_to_support_points<2, 3>( *comp_dom.mapping, dh, support_points);
2720  std::vector<bool> new_boundary_dofs(vector_dh.n_dofs());
2721  std::vector< bool > comp_sel(3, true);
2722  DoFTools::extract_boundary_dofs(vector_dh, comp_sel, new_boundary_dofs);
2723  for (unsigned int i=0; i<dh.n_dofs(); ++i)
2724  for (unsigned int j=0; j<old_points.size(); ++j)
2725  if (old_points[j].distance(support_points[i]) < 1e-5)
2726  {
2727  new_boundary_dofs[3*i] = 1;
2728  new_boundary_dofs[3*i+1] = 1;
2729  new_boundary_dofs[3*i+2] = 1;
2730  }
2731 
2732  //comp_dom.apply_curvatures(new_curvatures,new_boundary_dofs);
2733  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
2734  {
2735  comp_dom.map_points(i) = solution(i)+comp_dom.rigid_motion_map_points(i);
2736  }
2737  //std::string filename2 = ( "beforeCrash.vtu" );
2738  //output_results(filename2, t, solution, solution_dot);
2739 
2740  if (!comp_dom.no_boat)
2741  comp_dom.evaluate_ref_surf_distances(nodes_ref_surf_dist,false);
2742  comp_dom.map_points -= nodes_ref_surf_dist;
2743  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
2744  {
2745  solution(i) = comp_dom.map_points(i)-comp_dom.rigid_motion_map_points(i);
2746  }
2747 
2748 
2749  // in particular we must get the position of the nodes (in terms of curvilinear length)
2750  // on the smoothing lines, and the corresponding potential and horizontal velcoity values, in order to
2751  // interpolate the new values to be assigned at the restart of the simulation
2752 
2753  for (unsigned smooth_id=0; smooth_id<comp_dom.line_smoothers.size(); ++smooth_id)
2754  {
2755  Vector<double> &old_lengths = comp_dom.line_smoothers[smooth_id]->get_lengths_before_smoothing();
2756  Vector<double> &new_lengths = comp_dom.line_smoothers[smooth_id]->get_lengths_after_smoothing();
2757  std::vector<unsigned int> &indices = comp_dom.line_smoothers[smooth_id]->get_node_indices();
2758  Vector<double> old_potentials(old_lengths.size());
2759  Vector<double> old_vx(old_lengths.size());
2760  Vector<double> old_vy(old_lengths.size());
2761  //Vector<double> new_potentials(old_lengths.size());
2762  for (unsigned int i=0; i<old_lengths.size(); ++i)
2763  {
2764  old_potentials(i) = solution(indices[i]+vector_dh.n_dofs());
2765  old_vx(i) = solution_dot(3*indices[i]);
2766  old_vy(i) = solution_dot(3*indices[i]+1);
2767  //cout<<i<<"("<<indices[i]<<"->"<<round(indices[i]/3)<<") "<<old_lengths(i)<<" vs "<<new_lengths(i)<<" pot: "<<old_potentials(i)<<endl;
2768  //cout<<indices[i]<<" "<<comp_dom.support_points[indices[i]]<<endl;
2769  }
2770  //new_potentials(0) = old_potentials(0);
2771  //new_potentials(old_lengths.size()-1) = old_potentials(old_lengths.size()-1);
2772  for (unsigned int i=1; i<old_lengths.size()-1; ++i)
2773  {
2774  unsigned int jj=1000000;
2775  for (unsigned int j=1; j<old_lengths.size(); ++j)
2776  {
2777  if (new_lengths(i) < old_lengths(j))
2778  {
2779  jj = j;
2780  break;
2781  }
2782  }
2783  double fraction = (new_lengths(i)-old_lengths(jj-1))/(old_lengths(jj)-old_lengths(jj-1));
2784  solution(indices[i]+vector_dh.n_dofs()) = old_potentials(jj-1)+(old_potentials(jj)-old_potentials(jj-1))*fraction;
2785  //solution_dot(3*indices[i]) = old_vx(jj-1)+(old_vx(jj)-old_vx(jj-1))*fraction;
2786  //solution_dot(3*indices[i]+1) = old_vy(jj-1)+(old_vy(jj)-old_vy(jj-1))*fraction;
2787  //cout<<i<<" ---> "<<jj<<" "<<fraction<<" "<<old_potentials(jj-1)<<" "<<old_potentials(jj)<<" "<<new_potentials(i)<<endl;
2788  }
2789  }
2790 
2791  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2792  {
2793  if ( (!(comp_dom.flags[i] & near_boat)==0) &&
2794  (!(comp_dom.flags[i] & near_water)==0))
2795  {
2796  solution_dot(3*i) = 0;
2797  solution_dot(3*i+1) = 0;
2798  }
2799  }
2800 
2801  //std::string filename2 = ( "postPostPostRemesh.vtu" );
2802  //output_results(filename2, t, solution, solution_dot);
2803 
2804  std::cout<<"...Done restoring mesh conformity"<<std::endl;
2805 }
2806 
2807 
2808 
2809 template <int dim>
2811  Vector<double> &solution_dot,
2812  const double t,
2813  const unsigned int step_number,
2814  const double h)
2815 {
2816  std::cout<<"Removing hanging nodes from transom stern..."<<std::endl;
2817 
2818  Point<3> hull_lin_vel;
2819  Point<3> hull_lin_displ;
2820  Point<3> hull_lin_vel_dot;
2821  Point<3> hull_lin_displ_dot;
2822  Point<3> hull_ang_vel;
2823  Point<3> hull_ang_vel_dot;
2824  Point<3> hull_quat_vect;
2825  Point<3> hull_quat_vect_dot;
2826  double hull_quat_scal;
2827  double hull_quat_scal_dot;
2828  for (unsigned int d=0; d<3; ++d)
2829  {
2830  hull_lin_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
2831  hull_lin_displ(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
2832  hull_lin_vel_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
2833  hull_lin_displ_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
2834  hull_ang_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
2835  hull_ang_vel_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
2836  hull_quat_vect(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
2837  hull_quat_vect_dot(d) = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
2838  }
2839  hull_quat_scal = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
2840  hull_quat_scal_dot = solution_dot(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
2841 
2842  cout<<"*Hull Rigid Displacement: "<<hull_lin_displ<<endl;
2843  cout<<"*Hull Rigid Velocity: "<<hull_lin_vel<<endl;
2844  cout<<"*Hull Angualr Velocity: "<<hull_lin_vel<<endl;
2845 
2846 
2847  Vector<double> rigid_motion_velocities(comp_dom.vector_dh.n_dofs());
2848 
2849  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
2850  // mesh (all nodes except for the free surface ones)
2851  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2852  {
2853  if ( ((comp_dom.flags[i] & boat) &&
2854  !(comp_dom.flags[i] & near_water) ) ||
2855  (comp_dom.flags[i] & transom_on_water) )
2856  {
2857  //if (fabs(t-0.2) <1e-5)
2858  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
2859  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
2860  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
2861  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
2862  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
2863  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
2864  gp_Pnt boat_mesh_point = original_boat_mesh_point;
2865  // we first take this point (which is in the RESTART hull location) and transform it to be in the
2866  // REFERENCE configuration
2867  boat_mesh_point.Transform(restart_hull_location.Inverted());
2868 
2869  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
2870  // the 7 dofs associated to the rigid linear and angular displacements
2871 
2872  double s_x = hull_lin_displ(0);
2873  double s_y = hull_lin_displ(1);
2874  double s_z = hull_lin_displ(2);
2875  double v_x = hull_quat_vect(0);
2876  double v_y = hull_quat_vect(1);
2877  double v_z = hull_quat_vect(2);
2878  double s = hull_quat_scal;
2879 
2880  Point<3> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
2881  comp_dom.boat_model.reference_hull_baricenter(1),
2882  comp_dom.boat_model.reference_hull_baricenter(2));
2883 
2884  Point<3> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
2885  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
2886  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
2887 
2888  Point<3> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
2889  Point<3> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
2890  Point<3> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
2891 
2892  Point<3> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
2893  Point<3> rigid_lin_displ(s_x,s_y,s_z);
2894  Point<3> target_point_pos(RotMatRow1*(ref_point_pos+(-1.0)*ref_baricenter_pos),
2895  RotMatRow2*(ref_point_pos+(-1.0)*ref_baricenter_pos),
2896  RotMatRow3*(ref_point_pos+(-1.0)*ref_baricenter_pos));
2897  target_point_pos += baricenter_pos;
2898  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
2899  //boat_mesh_point.Transform(reference_to_current_transformation);
2900  // the rigid motion map points is the difference between the reference point position and the
2901  // current (rigidly displaced) node position
2902  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0)-ref_point_pos(0);
2903  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1)-ref_point_pos(1);
2904  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2)-ref_point_pos(2);
2905 
2906  rigid_motion_velocities(3*i) = hull_lin_vel(0)+
2907  hull_ang_vel(1)*(target_point_pos(2)-baricenter_pos(2))-
2908  hull_ang_vel(2)*(target_point_pos(1)-baricenter_pos(1));
2909  rigid_motion_velocities(3*i+1) = hull_lin_vel(1)+
2910  hull_ang_vel(2)*(target_point_pos(0)-baricenter_pos(0))-
2911  hull_ang_vel(0)*(target_point_pos(2)-baricenter_pos(2));
2912  rigid_motion_velocities(3*i+2) = hull_lin_vel(2)+
2913  hull_ang_vel(0)*(target_point_pos(1)-baricenter_pos(1))-
2914  hull_ang_vel(1)*(target_point_pos(0)-baricenter_pos(0));
2915 
2916 
2917 
2918  //if (fabs(t-0.2) <1e-5)
2919  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
2920  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
2921  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
2922  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
2923  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
2924  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
2925  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
2926  }
2927  }
2928 
2929 
2930  Triangulation<dim-1, dim> &tria = comp_dom.tria;
2931  DoFHandler<dim-1, dim> &dh = comp_dom.dh;
2932  DoFHandler<dim-1, dim> &vector_dh = comp_dom.vector_dh;
2933 
2934 
2935  std::vector<Point<dim> > support_points(dh.n_dofs());
2936  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, dh, support_points);
2937 
2938 
2939 
2940  VectorView<double> Phi(dh.n_dofs(), solution.begin()+vector_dh.n_dofs());
2941  VectorView<double> Phi_dot(dh.n_dofs(), solution_dot.begin()+vector_dh.n_dofs());
2942  VectorView<double> dphi_dn(dh.n_dofs(), solution.begin()+vector_dh.n_dofs()+dh.n_dofs());
2943  VectorView<double> dphi_dn_dot(dh.n_dofs(), solution_dot.begin()+vector_dh.n_dofs()+dh.n_dofs());
2944 
2945  std::vector<Point<3> > old_points(dh.n_dofs());
2946  old_points = support_points;
2947 
2948  Vector<double> curvatures(vector_dh.n_dofs());
2949  comp_dom.surface_smoother->compute_curvatures(curvatures);
2950 
2951  // Get support points in the
2952  // reference configuration
2953  std::vector<Point<3> > ref_points(dh.n_dofs());
2954  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
2955  dh, ref_points);
2956  unsigned int refinedCellCounter = 1;
2957 
2958  while (refinedCellCounter)
2959  {
2960  refinedCellCounter = 0;
2961  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
2962  {
2963  if ((comp_dom.flags[i] & transom_on_water) )
2964  //if ((comp_dom.flags[i] & water) && (comp_dom.flags[i] & near_boat))
2965  {
2966  //cout<<i<<": "<<support_points[i]<<endl;
2967  std::vector<cell_it> cells = comp_dom.dof_to_elems[i];
2968  for (unsigned int k=0; k<cells.size(); ++k)
2969  {
2970  //cout<<k<<": "<<cells[k]<<" ("<<cells[k]->center()<<")"<<endl;
2971  for (unsigned int j=0; j<GeometryInfo<2>::faces_per_cell; ++j)
2972  {
2973  //cout<<"j: "<<j<<" nb: "<<cells[k]->neighbor_index(j)<<" ("<<endl;
2974  if (cells[k]->neighbor_index(j) != -1)
2975  if ( cells[k]->neighbor(j)->at_boundary() &&
2976  (cells[k]->neighbor_is_coarser(j) || cells[k]->refine_flag_set() ) &&
2977  !(cells[k]->neighbor(j)->refine_flag_set()) )
2978  {
2979  //cout<<"FOUND: "<<cells[k]->neighbor(j)<<" ("<<cells[k]->neighbor(j)->center()<<")"<<endl;
2980  cells[k]->neighbor(j)->set_refine_flag();
2981  refinedCellCounter++;
2982  }
2983  }
2984  }
2985  }
2986  }
2987 
2988  }
2989 
2990  SolutionTransfer<dim-1, Vector<double>, DoFHandler<dim-1, dim> > soltrans(dh);
2991 
2992  Vector<double> positions_x(comp_dom.dh.n_dofs());
2993  Vector<double> positions_y(comp_dom.dh.n_dofs());
2994  Vector<double> positions_z(comp_dom.dh.n_dofs());
2995  Vector<double> positions_dot_x(comp_dom.dh.n_dofs());
2996  Vector<double> positions_dot_y(comp_dom.dh.n_dofs());
2997  Vector<double> positions_dot_z(comp_dom.dh.n_dofs());
2998 
2999  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3000  {
3001  positions_x(i) = solution(3*i+0)+comp_dom.rigid_motion_map_points(3*i+0)+comp_dom.ref_points[3*i](0);
3002  positions_y(i) = solution(3*i+1)+comp_dom.rigid_motion_map_points(3*i+1)+comp_dom.ref_points[3*i](1);
3003  positions_z(i) = solution(3*i+2)+comp_dom.rigid_motion_map_points(3*i+2)+comp_dom.ref_points[3*i](2);
3004  positions_dot_x(i) = solution_dot(3*i+0);
3005  positions_dot_y(i) = solution_dot(3*i+1);
3006  positions_dot_z(i) = solution_dot(3*i+2);
3007  }
3008 
3009  std::vector<Vector<double> > all_in;
3010  all_in.push_back((Vector<double>)Phi);
3011  all_in.push_back((Vector<double>)Phi_dot);
3012  all_in.push_back((Vector<double>)dphi_dn);
3013  all_in.push_back((Vector<double>)dphi_dn_dot);
3014  all_in.push_back(positions_x);
3015  all_in.push_back(positions_y);
3016  all_in.push_back(positions_z);
3017  all_in.push_back(positions_dot_x);
3018  all_in.push_back(positions_dot_y);
3019  all_in.push_back(positions_dot_z);
3020 
3021  tria.prepare_coarsening_and_refinement();
3022  soltrans.prepare_for_coarsening_and_refinement(all_in);
3023 
3024 
3025 
3026  //std::cout << "Refined counter: " << refinedCellCounter << std::endl;
3027  tria.execute_coarsening_and_refinement();
3028  dh.distribute_dofs(comp_dom.fe);
3029  vector_dh.distribute_dofs(comp_dom.vector_fe);
3030  comp_dom.map_points.reinit(vector_dh.n_dofs());
3031  comp_dom.smoothing_map_points.reinit(vector_dh.n_dofs());
3032  comp_dom.old_map_points.reinit(vector_dh.n_dofs());
3033  comp_dom.rigid_motion_map_points.reinit(vector_dh.n_dofs());
3034  comp_dom.initial_map_points.reinit(vector_dh.n_dofs());
3035  comp_dom.ref_points.resize(vector_dh.n_dofs());
3036  DoFTools::map_dofs_to_support_points<2,3>(StaticMappingQ1<2,3>::mapping,
3037  comp_dom.vector_dh, comp_dom.ref_points);
3038  comp_dom.generate_double_nodes_set();
3039 
3040  compute_constraints(constraints, vector_constraints);
3041 
3042  dofs_number = vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()+13;
3043 
3044  std::cout<<"Total number of dofs after fixing transom stern: "<<dh.n_dofs()<<std::endl;
3045 
3046 
3047  Vector<double> new_Phi(dh.n_dofs());
3048  Vector<double> new_Phi_dot(dh.n_dofs());
3049 
3050  Vector <double> new_dphi_dn(dh.n_dofs());
3051  Vector <double> new_dphi_dn_dot(dh.n_dofs());
3052 
3053  Vector<double> new_positions_x(dh.n_dofs());
3054  Vector<double> new_positions_y(dh.n_dofs());
3055  Vector<double> new_positions_z(dh.n_dofs());
3056  Vector<double> new_positions_dot_x(dh.n_dofs());
3057  Vector<double> new_positions_dot_y(dh.n_dofs());
3058  Vector<double> new_positions_dot_z(dh.n_dofs());
3059 
3060  std::vector<Vector<double> > all_out;
3061  all_out.push_back(new_Phi);
3062  all_out.push_back(new_Phi_dot);
3063  all_out.push_back(new_dphi_dn);
3064  all_out.push_back(new_dphi_dn_dot);
3065  all_out.push_back(new_positions_x);
3066  all_out.push_back(new_positions_y);
3067  all_out.push_back(new_positions_z);
3068  all_out.push_back(new_positions_dot_x);
3069  all_out.push_back(new_positions_dot_y);
3070  all_out.push_back(new_positions_dot_z);
3071 
3072  soltrans.interpolate(all_in, all_out);
3073 
3074  solution.reinit(dofs_number);
3075  solution_dot.reinit(dofs_number);
3076 
3077 
3078  constraints.distribute(all_out[0]);
3079  constraints.distribute(all_out[1]);
3080  constraints.distribute(all_out[2]);
3081  constraints.distribute(all_out[3]);
3082  constraints.distribute(all_out[4]);
3083  constraints.distribute(all_out[5]);
3084  constraints.distribute(all_out[6]);
3085  constraints.distribute(all_out[7]);
3086  constraints.distribute(all_out[8]);
3087  constraints.distribute(all_out[9]);
3088 
3089  // we have to compute rigid_motion_map_points and rigid_motion_velocities on the new mesh
3090 
3091  rigid_motion_velocities.reinit(comp_dom.vector_dh.n_dofs());
3092 
3093  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
3094  // mesh (all nodes except for the free surface ones)
3095  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3096  {
3097  if ( ((comp_dom.flags[i] & boat) &&
3098  !(comp_dom.flags[i] & near_water) ) ||
3099  (comp_dom.flags[i] & transom_on_water) )
3100  {
3101  //if (fabs(t-0.2) <1e-5)
3102  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
3103  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
3104  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
3105  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
3106  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
3107  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
3108  gp_Pnt boat_mesh_point = original_boat_mesh_point;
3109  // we first take this point (which is in the RESTART hull location) and transform it to be in the
3110  // REFERENCE configuration
3111  boat_mesh_point.Transform(restart_hull_location.Inverted());
3112 
3113  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
3114  // the 7 dofs associated to the rigid linear and angular displacements
3115 
3116  double s_x = hull_lin_displ(0);
3117  double s_y = hull_lin_displ(1);
3118  double s_z = hull_lin_displ(2);
3119  double v_x = hull_quat_vect(0);
3120  double v_y = hull_quat_vect(1);
3121  double v_z = hull_quat_vect(2);
3122  double s = hull_quat_scal;
3123 
3124  Point<3> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
3125  comp_dom.boat_model.reference_hull_baricenter(1),
3126  comp_dom.boat_model.reference_hull_baricenter(2));
3127 
3128  Point<3> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
3129  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
3130  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
3131 
3132  Point<3> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
3133  Point<3> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
3134  Point<3> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
3135 
3136  Point<3> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
3137  Point<3> rigid_lin_displ(s_x,s_y,s_z);
3138  Point<3> target_point_pos(RotMatRow1*(ref_point_pos+(-1.0)*ref_baricenter_pos),
3139  RotMatRow2*(ref_point_pos+(-1.0)*ref_baricenter_pos),
3140  RotMatRow3*(ref_point_pos+(-1.0)*ref_baricenter_pos));
3141  target_point_pos += baricenter_pos;
3142  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
3143  //boat_mesh_point.Transform(reference_to_current_transformation);
3144  // the rigid motion map points is the difference between the reference point position and the
3145  // current (rigidly displaced) node position
3146  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0)-ref_point_pos(0);
3147  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1)-ref_point_pos(1);
3148  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2)-ref_point_pos(2);
3149 
3150  rigid_motion_velocities(3*i) = hull_lin_vel(0)+
3151  hull_ang_vel(1)*(target_point_pos(2)-baricenter_pos(2))-
3152  hull_ang_vel(2)*(target_point_pos(1)-baricenter_pos(1));
3153  rigid_motion_velocities(3*i+1) = hull_lin_vel(1)+
3154  hull_ang_vel(2)*(target_point_pos(0)-baricenter_pos(0))-
3155  hull_ang_vel(0)*(target_point_pos(2)-baricenter_pos(2));
3156  rigid_motion_velocities(3*i+2) = hull_lin_vel(2)+
3157  hull_ang_vel(0)*(target_point_pos(1)-baricenter_pos(1))-
3158  hull_ang_vel(1)*(target_point_pos(0)-baricenter_pos(0));
3159 
3160 
3161 
3162  //if (fabs(t-0.2) <1e-5)
3163  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
3164  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
3165  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
3166  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
3167  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
3168  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
3169  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
3170  }
3171  }
3172 
3173  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3174  {
3175  solution(3*i+0) = all_out[4](i)-comp_dom.rigid_motion_map_points(3*i)-comp_dom.ref_points[3*i](0);
3176  solution(3*i+1) = all_out[5](i)-comp_dom.rigid_motion_map_points(3*i+1)-comp_dom.ref_points[3*i](1);
3177  solution(3*i+2) = all_out[6](i)-comp_dom.rigid_motion_map_points(3*i+2)-comp_dom.ref_points[3*i](2);
3178  solution_dot(3*i+0) = all_out[7](i);
3179  solution_dot(3*i+1) = all_out[8](i);
3180  solution_dot(3*i+2) = all_out[9](i);
3181  solution(i+vector_dh.n_dofs()) = all_out[0](i);
3182  solution_dot(i+vector_dh.n_dofs()) = all_out[1](i);
3183  solution(i+vector_dh.n_dofs()+dh.n_dofs()) = all_out[2](i);
3184  solution_dot(i+vector_dh.n_dofs()+dh.n_dofs()) = all_out[3](i);
3185  }
3186 
3187  for (unsigned int k=0; k<3; ++k)
3188  {
3189  solution(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_displ(k);
3190  solution_dot(k+3+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_displ_dot(k);
3191  solution(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_vel(k);
3192  solution_dot(k+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_lin_vel_dot(k);
3193  solution(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_ang_vel(k);
3194  solution_dot(k+6+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_ang_vel_dot(k);
3195  solution(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_vect(k);
3196  solution_dot(k+9+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_vect_dot(k);
3197  }
3198  solution(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_scal;
3199  solution_dot(12+vector_dh.n_dofs()+dh.n_dofs()+dh.n_dofs()) = hull_quat_scal_dot;
3200 
3201 
3202 
3203  DXDt_and_DphiDt_vector.reinit(vector_dh.n_dofs()+dh.n_dofs());
3204 
3205  DphiDt_sparsity_pattern.reinit (dh.n_dofs(),
3206  dh.n_dofs(),
3207  dh.max_couplings_between_dofs());
3208  vector_sparsity_pattern.reinit (vector_dh.n_dofs(),
3209  vector_dh.n_dofs(),
3210  vector_dh.max_couplings_between_dofs());
3211 
3212  DoFTools::make_sparsity_pattern (dh, DphiDt_sparsity_pattern, constraints);
3213  DphiDt_sparsity_pattern.compress();
3214 
3215  DoFTools::make_sparsity_pattern (vector_dh, vector_sparsity_pattern, vector_constraints);
3216  vector_sparsity_pattern.compress();
3217 
3218  working_map_points.reinit(comp_dom.vector_dh.n_dofs());
3219  working_nodes_velocities.reinit(comp_dom.vector_dh.n_dofs());
3220  nodes_pos_res.reinit(comp_dom.vector_dh.n_dofs());
3221  nodes_ref_surf_dist.reinit(comp_dom.vector_dh.n_dofs());
3222  nodes_diff_jac_x_delta.reinit(dofs_number);
3223  nodes_alg_jac_x_delta.reinit(dofs_number);
3224  dae_nonlin_residual.reinit(dofs_number);
3225  dae_linear_step_residual.reinit(dofs_number);
3226  current_sol.reinit(dofs_number);
3227  current_sol_dot.reinit(dofs_number);
3228  bem_residual.reinit(comp_dom.dh.n_dofs());
3229  bem_phi.reinit(comp_dom.dh.n_dofs());
3230  bem_dphi_dn.reinit(comp_dom.dh.n_dofs());
3231  temp_src.reinit(comp_dom.vector_dh.n_dofs());
3232  break_wave_press.reinit(comp_dom.dh.n_dofs());
3233 
3234 
3235 
3236  bem.reinit();
3237 
3238  support_points.resize(dh.n_dofs());
3239  DoFTools::map_dofs_to_support_points<2, 3>( *comp_dom.mapping, dh, support_points);
3240  std::vector<bool> new_boundary_dofs(vector_dh.n_dofs());
3241  std::vector< bool > comp_sel(3, true);
3242  DoFTools::extract_boundary_dofs(vector_dh, comp_sel, new_boundary_dofs);
3243  for (unsigned int i=0; i<dh.n_dofs(); ++i)
3244  for (unsigned int j=0; j<old_points.size(); ++j)
3245  if (old_points[j].distance(support_points[i]) < 1e-5)
3246  {
3247  new_boundary_dofs[3*i] = 1;
3248  new_boundary_dofs[3*i+1] = 1;
3249  new_boundary_dofs[3*i+2] = 1;
3250  }
3251 
3252  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
3253  {
3254  comp_dom.map_points(i) = solution(i)+comp_dom.rigid_motion_map_points(i);
3255  }
3256 
3257  //std::string filename2 = ( "beforeCrash.vtu" );
3258  //output_results(filename2, t, solution, solution_dot);
3259 
3260  if (!comp_dom.no_boat)
3261  comp_dom.evaluate_ref_surf_distances(nodes_ref_surf_dist,false);
3262  comp_dom.map_points -= nodes_ref_surf_dist;
3263  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
3264  {
3265  solution(i) = comp_dom.map_points(i)-comp_dom.rigid_motion_map_points(i);
3266  }
3267 
3268 
3269 
3270 
3271  // in particular we must get the position of the nodes (in terms of curvilinear length)
3272  // on the smoothing lines, and the corresponding potential and horizontal velcoity values, in order to
3273  // interpolate the new values to be assigned at the restart of the simulation
3274 
3275  for (unsigned smooth_id=0; smooth_id<comp_dom.line_smoothers.size(); ++smooth_id)
3276  {
3277  Vector<double> &old_lengths = comp_dom.line_smoothers[smooth_id]->get_lengths_before_smoothing();
3278  Vector<double> &new_lengths = comp_dom.line_smoothers[smooth_id]->get_lengths_after_smoothing();
3279  std::vector<unsigned int> &indices = comp_dom.line_smoothers[smooth_id]->get_node_indices();
3280  Vector<double> old_potentials(old_lengths.size());
3281  Vector<double> old_vx(old_lengths.size());
3282  Vector<double> old_vy(old_lengths.size());
3283  //Vector<double> new_potentials(old_lengths.size());
3284  for (unsigned int i=0; i<old_lengths.size(); ++i)
3285  {
3286  old_potentials(i) = solution(indices[i]+vector_dh.n_dofs());
3287  old_vx(i) = solution_dot(3*indices[i]);
3288  old_vy(i) = solution_dot(3*indices[i]+1);
3289  //cout<<i<<"("<<indices[i]<<"->"<<round(indices[i]/3)<<") "<<old_lengths(i)<<" vs "<<new_lengths(i)<<" pot: "<<old_potentials(i)<<endl;
3290  //cout<<indices[i]<<" "<<comp_dom.support_points[indices[i]]<<endl;
3291  }
3292  //new_potentials(0) = old_potentials(0);
3293  //new_potentials(old_lengths.size()-1) = old_potentials(old_lengths.size()-1);
3294  for (unsigned int i=1; i<old_lengths.size()-1; ++i)
3295  {
3296  unsigned int jj=1000000;
3297  for (unsigned int j=1; j<old_lengths.size(); ++j)
3298  {
3299  if (new_lengths(i) < old_lengths(j))
3300  {
3301  jj = j;
3302  break;
3303  }
3304  }
3305  double fraction = (new_lengths(i)-old_lengths(jj-1))/(old_lengths(jj)-old_lengths(jj-1));
3306  solution(indices[i]+vector_dh.n_dofs()) = old_potentials(jj-1)+(old_potentials(jj)-old_potentials(jj-1))*fraction;
3307  //solution_dot(3*indices[i]) = old_vx(jj-1)+(old_vx(jj)-old_vx(jj-1))*fraction;
3308  //solution_dot(3*indices[i]+1) = old_vy(jj-1)+(old_vy(jj)-old_vy(jj-1))*fraction;
3309  //cout<<i<<" ---> "<<jj<<" "<<fraction<<" "<<old_potentials(jj-1)<<" "<<old_potentials(jj)<<" "<<new_potentials(i)<<endl;
3310  }
3311  }
3312 
3313  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3314  {
3315  if ( (!(comp_dom.flags[i] & near_boat)==0) &&
3316  (!(comp_dom.flags[i] & near_water)==0))
3317  {
3318  solution_dot(3*i) = 0;
3319  solution_dot(3*i+1) = 0;
3320  }
3321  }
3322 
3323  //std::string filename2 = ( "postPostPostRemesh.vtu" );
3324  //output_results(filename2, t, solution, solution_dot);
3325 
3326  std::cout<<"...Done removing hanging nodes from transom stern"<<std::endl;
3327 }
3328 
3329 
3330 template <int dim>
3331 void FreeSurface<dim>::prepare_restart(const double t, Vector<double> &y, Vector<double> &yp, bool restart_flag)
3332 {
3333  std::cout<<"Preparing interpolated solution for restart"<<std::endl;
3334 
3335 
3336 
3337  Vector<double> res;
3338  res.reinit(sys_comp.size());
3339  //yp.reinit(sys_comp.size());
3340 //cout<<"CHECK1"<<endl;
3341 //residual(t,res,y,yp);
3342 //setup_jacobian_prec(t,y,yp,0.0);
3343 
3344 
3345 
3346 
3347 
3348  // first of all, all yp for coordinates is to be set to zero: at restarts all is idle
3349  if (restart_flag)
3350  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
3351  yp(i) = 0;
3352 
3353 
3354 
3355 
3356  const VectorView<double> nodes_positions(comp_dom.vector_dh.n_dofs(),y.begin());
3357  const VectorView<double> nodes_velocities(comp_dom.vector_dh.n_dofs(),yp.begin());
3358  const VectorView<double> phi(comp_dom.dh.n_dofs(),y.begin()+comp_dom.vector_dh.n_dofs());
3359  const VectorView<double> phi_time_derivs(comp_dom.dh.n_dofs(),yp.begin()+comp_dom.vector_dh.n_dofs());
3360  const VectorView<double> dphi_dn(comp_dom.dh.n_dofs(),y.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
3361  const VectorView<double> dphi_dn_time_derivs(comp_dom.dh.n_dofs(),yp.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
3362 
3363  Point<3> hull_lin_vel;
3364  Point<3> hull_lin_displ;
3365  Point<3> hull_lin_vel_dot;
3366  Point<3> hull_lin_displ_dot;
3367  Point<3> hull_ang_vel;
3368  Point<3> hull_quat_vector;
3369  Point<3> hull_ang_vel_dot;
3370  Point<3> hull_quat_vector_dot;
3371  for (unsigned int d=0; d<3; ++d)
3372  {
3373  hull_lin_vel(d) = y(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
3374  hull_lin_displ(d) = y(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
3375  hull_lin_vel_dot(d) = yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
3376  hull_lin_displ_dot(d) = yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
3377  hull_ang_vel(d) = y(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
3378  hull_quat_vector(d) = y(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
3379  hull_ang_vel_dot(d) = yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
3380  hull_quat_vector_dot(d) = yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
3381  }
3382  double hull_quat_scalar = y(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
3383  double hull_quat_scalar_dot = yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
3384 
3385  cout<<"*Hull Rigid Displacement: "<<hull_lin_displ<<endl;
3386  cout<<"*Hull Rigid Velocity: "<<hull_lin_vel<<endl;
3387  cout<<"*Hull Angular Velocity: "<<hull_ang_vel<<endl;
3388  //let's start with rigid modes variables
3389  for (unsigned int d=0; d<3; ++d)
3390  {
3391  yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d) = hull_lin_vel(d);
3392  }
3393 
3394 // for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3395 // cout<<i<<" Poss: "<<" "<<nodes_positions(3*i)<<" "<<nodes_positions(3*i+1)<<" "<<nodes_positions(3*i+2)<<endl;
3396 // for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3397 // cout<<i<<" Vels: "<<" "<<nodes_velocities(3*i)<<" "<<nodes_velocities(3*i+1)<<" "<<nodes_velocities(3*i+2)<<endl;
3398 // for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3399 // cout<<i<<" Pot: "<<" "<<phi(i)<<" Pod_dot: "<<phi_time_derivs(i)<<" dphi_dn: "<<dphi_dn(i)<<endl;
3400  // TO BE REMOVED
3401  DphiDt_sys_rhs.reinit (comp_dom.dh.n_dofs());
3402  DphiDt_sys_rhs_2.reinit (comp_dom.dh.n_dofs());
3403  DphiDt_sys_rhs_3.reinit (comp_dom.dh.n_dofs());
3404  DphiDt_sys_rhs_4.reinit (comp_dom.dh.n_dofs());
3405  DphiDt_sys_matrix.reinit(DphiDt_sparsity_pattern);
3406  DphiDt_sys_matrix_2.reinit(DphiDt_sparsity_pattern);
3407 
3408 
3409  wind.set_time(t);
3410  Vector<double> instantWindValue(dim);
3411  Point<dim> zero(0,0,0);
3412  wind.vector_value(zero,instantWindValue);
3413  std::cout<<std::endl<<"Simulation time= "<<t<<" Vinf= ";
3414  instantWindValue.print(std::cout,4,false,true);
3415  std::cout << "Ndofs ODE= " << y.size();
3416  std::cout << " Ndofs BEM= " << comp_dom.dh.n_dofs();
3417  std::cout<<std::endl;
3418  wind.set_time(t);
3419 // we'll need Vinf
3420  Vector<double> wind_value(dim);
3421  wind.vector_value(Point<3>(0.0,0.0,0.0),wind_value);
3422  Point<dim> Vinf;
3423  for (unsigned int i = 0; i < dim; i++)
3424  Vinf(i) = wind_value(i);
3425 
3426  cout<<"Hull Rigid Displacement: "<<hull_lin_displ<<endl;
3427  cout<<"Hull Rigid Velocity: "<<hull_lin_vel<<endl;
3428 
3430  // here we take care of the geometric part of the variables
3432  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
3433  // mesh (all nodes except for the free surface ones)
3434  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3435  {
3436  if ( ((comp_dom.flags[i] & boat) &&
3437  !(comp_dom.flags[i] & near_water) ) ||
3438  (comp_dom.flags[i] & transom_on_water) )
3439  {
3440  //if (fabs(t-0.2) <1e-5)
3441  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
3442  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
3443  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
3444  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
3445  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
3446  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
3447  gp_Pnt boat_mesh_point = original_boat_mesh_point;
3448  // we first take this point (which is in the RESTART hull location) and transform it to be in the
3449  // REFERENCE configuration
3450  boat_mesh_point.Transform(restart_hull_location.Inverted());
3451 
3452  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
3453  // the 7 dofs associated to the rigid linear and angular displacements
3454  double s_x,s_y,s_z,v_x,v_y,v_z,s;
3455 
3456  s_x = hull_lin_displ(0);
3457  s_y = hull_lin_displ(1);
3458  s_z = hull_lin_displ(2);
3459  v_x = hull_quat_vector(0);
3460  v_y = hull_quat_vector(1);
3461  v_z = hull_quat_vector(2);
3462  s = hull_quat_scalar;
3463 
3464  Point<3> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
3465  comp_dom.boat_model.reference_hull_baricenter(1),
3466  comp_dom.boat_model.reference_hull_baricenter(2));
3467 
3468  Point<3> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
3469  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
3470  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
3471 
3472  Point<3> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
3473  Point<3> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
3474  Point<3> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
3475 
3476  Point<3> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
3477  Point<3> rigid_lin_displ(s_x,s_y,s_z);
3478  Point<3> target_point_pos(RotMatRow1*(ref_point_pos+(-1.0)*ref_baricenter_pos),
3479  RotMatRow2*(ref_point_pos+(-1.0)*ref_baricenter_pos),
3480  RotMatRow3*(ref_point_pos+(-1.0)*ref_baricenter_pos));
3481  target_point_pos += baricenter_pos;
3482  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
3483  //boat_mesh_point.Transform(reference_to_current_transformation);
3484  // the rigid motion map points is the difference between the reference point position and the
3485  // current (rigidly displaced) node position
3486  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0)-ref_point_pos(0);
3487  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1)-ref_point_pos(1);
3488  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2)-ref_point_pos(2);
3489 
3490  //working_map_points(3*i) = ref_point_pos(0).val()-comp_dom.ref_points[3*i](0)+comp_dom.rigid_motion_map_points(3*i);
3491  //working_map_points(3*i+1) = ref_point_pos(1).val()-comp_dom.ref_points[3*i](1)+comp_dom.rigid_motion_map_points(3*i+1);
3492  //working_map_points(3*i+2) = ref_point_pos(2).val()-comp_dom.ref_points[3*i](2)+comp_dom.rigid_motion_map_points(3*i+2);
3493 
3494 
3495  //if (fabs(t-0.2) <1e-5)
3496  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
3497  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
3498  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
3499  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
3500  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
3501  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
3502  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
3503  }
3504  }
3505 
3506  // }
3507  // INEFFICIENTE!!!!!!!!!!
3508 
3509 
3510 
3511  Vector<double> full_map_points(comp_dom.rigid_motion_map_points);
3512  full_map_points.add(nodes_positions);
3513  comp_dom.update_mapping(full_map_points);
3514  comp_dom.update_support_points();
3515 
3516 
3517  //we work on a local COPY of map_points
3518  working_map_points = comp_dom.map_points;
3519  nodes_pos_res = 0;
3520 
3521 
3522 
3523  // as for now x and y coordinates of nodes are not moved (no surface smoothing)
3524  // so on x and y coordinates (except for water nodes) we only need to put a one
3525  // on the matrix diagonal
3526  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3527  {
3528  if ( !(comp_dom.flags[i] & near_boat) &&
3529  (comp_dom.flags[i] & water) &&
3530  (comp_dom.flags[i] & edge) &&
3531  !(comp_dom.flags[i] & transom_on_water) &&
3532  (!constraints.is_constrained(i)))
3533  {
3534  working_map_points(3*i) = comp_dom.old_map_points(3*i);
3535  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1);
3536  if (comp_dom.flags[i] & near_inflow)
3537  {
3538  working_map_points(3*i+2) = comp_dom.old_map_points(3*i+2);
3539  }
3540  }
3541  else if ( !(comp_dom.flags[i] & near_water) &&
3542  (comp_dom.flags[i] & boat) &&
3543  (!constraints.is_constrained(i)))
3544  {
3545  working_map_points(3*i) = comp_dom.old_map_points(3*i);
3546  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1);
3547  working_map_points(3*i+2) = comp_dom.old_map_points(3*i+2);
3548  //cout<<"&& "<<3*i<<" "<<3*i+1<<" "<<3*i+2<<endl;
3549  }
3550  else if ( !(comp_dom.flags[i] & near_water) &&
3551  !(comp_dom.flags[i] & water) &&
3552  !(comp_dom.flags[i] & boat) &&
3553  (!constraints.is_constrained(i)))
3554  {
3555  working_map_points(3*i) = comp_dom.old_map_points(3*i);
3556  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1);
3557  working_map_points(3*i+2) = comp_dom.old_map_points(3*i+2);
3558  //cout<<"&& "<<3*i<<" "<<3*i+1<<" "<<3*i+2<<endl;
3559  }
3560  else if ((comp_dom.flags[i] & transom_on_water) )
3561  {
3562  working_map_points(3*i) = comp_dom.old_map_points(3*i);
3563  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1);
3564  working_map_points(3*i+2) = comp_dom.old_map_points(3*i+2);
3565  }
3566  }
3567 
3568  // blending factor is needed to avoid that right after restart
3569  // the free surface mesh smoothing causes infinite horizontal nodes velocity:
3570  // here we are at restart, so blending factor is ZERO
3571  double blend_factor = 0.0;
3572  if (restart_flag)
3573  {
3574  }
3575  else
3576  {
3577 
3578  if (t - last_remesh_time < 0.5*remeshing_period)
3579  blend_factor = sin(3.141592654*(t-last_remesh_time)/remeshing_period);
3580  else
3581  blend_factor = 1.0;
3582  //std::cout<<"t "<<t<<" last_remesh_time "<<last_remesh_time<<" remeshing_period/5 "<<remeshing_period/5<<std::endl;
3583  }
3584 
3585  std::cout<<"blend_factor = "<<blend_factor<<std::endl;
3586 
3587 
3588  //this takes care of the right water line nodes projection (without smoothing)
3589  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3590  {
3591  if ( (comp_dom.flags[i] & water) &&
3592  (comp_dom.flags[i] & near_boat) &&
3593  (comp_dom.flags[i] & right_side) &&
3594  !(comp_dom.flags[i] & transom_on_water) &&
3595  (comp_dom.moving_point_ids[3] != i) &&
3596  (comp_dom.moving_point_ids[4] != i) &&
3597  (comp_dom.moving_point_ids[5] != i) &&
3598  (comp_dom.moving_point_ids[6] != i) ) // to avoid the bow and stern node
3599  {
3600  //cout<<"**** "<<i<<endl;
3601  Point<3> proj_node;
3602  double iges_curvature;
3603  Point<3> direction(comp_dom.iges_normals[i](0),comp_dom.iges_normals[i](1),0.0);
3604  //cout<<3*i+1<<" "<<comp_dom.support_points[i]<<" ("<<comp_dom.iges_normals[i]<<")"<<endl;
3605  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
3606  direction(0) = 0.0;
3607  else
3608  direction(1) = 0.0;
3609  //if (fabs(comp_dom.old_iges_normals[i](0)) > 1e-3)
3610  //cout<<3*i<<" dir: ("<<direction<<") | n_i("<<comp_dom.old_iges_normals[i]<<")"<<endl;
3611  comp_dom.boat_model.boat_water_line_right->assigned_axis_projection_and_diff_forms(proj_node,
3612  comp_dom.iges_normals[i],
3613  comp_dom.iges_mean_curvatures[i],
3614  comp_dom.support_points[i],
3615  direction); // hor normal dir projection
3616  //comp_dom.boat_model.boat_water_line_right->axis_projection_and_diff_forms(proj_node,
3617  // comp_dom.iges_normals[i],
3618  // iges_curvature,
3619  // comp_dom.support_points[i]); // y axis projection
3620  //working_map_points(3*i) = comp_dom.old_map_points(3*i); // x of the node must not change
3621  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
3622  {
3623  working_map_points(3*i) = comp_dom.old_map_points(3*i); // x of the node must not change
3624  working_map_points(3*i+1) = proj_node(1) - comp_dom.ref_points[3*i](1);
3625  }
3626  else
3627  {
3628  working_map_points(3*i) = proj_node(0) - comp_dom.ref_points[3*i](0);
3629  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1); // y of the node must not change
3630  }
3631  working_map_points(3*i+2) = proj_node(2) - comp_dom.ref_points[3*i](2);
3632  //cout<<3*i+1<<" "<<working_map_points(3*i+1)-comp_dom.map_points(3*i+1)<<" ("<<iges_normal<<")"<<endl;
3633  //if (fabs(comp_dom.old_iges_normals[i](0))>sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
3634  // {
3635  // cout<<i<<" "<<proj_node<<" ("<<comp_dom.support_points[i]<<")"<<endl;
3636  // cout<<direction<<" | "<<working_map_points(3*i)<<" "<<working_map_points(3*i+1)<<endl;
3637  // }
3638  }
3639  }
3640 
3641  //this takes care of the left water line nodes projection (without smoothing)
3642  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3643  {
3644  if ( (comp_dom.flags[i] & water) &&
3645  (comp_dom.flags[i] & near_boat) &&
3646  (comp_dom.flags[i] & left_side) &&
3647  !(comp_dom.flags[i] & transom_on_water) &&
3648  (comp_dom.moving_point_ids[3] != i) &&
3649  (comp_dom.moving_point_ids[4] != i) &&
3650  (comp_dom.moving_point_ids[5] != i) &&
3651  (comp_dom.moving_point_ids[6] != i) ) // to avoid the bow and stern node
3652  {
3653  //cout<<"**** "<<i<<endl;
3654  Point<3> proj_node;
3655  double iges_curvature;
3656  Point<3> direction(comp_dom.iges_normals[i](0),comp_dom.iges_normals[i](1),0.0);
3657  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
3658  direction(0) = 0.0;
3659  else
3660  direction(1) = 0.0;
3661  //if (fabs(comp_dom.iges_normals[i](0))<0.001)
3662  // cout<<3*i<<" dir: ("<<direction<<")"<<endl;
3663  comp_dom.boat_model.boat_water_line_left->assigned_axis_projection_and_diff_forms(proj_node,
3664  comp_dom.iges_normals[i],
3665  comp_dom.iges_mean_curvatures[i],
3666  comp_dom.support_points[i],
3667  direction); // hor normal dir projection
3668  //comp_dom.boat_model.boat_water_line_left->axis_projection_and_diff_forms(proj_node,
3669  // comp_dom.iges_normals[i],
3670  // iges_curvature,
3671  // comp_dom.support_points[i]); // y axis projection
3672  //working_map_points(3*i) = comp_dom.old_map_points(3*i); // x of the node must not change
3673  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
3674  {
3675  working_map_points(3*i) = comp_dom.old_map_points(3*i); // x of the node must not change
3676  working_map_points(3*i+1) = proj_node(1) - comp_dom.ref_points[3*i](1);
3677  }
3678  else
3679  {
3680  working_map_points(3*i) = proj_node(0) - comp_dom.ref_points[3*i](0);
3681  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1); // y of the node must not change
3682  }
3683  working_map_points(3*i+2) = proj_node(2) - comp_dom.ref_points[3*i](2);
3684  //cout<<i<<" "<<temp_src(3*i+1)<<" ("<<comp_dom.iges_normals[i]<<")"<<endl;
3685  //if (fabs(comp_dom.old_iges_normals[i](0))>sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
3686  // {
3687  // cout<<i<<" "<<proj_node<<" ("<<comp_dom.support_points[i]<<")"<<endl;
3688  // cout<<direction<<" | "<<working_map_points(3*i)<<" "<<working_map_points(3*i+1)<<endl;
3689  // }
3690  }
3691  }
3692 
3693  //this takes care of the bow and stern nodes
3694  if (!comp_dom.no_boat)
3695  for (unsigned int k=3; k<7; ++k)
3696  {
3697  unsigned int i = comp_dom.moving_point_ids[k];
3698  {
3699  Point <3> dP0 = comp_dom.support_points[i];
3700  Point <3> dP;
3701  //this is the horizontal plane
3702  Handle(Geom_Plane) horPlane = new Geom_Plane(0.,0.,1.,-dP0(2));
3703  Handle(Geom_Curve) curve;
3704  TopLoc_Location L = comp_dom.boat_model.current_loc;
3705  TopLoc_Location L_inv = L.Inverted();
3706  horPlane->Transform(L_inv.Transformation());
3707  if (comp_dom.boat_model.is_transom)
3708  {
3709  if (k==3 || k==4)
3710  curve = comp_dom.boat_model.equiv_keel_bspline;
3711  else if (k == 6)
3712  curve = comp_dom.boat_model.left_transom_bspline;
3713  else
3714  curve = comp_dom.boat_model.right_transom_bspline;
3715  }
3716  else
3717  {
3718  curve = comp_dom.boat_model.equiv_keel_bspline;
3719  }
3720 
3721  TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve);
3722  edge.Location(L);
3723  BRepAdaptor_Curve AC(edge);
3724  gp_Pnt P;
3725  gp_Vec V1;
3726  GeomAPI_IntCS Intersector(curve, horPlane);
3727  int npoints = Intersector.NbPoints();
3728 
3729  AssertThrow((npoints != 0), ExcMessage("Keel or transom curve is not intersecting with horizontal plane!"));
3730  double minDistance=1e7;
3731  double t,u,v;
3732  for (int j=0; j<npoints; ++j)
3733  {
3734  gp_Pnt int_point = Intersector.Point(j+1);
3735  int_point.Transform(L.Transformation());
3736  Point<3> inters = Pnt(int_point);
3737  Intersector.Parameters(j+1,u,v,t);
3738  if (dP0.distance(inters) < minDistance)
3739  {
3740  minDistance = dP0.distance(inters);
3741  dP = inters;
3742  AC.D1(t,P,V1);
3743  }
3744  }
3745  //cout<<"Check plane-curve intersection:"<<endl;
3746  //cout<<"Origin: "<<dP0<<" Proj: "<<dP<<" dist: "<<minDistance<<endl;
3747  //cout<<Pnt(P)<<endl;
3748  /*
3749  // here temporarily for kcs hull tests
3750  if (minDistance > 0.5*comp_dom.boat_model.boatWetLength)
3751  {
3752  Standard_Real First = curve->FirstParameter();
3753  Standard_Real Last = curve->LastParameter();
3754  gp_Pnt PIn(0.0,0.0,0.0);
3755  gp_Pnt PFin(0.0,0.0,0.0);
3756  gp_Vec VIn;
3757  gp_Vec VFin;
3758  curve->D1(First,PIn,VIn);
3759  curve->D1(Last,PFin,VFin);
3760  cout<<"New part one: "<<Pnt(PIn)<<" | "<<Pnt(PFin)<<endl;
3761  if (dP0.distance(Pnt(PIn)) < dP0.distance(Pnt(PFin)))
3762  {
3763  double delta_z = dP0(2) - PIn.Z();
3764  dP = Point<3>(PIn.X()+delta_z*VIn.X()/VIn.Z(),PIn.Y()+delta_z*VIn.Y()/VIn.Z(),dP0(2));
3765  V1 = VIn;
3766  }
3767  else
3768  {
3769  double delta_z = dP0(2) - PFin.Z();
3770  dP = Point<3>(PFin.X()+delta_z*VFin.X()/VFin.Z(),PIn.Y()+delta_z*VFin.Y()/VFin.Z(),dP0(2));
3771  V1 = VFin;
3772  }
3773  cout<<"New part two: "<<dP<<" | "<<V1.X()<<" "<<V1.Y()<<" "<<V1.Z()<<" | "<<dP0<<endl;
3774  }
3775  */
3776  //cout<<k<<"("<<i<<") ---> ("<<dP0<<") vs ("<<dP<<")"<<endl;
3777  working_map_points(3*i) = dP(0)-comp_dom.ref_points[3*i](0);
3778  working_map_points(3*i+1) = dP(1)-comp_dom.ref_points[3*i](1);
3779  working_map_points(3*i+2) = dP(2)-comp_dom.ref_points[3*i](2);
3780  comp_dom.edges_tangents[3*i] = V1.X();
3781  comp_dom.edges_tangents[3*i+1] = V1.Y();
3782  comp_dom.edges_tangents[3*i+2] = V1.Z();
3783  //cout<<i<<" (point) "<<comp_dom.support_points[i]<<" vs "<<dP<<endl;
3784  //cout<<i<<" (edges_tangents) "<<comp_dom.edges_tangents(3*i)<<","<<comp_dom.edges_tangents(3*i+1)<<","<<comp_dom.edges_tangents(3*i+2)<<endl;
3785  }
3786  }
3787 
3788  // this cycle hooks the boat and far field double nodes
3789  // to their water twins that have been moved
3790  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
3791  {
3792  if ( (comp_dom.vector_flags[i] & water) &&
3793  (comp_dom.vector_flags[i] & edge) )
3794  {
3795  std::set<unsigned int> duplicates = comp_dom.vector_double_nodes_set[i];
3796  duplicates.erase(i);
3797  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
3798  {
3799  //cout<<*pos<<"("<<i<<") "<<comp_dom.map_points(i)<<" vs "<<comp_dom.map_points(*pos)<<" diff "<<comp_dom.map_points(i)-comp_dom.map_points(*pos)<<endl;
3800  working_map_points(*pos) = working_map_points(i);
3801  }
3802  }
3803  }
3804 
3805  //we enforce constraint on the new geometry assigned by the DAE solver
3806  vector_constraints.distribute(working_map_points);
3807 
3808  // mesh is ready, now we copy on map points the new nodes displacements
3809  comp_dom.map_points = working_map_points;
3810  // and update the support points
3811  comp_dom.update_support_points();
3812  // and compute the node normals (needed by bem b.c.)
3813  comp_dom.compute_normals_at_nodes(comp_dom.map_points);
3814 
3815  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
3816  {
3817  y(i) = comp_dom.map_points(i)-comp_dom.rigid_motion_map_points(i);
3818  }
3819 
3821 
3823 // here we prepare the initial_map_points to be used in case of transom stern
3824  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom)
3825  {
3826  comp_dom.update_support_points();
3827 
3828  double transom_draft = fabs(comp_dom.boat_model.CurrentPointCenterTransom(2));
3829  double transom_aspect_ratio = (fabs(comp_dom.boat_model.CurrentPointLeftTransom(1))+
3830  fabs(comp_dom.boat_model.CurrentPointRightTransom(1)))/transom_draft;
3831 
3832  wind.set_time(100000000.0);
3833  Vector<double> instantWindValueTinf(dim);
3834  Point<dim> zero(0,0,0);
3835  wind.vector_value(zero,instantWindValueTinf);
3836  Point<dim> VinfTinf;
3837  for (unsigned int i = 0; i < dim; i++)
3838  VinfTinf(i) = instantWindValueTinf(i);
3839  wind.set_time(initial_time);
3840 
3841  double FrT = sqrt(VinfTinf*VinfTinf)/sqrt(9.81*transom_draft);
3842  double ReT = sqrt(9.81*pow(transom_draft,3.0))/1.307e-6;
3843  double eta_dry = fmin(0.05*pow(FrT,2.834)*pow(transom_aspect_ratio,0.1352)*pow(ReT,0.01338),1.0);
3844  double lh = 0.0;
3845  //if (eta_dry < 1.0)
3846  lh = 5.0;
3847  //lh = 0.1135*pow(FrT,3.025)*pow(transom_aspect_ratio,0.4603)*pow(ReT,-0.1514);
3848  //lh = 0.3265*pow(FrT,3.0) - 1.7216*pow(FrT,2.0) + 2.7593*FrT;
3849  cout<<FrT<<" "<<transom_aspect_ratio<<" "<<ReT<<endl;
3850  cout<<"****eta_dry: "<<eta_dry<<endl;
3851 
3852  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3853  {
3854  comp_dom.initial_map_points(3*i+2) = 0.0;
3855  }
3856 
3857  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3858  {
3859  if ( (comp_dom.support_points[i](1) < comp_dom.boat_model.CurrentPointRightTransom(1)) &&
3860  (comp_dom.support_points[i](1) >= 0.0) &&
3861  (comp_dom.support_points[i](0) > comp_dom.boat_model.CurrentPointCenterTransom(0)-fabs(comp_dom.boat_model.CurrentPointCenterTransom(2)) ) &&
3862  (comp_dom.support_points[3*i](0) < comp_dom.boat_model.CurrentPointCenterTransom(0)+lh*fabs(comp_dom.boat_model.CurrentPointCenterTransom(2)) ) &&
3863  (comp_dom.support_points[i](2) > 2.0*comp_dom.boat_model.CurrentPointCenterTransom(2)) )
3864  {
3865  Point <3> dP0 = comp_dom.support_points[i];
3866  Point <3> dP;
3867  //this is the vertical plane
3868  Handle(Geom_Plane) vertPlane = new Geom_Plane(0.,1.,0.,-dP0(1));
3869  vertPlane->Transform(comp_dom.boat_model.current_loc.Inverted());
3870  Handle(Geom_Curve) curve = comp_dom.boat_model.right_transom_bspline;
3871 
3872  GeomAPI_IntCS Intersector(curve, vertPlane);
3873  int npoints = Intersector.NbPoints();
3874  AssertThrow((npoints != 0), ExcMessage("Transom curve is not intersecting with vertical plane!"));
3875  //cout<<"Number of intersections: "<<npoints<<endl;
3876  double minDistance=1e7;
3877  for (int j=0; j<npoints; ++j)
3878  {
3879  gp_Pnt int_point = Intersector.Point(j+1);
3880  int_point.Transform(comp_dom.boat_model.current_loc);
3881  Point<3> inters = Pnt(int_point);
3882 
3883  if (dP0.distance(inters) < minDistance)
3884  {
3885  minDistance = dP0.distance(inters);
3886  dP = inters;
3887  }
3888  }
3889 
3890  if ( (comp_dom.support_points[i](0) > dP(0)+comp_dom.min_diameter/20.0) &&
3891  (comp_dom.support_points[i](0) < dP(0)+lh*fabs(dP(2))+comp_dom.min_diameter/20.0) )
3892  {
3893  double mean_curvature;
3894  Point<3> normal;
3895  Point<3> projection;
3896  comp_dom.boat_model.boat_surface_right->normal_projection_and_diff_forms(projection,
3897  normal,
3898  mean_curvature,
3899  dP);
3900  AssertThrow((dP.distance(projection) < 1e-4*comp_dom.boat_model.boatWetLength), ExcMessage("Normal projection for surface normal evaluation went wrong!"));
3901  double transom_slope = -normal(0)/normal(2);
3902  double a = -transom_slope/(lh*fabs(dP(2))) - 1/dP(2)/lh/lh;
3903  double x = comp_dom.support_points[i](0)-dP(0);
3904  comp_dom.initial_map_points(3*i+2) = a*x*x + transom_slope*x + dP(2);
3905  }
3906  }
3907  else if ( (comp_dom.support_points[i](1) > comp_dom.boat_model.CurrentPointLeftTransom(1)) &&
3908  (comp_dom.support_points[i](1) < 0.0) &&
3909  (comp_dom.support_points[i](0) > comp_dom.boat_model.CurrentPointCenterTransom(0)-fabs(comp_dom.boat_model.CurrentPointCenterTransom(2))) &&
3910  (comp_dom.support_points[i](0) < comp_dom.boat_model.CurrentPointCenterTransom(0)+lh*fabs(comp_dom.boat_model.CurrentPointCenterTransom(2))) &&
3911  (comp_dom.support_points[i](2) > 2.0*comp_dom.boat_model.CurrentPointCenterTransom(2)) )
3912  {
3913  Point <3> dP0 = comp_dom.support_points[i];
3914  Point <3> dP;
3915  //this is the vertical plane
3916  Handle(Geom_Plane) vertPlane = new Geom_Plane(0.,1.,0.,-dP0(1));
3917  vertPlane->Transform(comp_dom.boat_model.current_loc.Inverted());
3918  Handle(Geom_Curve) curve = comp_dom.boat_model.left_transom_bspline;
3919 
3920  GeomAPI_IntCS Intersector(curve, vertPlane);
3921  int npoints = Intersector.NbPoints();
3922  AssertThrow((npoints != 0), ExcMessage("Transom curve is not intersecting with vertical plane!"));
3923  //cout<<"Number of intersections: "<<npoints<<endl;
3924  double minDistance=1e7;
3925  for (int j=0; j<npoints; ++j)
3926  {
3927  gp_Pnt int_point = Intersector.Point(j+1);
3928  int_point.Transform(comp_dom.boat_model.current_loc);
3929  Point<3> inters = Pnt(int_point);
3930 
3931  if (dP0.distance(inters) < minDistance)
3932  {
3933  minDistance = dP0.distance(inters);
3934  dP = inters;
3935  }
3936  }
3937  if ( (comp_dom.support_points[i](0) > dP(0)+comp_dom.min_diameter/20.0) &&
3938  (comp_dom.support_points[i](0) < dP(0)+lh*fabs(dP(2))+comp_dom.min_diameter/20.0) )
3939  {
3940  double mean_curvature;
3941  Point<3> normal;
3942  Point<3> projection;
3943  comp_dom.boat_model.boat_surface_left->normal_projection_and_diff_forms(projection,
3944  normal,
3945  mean_curvature,
3946  dP);
3947  AssertThrow((dP.distance(projection) < 1e-4*comp_dom.boat_model.boatWetLength), ExcMessage("Normal projection for surface normal evaluation went wrong!"));
3948  double transom_slope = -normal(0)/normal(2);
3949  double a = -transom_slope/(lh*fabs(dP(2))) - 1/dP(2)/lh/lh;
3950  double x = comp_dom.support_points[i](0)-dP(0);
3951  comp_dom.initial_map_points(3*i+2) = a*x*x + transom_slope*x + dP(2);
3952  }
3953  }
3954  }
3955  comp_dom.vector_constraints.distribute(comp_dom.initial_map_points);
3956  }
3957 
3958 
3959 
3960 
3961 
3962 
3964 
3965 
3966 
3967 
3969  // here we take care of the free surface boundary condition (differential)
3970  // part of the variables, and the boat neumann condition variables
3972 
3973 
3974 // we first need to fix the nodes horiziontal velocities on the boat (they must be parallel to the boat
3975 // and respect the differential equation)
3976 
3977  Vector<double> complete_potential_gradients(comp_dom.vector_dh.n_dofs());
3978  compute_potential_gradients(complete_potential_gradients,phi,dphi_dn);
3979 
3980  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
3981  {
3982  if ( (comp_dom.flags[i] & water) &&
3983  (comp_dom.flags[i] & near_boat) &&
3984  !(comp_dom.flags[i] & transom_on_water) &&
3985  (comp_dom.moving_point_ids[3] != i) &&
3986  (comp_dom.moving_point_ids[4] != i) &&
3987  (comp_dom.moving_point_ids[5] != i) &&
3988  (comp_dom.moving_point_ids[6] != i) )
3989  {
3990  Point<3> phi_gradient(complete_potential_gradients(3*i),complete_potential_gradients(3*i+1),complete_potential_gradients(3*i+2));
3991  Point<3> eta_gradient(-comp_dom.node_normals[i](0)/comp_dom.node_normals[i](2),-comp_dom.node_normals[i](1)/comp_dom.node_normals[i](2),0.0);
3992  double eta_dot = (phi_gradient(2)-eta_gradient*(Vinf+phi_gradient))/(1-eta_gradient(1)*comp_dom.iges_normals[i](2)/comp_dom.iges_normals[i](1));
3993  //yp(3*i+1) = -eta_dot*comp_dom.iges_normals[i](2)/comp_dom.iges_normals[i](1);
3994  std::set <unsigned int> duplicates = comp_dom.vector_double_nodes_set[3*i+1];
3995  for (std::set <unsigned int>::iterator pos = duplicates.begin(); pos != duplicates.end(); ++pos)
3996  {
3997  yp(*pos) = -eta_dot*comp_dom.iges_normals[i](2)/comp_dom.iges_normals[i](1);
3998  }
3999  //cout<<"WL "<<i<<" "<<eta_dot<<" "<<yp(3*i+1)<<" ("<<comp_dom.iges_normals[i]<<")"<<endl;
4000  }
4001  }
4002 
4003  //this takes care of the bow and stern nodes
4004  if (!comp_dom.no_boat)
4005  for (unsigned int k=3; k<7; ++k)
4006  {
4007  unsigned int i = comp_dom.moving_point_ids[k];
4008  Point<3> phi_gradient(complete_potential_gradients(3*i),complete_potential_gradients(3*i+1),complete_potential_gradients(3*i+2));
4009  Point<3> eta_gradient(-comp_dom.node_normals[i](0)/comp_dom.node_normals[i](2),-comp_dom.node_normals[i](1)/comp_dom.node_normals[i](2),0.0);
4010  Point<3> t(comp_dom.edges_tangents[3*i],comp_dom.edges_tangents[3*i+1],comp_dom.edges_tangents[3*i+2]);
4011  double eta_dot = (phi_gradient(2)-eta_gradient*(Vinf+phi_gradient))/(1.0-t(0)/t(2)-t(1)/t(2));
4012  std::set <unsigned int> duplicates = comp_dom.vector_double_nodes_set[3*i];
4013  for (std::set <unsigned int>::iterator pos = duplicates.begin(); pos != duplicates.end(); ++pos)
4014  {
4015  yp(*pos) = eta_dot*t(0)/t(2);
4016  }
4017  duplicates = comp_dom.vector_double_nodes_set[3*i+1];
4018  for (std::set <unsigned int>::iterator pos = duplicates.begin(); pos != duplicates.end(); ++pos)
4019  {
4020  yp(*pos) = eta_dot*t(1)/t(2);
4021  }
4022 
4023  //cout<<"KT "<<i<<" "<<eta_dot<<" "<<yp(3*i)<<" "<<yp(3*i+1)<<" (";
4024  //cout<<comp_dom.edges_tangents(3*i)<<" "<<comp_dom.edges_tangents(3*i+1)<<" "<<comp_dom.edges_tangents(3*i+2)<<")"<<endl;
4025  }
4026 
4027 
4028 
4029 // building reference cell
4030  Triangulation<2,3> ref_triangulation;
4031 
4032  std::vector<Point<3> > ref_vertices;
4033  std::vector<CellData<2> > ref_cells;
4034  SubCellData ref_subcelldata;
4035 
4036  ref_vertices.resize(4);
4037  ref_vertices[0](0)=-1.0;
4038  ref_vertices[0](1)=-1.0;
4039  ref_vertices[0](2)=0.0;
4040  ref_vertices[1](0)= 1.0;
4041  ref_vertices[1](1)=-1.0;
4042  ref_vertices[1](2)=0.0;
4043  ref_vertices[2](0)=-1.0;
4044  ref_vertices[2](1)= 1.0;
4045  ref_vertices[2](2)=0.0;
4046  ref_vertices[3](0)= 1.0;
4047  ref_vertices[3](1)= 1.0;
4048  ref_vertices[3](2)=0.0;
4049 
4050  ref_cells.resize(1);
4051 
4052  ref_cells[0].vertices[0]=0;
4053  ref_cells[0].vertices[1]=1;
4054  ref_cells[0].vertices[2]=3;
4055  ref_cells[0].vertices[3]=2;
4056  ref_cells[0].material_id = 1;
4057 
4058  GridTools::delete_unused_vertices (ref_vertices, ref_cells, ref_subcelldata);
4060 
4061  ref_triangulation.create_triangulation_compatibility(ref_vertices, ref_cells, ref_subcelldata );
4062 
4063  FE_Q<2,3> fe(1);
4064  DoFHandler<2,3> ref_dh(ref_triangulation);
4065  ref_dh.distribute_dofs(fe);
4066 
4067  FEValues<2,3> ref_fe_v(StaticMappingQ1<2,3>::mapping, fe, *comp_dom.quadrature,
4068  update_values | update_gradients |
4069  update_cell_normal_vectors |
4070  update_quadrature_points |
4071  update_JxW_values);
4072 
4073  const unsigned int n_q_points = ref_fe_v.n_quadrature_points;
4074  const unsigned int dofs_per_cell = fe.dofs_per_cell;
4075 
4076  cell_it ref_cell = ref_dh.begin_active();
4077  ref_fe_v.reinit(ref_cell);
4078 
4080 
4081 // test: let's try assemble actual mass matrix
4082 
4083  DphiDt_sys_matrix = 0;
4084  DphiDt_sys_solution = 0;
4085  DphiDt_sys_solution_2 = 0;
4086  DphiDt_sys_solution_3 = 0;
4087  DphiDt_sys_rhs = 0;
4088  DphiDt_sys_rhs_2 = 0;
4089  DphiDt_sys_rhs_3 = 0;
4090 
4091 //let's build the residual on the free surface cells (differential components)
4092  std::vector<double> eta_res(comp_dom.dh.n_dofs(),0.0);
4093  std::vector<double> phi_res(comp_dom.dh.n_dofs(),0.0);
4094  std::vector<double> dphi_dn_res(comp_dom.dh.n_dofs(),0.0);
4095  std::vector<double> x_smoothing_res(comp_dom.dh.n_dofs(),0.0);
4096  std::vector<double> y_smoothing_res(comp_dom.dh.n_dofs(),0.0);
4097 
4098 
4099  double g = 9.81;
4100 
4101  FullMatrix<double> local_DphiDt_matrix (dofs_per_cell, dofs_per_cell);
4102  FullMatrix<double> local_DphiDt_matrix_2 (dofs_per_cell, dofs_per_cell);
4103  Vector<double> local_DphiDt_rhs (dofs_per_cell);
4104  Vector<double> local_DphiDt_rhs_2 (dofs_per_cell);
4105  Vector<double> local_DphiDt_rhs_3 (dofs_per_cell);
4106 
4107  cell_it
4108  cell = comp_dom.dh.begin_active(),
4109  endc = comp_dom.dh.end();
4110 
4111  std::vector<fad_double> coors(3*dofs_per_cell,0.0);
4112  std::vector<fad_double> phis(dofs_per_cell,0.0);
4113  std::vector<fad_double> dphi_dns(dofs_per_cell,0.0);
4114  std::vector<fad_double> coors_dot(3*dofs_per_cell,0.0);
4115  std::vector<fad_double> phis_dot(dofs_per_cell,0.0);
4116  std::vector<fad_double> dphi_dns_dot(dofs_per_cell,0.0);
4117  std::vector<fad_double> x_displs(dofs_per_cell,0.0);
4118  std::vector<fad_double> y_displs(dofs_per_cell,0.0);
4119 
4120  std::vector<fad_double> loc_eta_res(dofs_per_cell,0.0);
4121  std::vector<fad_double> loc_phi_res(dofs_per_cell,0.0);
4122  std::vector<fad_double> loc_dphi_dn_res(dofs_per_cell,0.0);
4123  std::vector<fad_double> loc_x_smooth_res(dofs_per_cell,0.0);
4124  std::vector<fad_double> loc_y_smooth_res(dofs_per_cell,0.0);
4125 
4126  std::vector< std::vector<fad_double> > loc_stiffness_matrix(dofs_per_cell,std::vector<fad_double>(dofs_per_cell));
4127  std::vector< std::vector<fad_double> > loc_mass_matrix(dofs_per_cell,std::vector<fad_double>(dofs_per_cell));
4128  std::vector< std::vector<fad_double> > loc_supg_mass_matrix(dofs_per_cell,std::vector<fad_double>(dofs_per_cell));
4129 
4130 
4131  std::vector<unsigned int> local_dof_indices(dofs_per_cell);
4132 
4133 
4134  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4135  // cout<<i<<" VelsAgain: "<<" "<<nodes_velocities(3*i)<<" "<<nodes_velocities(3*i+1)<<" "<<nodes_velocities(3*i+2)<<endl;
4136 
4137  for (; cell!=endc; ++cell)
4138  {
4139  //if (cell->material_id() == comp_dom.free_sur_ID1 ||
4140  // cell->material_id() == comp_dom.free_sur_ID2 ||
4141  // cell->material_id() == comp_dom.free_sur_ID3 ||
4142  // cell->material_id() == comp_dom.wall_sur_ID1 ||
4143  // cell->material_id() == comp_dom.wall_sur_ID2 ||
4144  // cell->material_id() == comp_dom.wall_sur_ID3 )
4145  {
4146  //std::cout<<std::endl;
4147  //std::cout<<"Cell: "<<cell<<" Center: "<<cell->center()<<" --- "<<dofs_per_cell<<std::endl;
4148 
4149  local_DphiDt_matrix = 0;
4150  local_DphiDt_matrix_2 = 0;
4151  local_DphiDt_rhs = 0;
4152  local_DphiDt_rhs_2 = 0;
4153  local_DphiDt_rhs_3 = 0;
4154 
4155  cell->get_dof_indices(local_dof_indices);
4156  for (unsigned int i=0; i<dofs_per_cell; ++i)
4157  {
4158  loc_eta_res[i] = 0;
4159  loc_phi_res[i] = 0;
4160  loc_dphi_dn_res[i] = 0;
4161  loc_x_smooth_res[i] = 0;
4162  loc_y_smooth_res[i] = 0;
4163  for (unsigned int j=0; j<dofs_per_cell; ++j)
4164  {
4165  loc_mass_matrix[i][j] = 0;
4166  loc_supg_mass_matrix[i][j] = 0;
4167  loc_stiffness_matrix[i][j] = 0;
4168  }
4169  //cout<<local_dof_indices[i]<<" ";
4170  }
4171 
4172  for (unsigned int i=0; i<dofs_per_cell; ++i)
4173  {
4174  for (unsigned int j=0; j<3; ++j)
4175  {
4176  //cout<<3*local_dof_indices[i]+j<<endl;
4177  coors[3*i+j] = comp_dom.support_points[local_dof_indices[i]](j);
4178  coors[3*i+j].diff(3*i+j,10*dofs_per_cell);
4179  coors_dot[3*i+j] = nodes_velocities(3*local_dof_indices[i]+j);
4180  coors_dot[3*i+j].diff(3*i+j+5*dofs_per_cell,10*dofs_per_cell);
4181  //std::cout<<i<<"-------> "<<coors_dot[3*i+j].val()<<" vs "<<nodes_velocities(3*local_dof_indices[i]+j)<<endl;
4182  }
4183  //std::cout<<i<<"-------> "<<coors_dot[3*i].val()<<" "<<coors_dot[3*i+1].val()<<" "<<coors_dot[3*i+2].val()<<" "<<endl;
4184  }
4185  for (unsigned int i=0; i<dofs_per_cell; ++i)
4186  {
4187  phis[i] = phi(local_dof_indices[i]);
4188  phis[i].diff(i+3*dofs_per_cell,10*dofs_per_cell);
4189  phis_dot[i] = phi_time_derivs(local_dof_indices[i]);
4190  phis_dot[i].diff(i+8*dofs_per_cell,10*dofs_per_cell);
4191  dphi_dns[i] = dphi_dn(local_dof_indices[i]);
4192  dphi_dns[i].diff(i+4*dofs_per_cell,10*dofs_per_cell);
4193  dphi_dns_dot[i] = dphi_dn_time_derivs(local_dof_indices[i]);
4194  dphi_dns_dot[i].diff(i+9*dofs_per_cell,10*dofs_per_cell);
4195  //std::cout<<i<<"--> "<<local_dof_indices[i]<<"--------->"<<bem_phi(local_dof_indices[i])<<" "<<bem_dphi_dn(local_dof_indices[i])<<endl;
4196  }
4197 
4198  // computation of displacements
4199  for (unsigned int i=0; i<dofs_per_cell; ++i)
4200  {
4201  x_displs[i] = coors[3*i] - comp_dom.ref_points[3*local_dof_indices[i]](0);
4202  y_displs[i] = coors[3*i+1] - comp_dom.ref_points[3*local_dof_indices[i]](1);
4203  //cout<<i<<" "<<x_displs[i].val()<<" "<<y_displs[i].val()<<endl;
4204  //cout<<i<<" "<<coors[3*i].val()<<" "<<comp_dom.ref_points[3*local_dof_indices[i]](0)<<" "<<comp_dom.support_points[local_dof_indices[i]](0)<<endl;
4205  //cout<<i<<" "<<coors[3*i+1].val()<<" "<<comp_dom.ref_points[3*local_dof_indices[i]](1)<<" "<<comp_dom.support_points[local_dof_indices[i]](1)<<endl;
4206  }
4207  // computation of cell center
4208  Point<3,fad_double> center(0.0,0.0,0.0);
4209  for (unsigned int i=0; i<dofs_per_cell; ++i)
4210  {
4211  center += (Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]))/fad_double(dofs_per_cell);
4212  }
4213 
4214  std::vector<fad_double> eta_dot_rhs_fun(n_q_points);
4215  std::vector<fad_double> phi_dot_rhs_fun(n_q_points);
4216  std::vector< Point<3,fad_double> > fluid_vel(n_q_points);
4217  std::vector<fad_double> q_JxW(n_q_points);
4218 
4219 
4220  for (unsigned int q=0; q<n_q_points; ++q)
4221  {
4222  Point<3,fad_double> q_point(0.0,0.0,0.0);
4223  Point<3,fad_double> u_deriv_pos(0.0,0.0,0.0);
4224  Point<3,fad_double> v_deriv_pos(0.0,0.0,0.0);
4225  fad_double u_deriv_phi = 0;
4226  fad_double v_deriv_phi = 0;
4227  fad_double q_dphi_dn = 0;
4228  fad_double q_x_dot = 0;
4229  fad_double q_y_dot = 0;
4230  fad_double q_z_dot = 0;
4231  fad_double q_eta = 0;
4232  for (unsigned int i=0; i<dofs_per_cell; ++i)
4233  {
4234  unsigned int index = local_dof_indices[i];
4235  q_point += fad_double(ref_fe_v.shape_value(i,q))*T(Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]));
4236  u_deriv_pos += fad_double(ref_fe_v.shape_grad(i,q)[0])*Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]);
4237  v_deriv_pos += fad_double(ref_fe_v.shape_grad(i,q)[1])*Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]);
4238  u_deriv_phi += fad_double(ref_fe_v.shape_grad(i,q)[0])*phis[i];
4239  v_deriv_phi += fad_double(ref_fe_v.shape_grad(i,q)[1])*phis[i];
4240  q_dphi_dn += fad_double(ref_fe_v.shape_value(i,q))*dphi_dns[i];
4241  q_x_dot += fad_double(ref_fe_v.shape_value(i,q))*coors_dot[3*i];
4242  q_y_dot += fad_double(ref_fe_v.shape_value(i,q))*coors_dot[3*i+1];
4243  q_z_dot += fad_double(ref_fe_v.shape_value(i,q))*coors_dot[3*i+2];
4244  q_eta += fad_double(ref_fe_v.shape_value(i,q))*coors[3*i+2];
4245  //std::cout<<i<<"-------> "<<u_deriv_pos<<" "<<v_deriv_pos<<" "<<u_deriv_phi<<" "<<v_deriv_phi<<endl;
4246  //std::cout<<i<<"-------> "<<coors[3*i].val()<<" "<<coors[3*i+1]<<" "<<coors[3*i+2]<<" "<<endl;
4247  }
4248  Point<3,fad_double> q_normal(u_deriv_pos(1)*v_deriv_pos(2)-u_deriv_pos(2)*v_deriv_pos(1),
4249  u_deriv_pos(2)*v_deriv_pos(0)-u_deriv_pos(0)*v_deriv_pos(2),
4250  u_deriv_pos(0)*v_deriv_pos(1)-u_deriv_pos(1)*v_deriv_pos(0));
4251  //std::cout<<"q_normal="<<q_normal<<std::endl;
4252  //std::cout<<"q_y_dot="<<q_y_dot<<std::endl;
4253  fad_double q_jac_det = q_normal.norm();
4254  q_normal/=q_jac_det;
4255  fad_double a = 1.0/((u_deriv_pos*u_deriv_pos)*(v_deriv_pos*v_deriv_pos)-(u_deriv_pos*v_deriv_pos)*(u_deriv_pos*v_deriv_pos));
4256  fad_double d11 = a*(u_deriv_pos(0)*v_deriv_pos*v_deriv_pos-v_deriv_pos(0)*u_deriv_pos*v_deriv_pos);
4257  fad_double d21 = a*(u_deriv_pos(1)*v_deriv_pos*v_deriv_pos-v_deriv_pos(1)*u_deriv_pos*v_deriv_pos);
4258  fad_double d31 = a*(u_deriv_pos(2)*v_deriv_pos*v_deriv_pos-v_deriv_pos(2)*u_deriv_pos*v_deriv_pos);
4259  fad_double d12 = a*(v_deriv_pos(0)*u_deriv_pos*u_deriv_pos-u_deriv_pos(0)*u_deriv_pos*v_deriv_pos);
4260  fad_double d22 = a*(v_deriv_pos(1)*u_deriv_pos*u_deriv_pos-u_deriv_pos(1)*u_deriv_pos*v_deriv_pos);
4261  fad_double d32 = a*(v_deriv_pos(2)*u_deriv_pos*u_deriv_pos-u_deriv_pos(2)*u_deriv_pos*v_deriv_pos);
4262  Point<3,fad_double> phi_surf_grad(d11*u_deriv_phi+d12*v_deriv_phi,
4263  d21*u_deriv_phi+d22*v_deriv_phi,
4264  d31*u_deriv_phi+d32*v_deriv_phi);
4265  Point<3,fad_double> phi_surf_grad_corrected(phi_surf_grad(0) - phi_surf_grad(2)*q_normal(0)/q_normal(2),
4266  phi_surf_grad(1) - phi_surf_grad(2)*q_normal(1)/q_normal(2),
4267  0.0);
4268  Point<3,fad_double> phi_grad = phi_surf_grad + q_normal*q_dphi_dn;
4269 
4270  //std::cout<<"q_point="<<q_point<<" q_normal="<<q_normal<<" q_dphi_dn="<<q_dphi_dn<<std::endl;
4271  //cout<<q<<" phi_grad("<<phi_grad<<") phi_surf_grad("<<phi_surf_grad<<")"<<endl;
4272  Point<3,fad_double> eta_grad(-q_normal(0)/q_normal(2),-q_normal(1)/q_normal(2),0.0);
4273  Point<3,fad_double> q_nodes_vel(q_x_dot,q_y_dot,q_z_dot);
4274  fluid_vel[q] = Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2))) + phi_grad;
4275  fad_double fluid_vel_norm = fluid_vel[q].norm();
4276  if (fluid_vel_norm < 1e-3)
4277  fluid_vel_norm = -8.0e+05*pow(fluid_vel_norm,3.0) + 1.7e+03*pow(fluid_vel_norm,2.0) + 0.0001;
4278  fad_double cell_diameter;
4279  for (unsigned int i=0; i<dofs_per_cell; ++i)
4280  {
4281  cell_diameter += pow(fluid_vel[q]*(Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2])-center),2.0)/dofs_per_cell;
4282  }
4283  cell_diameter = sqrt(cell_diameter)*2;
4284 
4285  eta_dot_rhs_fun[q] = phi_grad(2) + eta_grad*(q_nodes_vel-fluid_vel[q]);
4286  phi_dot_rhs_fun[q] = phi_grad*phi_grad/2 - g*q_eta + phi_surf_grad_corrected*(q_nodes_vel-fluid_vel[q]);
4287  q_JxW[q] = q_jac_det*ref_fe_v.JxW(q);
4288 
4289  //cout<<q<<" fvel("<<fluid_vel[q].val()<<") fvel_norm="<<fluid_vel_norm<<" q_JxW="<<q_JxW[q]<<endl;
4290  //cout<<q<<" erhs("<<eta_dot_rhs_fun[q]<<") prhs("<<phi_dot_rhs_fun[q]<<")"<<endl;
4291  //cout<<q<<" phi_grad("<<phi_grad<<") phi_surf_grad("<<phi_surf_grad<<")"<<endl;
4292  // cout<<q<<" "<<phi_dot_rhs_fun[q].val()<<endl;//" "<<phi_dot_rhs_fun[q].val()<<endl;
4293  //cout<<q<<" "<<phi_grad(0).val()<<" "<<phi_grad(1).val()<<" "<<phi_grad(2).val()<<endl;
4294 
4295  if (cell->material_id() == comp_dom.free_sur_ID1 ||
4296  cell->material_id() == comp_dom.free_sur_ID2 ||
4297  cell->material_id() == comp_dom.free_sur_ID3 )
4298  {
4299  for (unsigned int i=0; i<dofs_per_cell; ++i)
4300  {
4301  Point<3,fad_double> N_i_surf_grad(d11*ref_fe_v.shape_grad(i,q)[0]+d12*ref_fe_v.shape_grad(i,q)[1],
4302  d21*ref_fe_v.shape_grad(i,q)[0]+d22*ref_fe_v.shape_grad(i,q)[1],
4303  d31*ref_fe_v.shape_grad(i,q)[0]+d32*ref_fe_v.shape_grad(i,q)[1]);
4304  fad_double N_i_supg = fad_double(ref_fe_v.shape_value(i,q)) +
4305  N_i_surf_grad*fluid_vel[q]/fluid_vel_norm*cell_diameter/sqrt(2);
4306  loc_eta_res[i] -= eta_dot_rhs_fun[q]*N_i_supg*q_JxW[q];
4307  loc_phi_res[i] -= phi_dot_rhs_fun[q]*N_i_supg*q_JxW[q];
4308  loc_x_smooth_res[i] -= blend_factor*0*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
4309  loc_y_smooth_res[i] -= blend_factor*0*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
4310  local_DphiDt_rhs(i) += (phi_dot_rhs_fun[q]*N_i_supg*q_JxW[q]).val();
4311  local_DphiDt_rhs_2(i) += (eta_dot_rhs_fun[q]*N_i_supg*q_JxW[q]).val();
4312  // cout<<q<<" "<<endl; //<<local_DphiDt_rhs(i)<<" "<<local_DphiDt_rhs_2(i)<<endl;
4313  // if (q_point(0).val()>36 && q_point(0).val()<70 && abs(q_point(1).val())< 6 && abs(q_point(2).val())< 1)
4314  // {
4315  // std::cout<<"q_point=("<<q_point(0).val()<<","<<q_point(1).val()<<","<<q_point(2).val()<<") q_dphi_dn="<<q_dphi_dn.val()<<endl;
4316  // std::cout<<"phi_grad=("<<phi_grad(0).val()<<","<<phi_grad(1).val()<<","<<phi_grad(2).val()<<")"<<endl;
4317  // std::cout<<"fluid_vel=("<<fluid_vel[q](0).val()<<","<<fluid_vel[q](1).val()<<","<<fluid_vel[q](2).val()<<")"<<endl;
4318  // std::cout<<"q_nodes_vel=("<<q_nodes_vel(0).val()<<","<<q_nodes_vel(1).val()<<","<<q_nodes_vel(2).val()<<")"<<endl;
4319  // std::cout<<"phi_surf_grad_corrected=("<<phi_surf_grad_corrected(0).val()<<","<<phi_surf_grad_corrected(1).val()<<","<<phi_surf_grad_corrected(2).val()<<")"<<endl;
4320  // cout<<q<<" erhs("<<eta_dot_rhs_fun[q].val()<<") prhs("<<phi_dot_rhs_fun[q].val()<<")"<<endl;
4321  // std::cout<<"local_DphiDt_rhs_2(i)="<<local_DphiDt_rhs_2(i)<<"local_DphiDt_rhs_2(i) ="<<local_DphiDt_rhs_2(i)<<")"<<endl;
4322  // }
4323 
4324  //cout<<q<<" "<<i<<" "<<phi_grad(2)<<" "<<eta_grad<<" "<<q_nodes_vel-fluid_vel[q]<<endl;
4325  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
4326  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_rhs_fun[q].val()<<" "<<q_JxW[q].val()<<endl;
4327  for (unsigned int j=0; j<dofs_per_cell; ++j)
4328  {
4329  //loc_eta_res[i] += fad_double(ref_fe_v.shape_value(j,q))*coors_dot[3*j+2]*N_i_supg*q_JxW[q];
4330  //loc_phi_res[i] += fad_double(ref_fe_v.shape_value(j,q))*phis_dot[j]*N_i_supg*q_JxW[q];
4331  //local_DphiDt_matrix.add(i,j,ref_fe_v.shape_value(j,q)*(N_i_supg*q_JxW[q]).val());
4332  loc_supg_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*N_i_supg*q_JxW[q];
4333  Point<3,fad_double> N_j_surf_grad(d11*ref_fe_v.shape_grad(j,q)[0]+d12*ref_fe_v.shape_grad(j,q)[1],
4334  d21*ref_fe_v.shape_grad(j,q)[0]+d22*ref_fe_v.shape_grad(j,q)[1],
4335  d31*ref_fe_v.shape_grad(j,q)[0]+d32*ref_fe_v.shape_grad(j,q)[1]);
4336  loc_stiffness_matrix[i][j] += N_i_surf_grad*N_j_surf_grad*q_JxW[q];
4337  }
4338  //if (fmax(abs(loc_eta_res[i].val()),abs(loc_phi_res[i].val()))>1e-6)
4339  // cout<<q<<" "<<i<<" "<<loc_eta_res[i].val()<<"("<<coors_dot[3*i+2].val()<<") "<<loc_phi_res[i].val()<<"("<<phis_dot[i].val()<<") "<<endl;
4340  }
4341 
4342  }
4343 
4344  if (cell->material_id() == comp_dom.wall_sur_ID1 ||
4345  cell->material_id() == comp_dom.wall_sur_ID2 ||
4346  cell->material_id() == comp_dom.wall_sur_ID3 )
4347  {
4348  for (unsigned int i=0; i<dofs_per_cell; ++i)
4349  {
4350  loc_dphi_dn_res[i] -= -(q_normal*Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2))))*
4351  fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
4352  //cout<<q<<" "<<i<<" "<<-(q_normal*Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2)))).val()<<" "<<cell->center()<<" "<<endl;
4353  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
4354  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_res_fun[q].val()<<" "<<q_JxW[q].val()<<endl;
4355  local_DphiDt_rhs_3(i) += (-(q_normal*Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2))))*
4356  fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
4357  //cout<<"**** "<<loc_dphi_dn_res[i].val()<<" "<<local_DphiDt_rhs_3(i)<<" "<<loc_dphi_dn_res[i].val()+local_DphiDt_rhs_3(i)<<endl;
4358  for (unsigned int j=0; j<dofs_per_cell; ++j)
4359  {
4360  //loc_dphi_dn_res[i] += fad_double(ref_fe_v.shape_value(i,q))*fad_double(ref_fe_v.shape_value(j,q))*dphi_dns[j]*q_JxW[q];
4361  loc_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
4362  }
4363  //if (abs(loc_dphi_dn_res[i].val())>1e-7)
4364  // cout<<q<<" "<<i<<" "<<loc_dphi_dn_res[i].val()<<endl;
4365  }
4366  }
4367 
4368  if (cell->material_id() != comp_dom.wall_sur_ID1 &&
4369  cell->material_id() != comp_dom.wall_sur_ID2 &&
4370  cell->material_id() != comp_dom.wall_sur_ID3 &&
4371  cell->material_id() != comp_dom.free_sur_ID1 &&
4372  cell->material_id() != comp_dom.free_sur_ID2 &&
4373  cell->material_id() != comp_dom.free_sur_ID3)
4374  {
4375  for (unsigned int i=0; i<dofs_per_cell; ++i)
4376  {
4377  loc_dphi_dn_res[i] -= 0;
4378  //cout<<q<<" "<<i<<" "<<-(q_normal*Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2)))).val()<<" "<<cell->center()<<" "<<endl;
4379  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
4380  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_res_fun[q].val()<<" "<<q_JxW[q].val()<<endl;
4381  local_DphiDt_rhs_3(i) += 0;
4382  //cout<<"**** "<<loc_dphi_dn_res[i].val()<<" "<<local_DphiDt_rhs_3(i)<<" "<<loc_dphi_dn_res[i].val()+local_DphiDt_rhs_3(i)<<endl;
4383  for (unsigned int j=0; j<dofs_per_cell; ++j)
4384  {
4385  //loc_dphi_dn_res[i] += fad_double(ref_fe_v.shape_value(i,q))*fad_double(ref_fe_v.shape_value(j,q))*dphi_dns[j]*q_JxW[q];
4386  loc_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
4387  }
4388  //if (abs(loc_dphi_dn_res[i].val())>1e-7)
4389  // cout<<q<<" "<<i<<" "<<loc_dphi_dn_res[i].val()<<endl;
4390  }
4391  }
4392 
4393  for (unsigned int i=0; i<dofs_per_cell; ++i)
4394  {
4395  Point<3,fad_double> N_i_surf_grad(d11*ref_fe_v.shape_grad(i,q)[0]+d12*ref_fe_v.shape_grad(i,q)[1],
4396  d21*ref_fe_v.shape_grad(i,q)[0]+d22*ref_fe_v.shape_grad(i,q)[1],
4397  d31*ref_fe_v.shape_grad(i,q)[0]+d32*ref_fe_v.shape_grad(i,q)[1]);
4398  fad_double N_i_supg = fad_double(ref_fe_v.shape_value(i,q)) +
4399  N_i_surf_grad*fluid_vel[q]/fluid_vel_norm*cell_diameter/sqrt(2);
4400  for (unsigned int j=0; j<dofs_per_cell; ++j)
4401  {
4402  local_DphiDt_matrix.add(i,j,ref_fe_v.shape_value(j,q)*(N_i_supg*q_JxW[q]).val());
4403  local_DphiDt_matrix_2.add(i,j,ref_fe_v.shape_value(j,q)*ref_fe_v.shape_value(i,q)*(q_JxW[q]).val());
4404  //loc_supg_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*N_i_supg*q_JxW[q];
4405  //loc_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
4406  }
4407  }
4408  }
4409 
4410  for (unsigned int i=0; i<dofs_per_cell; ++i)
4411  {
4412  DphiDt_sys_rhs(local_dof_indices[i]) += local_DphiDt_rhs(i);
4413  DphiDt_sys_rhs_2(local_dof_indices[i]) += local_DphiDt_rhs_2(i);
4414  DphiDt_sys_rhs_3(local_dof_indices[i]) += local_DphiDt_rhs_3(i);
4415  for (unsigned int j=0; j<dofs_per_cell; ++j)
4416  {
4417  DphiDt_sys_matrix.add(local_dof_indices[i],local_dof_indices[j],local_DphiDt_matrix(i,j));
4418  DphiDt_sys_matrix_2.add(local_dof_indices[i],local_dof_indices[j],local_DphiDt_matrix_2(i,j));
4419  }
4420  }
4421 
4422  if (cell->material_id() == comp_dom.free_sur_ID1 ||
4423  cell->material_id() == comp_dom.free_sur_ID2 ||
4424  cell->material_id() == comp_dom.free_sur_ID3 )
4425  {
4426  for (unsigned int i=0; i<dofs_per_cell; ++i)
4427  {
4428  for (unsigned int j=0; j<dofs_per_cell; ++j)
4429  {
4430  loc_eta_res[i] += loc_supg_mass_matrix[i][j]*coors_dot[3*j+2];
4431  loc_phi_res[i] += loc_supg_mass_matrix[i][j]*phis_dot[j];
4432  loc_x_smooth_res[i] += loc_stiffness_matrix[i][j]*(x_displs[j]-(1-blend_factor)*comp_dom.old_map_points(3*local_dof_indices[j]));
4433  loc_y_smooth_res[i] += loc_stiffness_matrix[i][j]*(y_displs[j]-(1-blend_factor)*comp_dom.old_map_points(3*local_dof_indices[j]+1));
4434  }
4435  if ( !constraints.is_constrained(local_dof_indices[i]) &&
4436  !(comp_dom.flags[local_dof_indices[i]] & transom_on_water) &&
4437  !(comp_dom.flags[local_dof_indices[i]] & near_inflow))
4438  {
4439  unsigned int ii = local_dof_indices[i];
4440  eta_res[ii] += loc_eta_res[i].val();
4441  phi_res[ii] += loc_phi_res[i].val();
4442 
4443  }
4444  if ( !(constraints.is_constrained(local_dof_indices[i])) &&
4445  !(comp_dom.flags[local_dof_indices[i]] & edge) &&
4446  !(comp_dom.flags[local_dof_indices[i]] & near_inflow))
4447  {
4448  unsigned int ii = local_dof_indices[i];
4449  x_smoothing_res[ii] += loc_x_smooth_res[i].val();
4450  y_smoothing_res[ii] += loc_y_smooth_res[i].val();
4451 
4452  }
4453  }
4454  }
4455  if (cell->material_id() != comp_dom.free_sur_ID1 &&
4456  cell->material_id() != comp_dom.free_sur_ID2 &&
4457  cell->material_id() != comp_dom.free_sur_ID3 )
4458  {
4459  for (unsigned int i=0; i<dofs_per_cell; ++i)
4460  {
4461  unsigned int ii = local_dof_indices[i];
4462  for (unsigned int j=0; j<dofs_per_cell; ++j)
4463  {
4464  loc_dphi_dn_res[i] += loc_mass_matrix[i][j]*dphi_dns[j];
4465  }
4466  if (!constraints.is_constrained(ii))
4467  {
4468  dphi_dn_res[ii] += loc_dphi_dn_res[i].val();
4469  }
4470  }
4471  }
4472  }
4473  }
4474 //for (unsigned int i=0; i<comp_dom.dh.n_dofs();++i)
4475 // cout<<i<<"---> "<<eta_res[i]<<endl;;
4476 
4477  SparseMatrix<double> DphiDt_sys_matrix_copy;
4478  DphiDt_sys_matrix_copy.reinit(DphiDt_sparsity_pattern);
4479  DphiDt_sys_matrix_copy.copy_from(DphiDt_sys_matrix);
4480 
4481  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4482  // {
4483  // cout<<"*** "<<i<<" "<<DphiDt_sys_rhs(i)<<" "<<DphiDt_sys_rhs_2(i)<<" "<<DphiDt_sys_rhs_3(i)<<endl;
4484  // }
4485 
4486  constraints.condense(DphiDt_sys_matrix,DphiDt_sys_rhs);
4487  constraints.condense(DphiDt_sys_matrix_copy,DphiDt_sys_rhs_2);
4488  constraints.condense(DphiDt_sys_matrix_2,DphiDt_sys_rhs_3);
4489 
4490 
4491  SparseDirectUMFPACK DphiDt_direct;
4492  SparseDirectUMFPACK DphiDt_direct_copy;
4493  SparseDirectUMFPACK DphiDt_direct_2;
4494 
4495  DphiDt_direct.initialize(DphiDt_sys_matrix);
4496  DphiDt_direct_copy.initialize(DphiDt_sys_matrix_copy);
4497  DphiDt_direct_2.initialize(DphiDt_sys_matrix_2);
4498 
4499  DphiDt_direct.vmult(DphiDt_sys_solution, DphiDt_sys_rhs); // solving for phi_dot
4500  constraints.distribute(DphiDt_sys_solution);
4501  DphiDt_direct_copy.vmult(DphiDt_sys_solution_2, DphiDt_sys_rhs_2); // solving for eta_dot
4502  constraints.distribute(DphiDt_sys_solution_2);
4503  DphiDt_direct_2.vmult(DphiDt_sys_solution_3, DphiDt_sys_rhs_3); // solving for dphi_dn
4504  constraints.distribute(DphiDt_sys_solution_3);
4505 
4506  Vector<double> RES(DphiDt_sys_solution.size());
4507  DphiDt_sys_matrix.vmult(RES,DphiDt_sys_solution_2);
4508  RES*=-1.0;
4509  RES.add(DphiDt_sys_rhs_2);
4510  RES*=-1.0;
4511 
4512  //for (unsigned int i=0; i<comp_dom.dh.n_dofs();i++)
4513  // {
4514  // if (constraints.is_constrained(i) == 0)
4515  // cout<<"eta_dot("<<i<<") "<<DphiDt_sys_solution_2(i)<<" res("<<i<<") "<<RES(i)<<" eta_res("<<i<<") "<<eta_res[i]<<endl;
4516  // }
4517 
4518  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
4519  {
4520  if ( (comp_dom.flags[i] & water) &&
4521  !(comp_dom.flags[i] & transom_on_water) )
4522  {
4523  yp(3*i+2) = DphiDt_sys_solution_2(i);
4524  // cout<<3*i+2<<" -> "<<yp(3*i+2)<<endl;
4525  yp(i+comp_dom.vector_dh.n_dofs()) = DphiDt_sys_solution(i);
4526  // cout<<i+comp_dom.vector_dh.n_dofs()<<" -> "<<yp(i+comp_dom.vector_dh.n_dofs())<<endl;
4527  }
4528  else
4529  {
4530  y(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = DphiDt_sys_solution_3(i);
4531  }
4532  }
4533 
4534 
4535  RestartNonlinearProblemAlg rest_nonlin_prob_alg(*this,comp_dom,t,y,yp,jacobian_matrix);
4536  NewtonSolver restart_solver_alg(rest_nonlin_prob_alg);
4537 
4538  std::map<unsigned int,unsigned int> &map_alg = rest_nonlin_prob_alg.indices_map;
4539  Vector<double> restart_prob_solution_alg(rest_nonlin_prob_alg.n_dofs());
4540  for (std::map<unsigned int, unsigned int>::iterator it = map_alg.begin(); it != map_alg.end(); ++it)
4541  restart_prob_solution_alg(it->second) = y(it->first);
4542  restart_solver_alg.solve(restart_prob_solution_alg,5);
4543 
4544  //for (unsigned int i=0; i<restart_prob_solution.size(); ++i)
4545  // cout<<i<<" "<<restart_prob_solution(i)<<endl;
4546 
4547  for (std::map<unsigned int, unsigned int>::iterator it = map_alg.begin(); it != map_alg.end(); ++it)
4548  {
4549  y(it->first) = restart_prob_solution_alg(it->second);
4550  //cout<<it->first<<" "<<yp(it->first)<<"("<<restart_prob_solution(it->second)<<")"<<endl;
4551  }
4553  // here we take care of the bem part of the variables
4555 
4556 
4557  bem_phi = (const Vector<double> &)phi;
4558  constraints.distribute(bem_phi);
4559 
4560  bem_dphi_dn = (const Vector<double> &)dphi_dn;
4561  //constraints.distribute(bem_dphi_dn);
4562 
4563  Vector<double> bem_bc(comp_dom.dh.n_dofs());
4564  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
4565  {
4566  if (comp_dom.flags[i] & water)
4567  bem_bc(i) = bem_phi(i);
4568  else
4569  {
4570  if (comp_dom.flags[i] & boat)
4571  bem_bc(i) = bem_dphi_dn(i);
4572  else
4573  bem_bc(i) = 0.0;
4574  }
4575  }
4576 
4577  // trying a fix for transom stern nodes
4578  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4579  {
4580  if ( comp_dom.flags[i] & transom_on_water )
4581  {
4582  comp_dom.surface_nodes(i) = 0;
4583  comp_dom.other_nodes(i) = 1;
4584  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
4585  duplicates.erase(i);
4586  bem_bc(i) = 0;
4587  jacobian_matrix.add(i,i,-1.0);
4588  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
4589  {
4590  bem_bc(i) += bem_dphi_dn(*pos)/duplicates.size();
4591  }
4592  bem_dphi_dn(i) = bem_bc(i);
4593  }
4594  }
4595 
4596  // this is to enforce constraints in a more strict way
4597  // pure normals might not be respecting constraints
4598  //constraints.distribute(bem_phi);
4599  //constraints.distribute(bem_dphi_dn);
4600  //constraints.distribute(bem_bc);
4601 
4602  bem.solve(bem_phi, bem_dphi_dn, bem_bc);
4603 
4604  // this is to enforce constraints in a more strict way
4605  // the vector given back by bem has constraints
4606  // imposed up to the bem GMRES tolerance
4607  //constraints.distribute(bem_phi);
4608  //constraints.distribute(bem_dphi_dn);
4609 
4610  // finally this imposes that the potential on water side of
4611  // transom line equals that on boat side
4612  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4613  {
4614  if (comp_dom.flags[i] & transom_on_water)
4615  {
4616  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
4617  duplicates.erase(i);
4618  bem_phi(i) = bem_phi(*duplicates.begin());
4619  }
4620  }
4621 
4622 
4623  // now bem_phi and bem_dphi_dn are correct, we copy them on phi and dphi_dn
4624  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4625  {
4626  y(i+comp_dom.vector_dh.n_dofs()) = bem_phi(i);
4627  y(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = bem_dphi_dn(i);
4628  //if (comp_dom.flags[i] & water)
4629  // {
4630  // cout<<"bem_phi("<<i<<") "<<y(i+comp_dom.vector_dh.n_dofs())<<endl;
4631  // cout<<"bem_dphi_dn("<<i<<") "<<y(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs())<<endl;
4632  // }
4633  }
4634 
4636 
4637 
4638 
4639 
4640  //residual(t,res,y,yp);
4641  //setup_jacobian_prec(t,y,yp,0.0);
4642 
4643  RestartNonlinearProblemDiff rest_nonlin_prob_diff(*this,comp_dom,t,y,yp,jacobian_dot_matrix);
4644  std::map<unsigned int,unsigned int> &map_diff = rest_nonlin_prob_diff.indices_map;
4645 
4646 
4647  // these lines test the correctness of the jacobian for the
4648  // restart (reduced) nonlinear problem
4649  /*
4650  Vector<double> restart_prob_solution(rest_nonlin_prob_diff.n_dofs());
4651  Vector<double> restart_prob_residual(rest_nonlin_prob_diff.n_dofs());
4652  for (std::map<unsigned int, unsigned int>::iterator it = map_diff.begin(); it != map_diff.end(); ++it)
4653  restart_prob_solution(it->second) = yp(it->first);
4654 
4655  Vector<double> delta_y(rest_nonlin_prob_diff.n_dofs());
4656  Vector<double> delta_res(rest_nonlin_prob_diff.n_dofs());
4657  //delta_y.add(1e-8);
4658  //delta_y(974) = 1e-8;
4659  for (unsigned int i=0; i<rest_nonlin_prob_diff.n_dofs();++i)
4660  {
4661  double f = (double)rand()/RAND_MAX;
4662  delta_y(i) = -1e-8 + f * (2e-8);
4663  cout<<i<<" "<<delta_y(i)<<endl;
4664  }
4665  rest_nonlin_prob_diff.residual(restart_prob_residual,restart_prob_solution);
4666  rest_nonlin_prob_diff.jacobian(delta_res,restart_prob_solution,delta_y);
4667  restart_prob_solution.add(delta_y);
4668  //yp.add(delta_y);
4669  delta_res.add(restart_prob_residual);
4670  rest_nonlin_prob_diff.residual(restart_prob_residual,restart_prob_solution);
4671  cout<<"----------Test---------"<<endl;
4672  for (unsigned int i=0; i<rest_nonlin_prob_diff.n_dofs(); ++i)
4673  if (fabs(restart_prob_residual(i)-delta_res(i)) > 1e-15)
4674  cout<<i<<" "<<delta_res(i)<<" vs "<<restart_prob_residual(i)<<" err "<<restart_prob_residual(i)-delta_res(i)<<" "<<sys_comp(i)<<endl;
4675  delta_res*=-1;
4676  delta_res.add(restart_prob_residual);
4677  cout<<"Absolute error norm: "<<delta_res.l2_norm()<<endl;
4678  cout<<"Relative error norm: "<<delta_res.l2_norm()/delta_y.l2_norm()<<endl;
4679  cout<<"----------Done---------"<<endl;
4680  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4681  cout<<i<<" "<<comp_dom.support_points[i]<<" sn "<<comp_dom.surface_nodes(i)<<" ic "<<constraints.is_constrained(i)<<endl;
4682 
4683  //*/
4684 
4685 
4686 
4687  NewtonSolver restart_solver_diff(rest_nonlin_prob_diff);
4688 
4689  Vector<double> restart_prob_solution_diff(rest_nonlin_prob_diff.n_dofs());
4690  for (std::map<unsigned int, unsigned int>::iterator it = map_diff.begin(); it != map_diff.end(); ++it)
4691  restart_prob_solution_diff(it->second) = yp(it->first);
4692  restart_solver_diff.solve(restart_prob_solution_diff,8);
4693 
4694  //for (unsigned int i=0; i<restart_prob_solution.size(); ++i)
4695  // cout<<i<<" "<<restart_prob_solution(i)<<endl;
4696 
4697  for (std::map<unsigned int, unsigned int>::iterator it = map_diff.begin(); it != map_diff.end(); ++it)
4698  {
4699  yp(it->first) = restart_prob_solution_diff(it->second);
4700  //cout<<it->first<<" "<<yp(it->first)<<"("<<restart_prob_solution_diff(it->second)<<")"<<endl;
4701  }
4702 
4703 
4704  //std::string filename1 = ( "post_restart_mesh.vtu" );
4705  //output_results(filename1, t, y, yp);
4706 
4707 
4708  /*
4709  // these lines test the jacobian of the DAE system
4710 
4711  Vector<double> delta_y(this->n_dofs());
4712  Vector<double> delta_res(this->n_dofs());
4713 
4714  for (unsigned int i=0; i<this->n_dofs();++i)
4715  {
4716  double f = (double)rand()/RAND_MAX;
4717  delta_y(i) = -1e-8 + f * (2e-8);
4718  cout<<i<<" "<<delta_y(i)<<endl;
4719  }
4720  Vector<double> delta_y_dot(delta_y);
4721  delta_y_dot*=00000001.0;
4722  residual(t,res,y,yp);
4723  jacobian(t,delta_res,y,yp,delta_y,00000001.0);
4724  y.add(delta_y);
4725  yp.add(delta_y_dot);
4726  delta_res.add(res);
4727  residual(t,res,y,yp);
4728  cout<<"----------Test---------"<<endl;
4729  for (unsigned int i=0; i<this->n_dofs(); ++i)
4730  if (fabs(res(i)-delta_res(i)) > 1e-15)
4731  //if (fabs(res(i)) > 1e-20)
4732  cout<<i<<" "<<delta_res(i)<<" vs "<<res(i)<<" err "<<res(i)-delta_res(i)<<" "<<sys_comp(i)<<endl;
4733  delta_res*=-1;
4734  delta_res.add(res);
4735  cout<<"Absolute error norm: "<<delta_res.l2_norm()<<endl;
4736  cout<<"Relative error norm: "<<delta_res.l2_norm()/delta_y.l2_norm()<<endl;
4737  cout<<"----------Done---------"<<endl;
4738  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4739  cout<<i<<" "<<comp_dom.support_points[i]<<" sn "<<comp_dom.surface_nodes(i)<<" ic "<<constraints.is_constrained(i)<<endl;
4740  //*/
4741  std::cout<<"... Done preparing interpolated solution for restart"<<std::endl;
4742 
4743 
4744 }
4745 
4746 
4747 
4748 
4749 template <int dim>
4751 {
4752  if (diameters.size() != n_dofs())
4753  {
4754  diameters.reinit(dofs_number);
4755  diameters.add(1000000);
4756 
4757  cell_it
4758  vector_cell = comp_dom.vector_dh.begin_active(),
4759  vector_endc = comp_dom.vector_dh.end();
4760 
4761  cell_it
4762  phi_cell = comp_dom.dh.begin_active(),
4763  phi_endc = comp_dom.dh.end();
4764 
4765  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
4766  update_JxW_values);
4767  const unsigned int n_q_points = fe_v.n_quadrature_points;
4768  std::vector<unsigned int> vector_local_dof_indices(comp_dom.vector_fe.dofs_per_cell);
4769  std::vector<unsigned int> phi_local_dof_indices(comp_dom.fe.dofs_per_cell);
4770 
4771  for (; phi_cell!=phi_endc,vector_cell!=vector_endc; ++phi_cell,++vector_cell)
4772  {
4773  Assert(phi_cell->index() == vector_cell->index(), ExcInternalError());
4774 
4775  phi_cell->get_dof_indices(phi_local_dof_indices);
4776  vector_cell->get_dof_indices(vector_local_dof_indices);
4777  for (unsigned int i=0; i<comp_dom.vector_fe.dofs_per_cell; ++i)
4778  {
4779  diameters(vector_local_dof_indices[i]) =
4780  fmin(diameters(vector_local_dof_indices[i]),vector_cell->diameter());
4781  }
4782  for (unsigned int i=0; i<comp_dom.fe.dofs_per_cell; ++i)
4783  {
4784  diameters(phi_local_dof_indices[i]+comp_dom.vector_dh.n_dofs()) =
4785  fmin(diameters(phi_local_dof_indices[i]+comp_dom.vector_dh.n_dofs()),phi_cell->diameter());
4786  diameters(phi_local_dof_indices[i]+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) =
4787  fmin(diameters(phi_local_dof_indices[i]+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()),phi_cell->diameter());
4788  }
4789 
4790  }
4791  }
4792  return diameters;
4793 }
4794 
4795 template <int dim>
4797  const Vector<double> &src_yy)
4798 {
4799  double alpha = 0;
4800  // here nodes_alg_jac_x_delta won't be used, it's just to feed it with something
4801  // withoud having to generate a (big) dummy vector
4802  nodes_alg_jac_x_delta=0;
4803  residual_and_jacobian(current_time,dst,current_sol,src_yy,nodes_alg_jac_x_delta,0.0,false);
4804 
4805 
4806  dae_nonlin_residual = dst;
4807  dae_nonlin_residual*=-1;
4808 
4809 
4810  return 0;
4811 }
4812 
4813 
4814 template <int dim>
4815 int FreeSurface<dim>::residual(const double t,
4816  Vector<double> &dst,
4817  const Vector<double> &src_yy,
4818  const Vector<double> &src_yp)
4819 {
4820  double alpha = 0;
4821  // here nodes_alg_jac_x_delta won't be used, it's just to feed it with something
4822  // withoud having to generate a (big) dummy vector
4823  residual_and_jacobian(t,dst,src_yy,src_yp,nodes_alg_jac_x_delta,alpha,false);
4824 
4825 
4826  dae_nonlin_residual = dst;
4827  dae_nonlin_residual*=-1;
4828 
4829  //for (unsigned int i=0; i<dst.size(); ++i)
4830  // {
4831  // cout<<i<<" -> "<<dst(i)<<endl;
4832  // }
4833 
4834 
4835  return 0;
4836 }
4837 
4838 
4839 
4840 template <int dim>
4842 {
4843 
4844  dst = 0;
4845 
4846  Vector<double> pphi(comp_dom.dh.n_dofs());
4847  Vector<double> dpphi_dn(comp_dom.dh.n_dofs());
4848  Vector<double> bem_pphi(comp_dom.dh.n_dofs());
4849  Vector<double> bem_dpphi_dn(comp_dom.dh.n_dofs());
4850 
4851  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4852  {
4853  pphi(i) = src(i+comp_dom.vector_dh.n_dofs());
4854  bem_pphi(i) = src(i+comp_dom.vector_dh.n_dofs());
4855  dpphi_dn(i) = src(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
4856  bem_dpphi_dn(i) = src(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
4857  }
4858 
4859 // const VectorView<double> phi(comp_dom.dh.n_dofs(),src.begin()+comp_dom.vector_dh.n_dofs());
4860 // const VectorView<double> dphi_dn(comp_dom.dh.n_dofs(),src.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
4861 
4862  //bem_phi = pphi; //(const Vector<double> &)phi;
4863  constraints.distribute(bem_pphi);
4864 
4865  //bem_dphi_dn = dpphi_dn;//(const Vector<double> &)dphi_dn;
4866  constraints.distribute(bem_dpphi_dn);
4867 
4868  Vector<double> bem_bc(comp_dom.dh.n_dofs());
4869  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
4870  {
4871  if (comp_dom.flags[i] & water)
4872  bem_bc(i) = bem_pphi(i);
4873  else
4874  bem_bc(i) = bem_dpphi_dn(i);
4875  }
4876 
4877  bem.solve_system(bem_pphi, bem_dpphi_dn, bem_bc);
4878 
4879  jacobian_dot_matrix.vmult(dst,src);
4880  dst*=alpha;
4881  jacobian_matrix.vmult_add(dst,src);
4882 
4883  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4884  {
4885  if ( //(!constraints.is_constrained(i)) &&
4886  (comp_dom.flags[i] & water) )
4887  {
4888  dst(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = dpphi_dn(i) - bem_dphi_dn(i);
4889  }
4890  else if ( //(!constraints.is_constrained(i)) &&
4891  (!(comp_dom.flags[i] & water)) )
4892  {
4893  dst(i+comp_dom.vector_dh.n_dofs()) = pphi(i) - bem_phi(i);
4894  }
4895  }
4896 
4897 
4898 
4899 
4900 
4901 }
4902 
4903 
4904 template <int dim>
4906  const Vector<double> &src_yy,
4907  const Vector<double> &src)
4908 {
4909 
4910  Vector<double> src_copy(src);
4911  jacobian(current_time,dst,current_sol,src_yy,src_copy,1e7);
4912 
4913  return 0;
4914 }
4915 
4916 
4917 template <int dim>
4918 int FreeSurface<dim>::jacobian(const double t,
4919  Vector<double> &dst,
4920  const Vector<double> &src_yy,
4921  const Vector<double> &src_yp,
4922  const Vector<double> &src,
4923  const double alpha)
4924 {
4925 
4926  //for (unsigned int i=0; i<dst.size(); ++i)
4927  // cout<<"src("<<i<<") = "<<src(i)<<endl;
4928  //residual_and_jacobian(t,dst,src_yy,src_yp,src,alpha,true);
4929 
4930  dst = 0;
4931 
4932  const VectorView<double> phi(comp_dom.dh.n_dofs(),src.begin()+comp_dom.vector_dh.n_dofs());
4933  const VectorView<double> dphi_dn(comp_dom.dh.n_dofs(),src.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
4934 
4935  bem_phi = (const Vector<double> &)phi;
4936  constraints.distribute(bem_phi);
4937 
4938  bem_dphi_dn = (const Vector<double> &)dphi_dn;
4939  constraints.distribute(bem_dphi_dn);
4940 
4941  Vector<double> bem_bc(comp_dom.dh.n_dofs());
4942  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
4943  {
4944  if (comp_dom.flags[i] & water ||
4945  comp_dom.flags[i] & pressure)
4946  bem_bc(i) = phi(i);
4947  else
4948  bem_bc(i) = dphi_dn(i);
4949  }
4950 
4951  // trying a fix for transom stern nodes
4952  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4953  {
4954  if ( comp_dom.flags[i] & transom_on_water )
4955  {
4956  comp_dom.surface_nodes(i) = 0;
4957  comp_dom.other_nodes(i) = 1;
4958  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
4959  duplicates.erase(i);
4960  bem_bc(i) = 0;
4961  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
4962  {
4963  bem_bc(i) += bem_dphi_dn(*pos)/duplicates.size();
4964  }
4965  bem_dphi_dn(i) = bem_bc(i);
4966  }
4967  }
4968 
4969  // trying a fix for water/pressure nodes (water side)
4970  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
4971  {
4972  if ( (comp_dom.flags[i] & water) && (comp_dom.flags[i] & near_pressure) )
4973  {
4974  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
4975  duplicates.erase(i);
4976  unsigned int count=0;
4977  bem_bc(i) = 0;
4978  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
4979  if (comp_dom.flags[*pos] & pressure)
4980  count++;
4981 
4982  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
4983  {
4984  if (comp_dom.flags[*pos] & pressure)
4985  {
4986  bem_bc(i) += phi(*pos)/count;
4987  }
4988  }
4989  bem_phi(i) = bem_bc(i);
4990  }
4991  }
4992 
4993  bem.solve_system(bem_phi, bem_dphi_dn, bem_bc);
4994 
4995  /*
4996  cout<<"JACOBIANO!!!!!!"<<endl;
4997  for (SparsityPattern::iterator col=jacobian_sparsity_pattern.begin(80); col!=jacobian_sparsity_pattern.end(80); ++col)
4998  {
4999  unsigned int j = col->column();
5000  cout<<j<<"("<<jacobian_matrix(80,j)<<") ";
5001  }
5002  cout<<endl;
5003  //*/
5004 
5005 //for (SparsityPattern::iterator col=jacobian_sparsity_pattern.begin(3196); col!=jacobian_sparsity_pattern.end(3196); ++col)
5006 // {
5007 // unsigned int j = col->column();
5008 // cout<<" "<<3196<<" "<<j<<" "<<jacobian_matrix(3196,j)<<" "<<alpha*jacobian_dot_matrix(3196,j)<<" * "<<src(j)<<endl;
5009 // }
5010 
5011  jacobian_dot_matrix.vmult(dst,src);
5012 
5013  dst*=alpha;
5014  jacobian_matrix.vmult_add(dst,src);
5015 
5016  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5017  {
5018  if ( (!constraints.is_constrained(i)) &&
5019  ((comp_dom.flags[i] & water) || (comp_dom.flags[i] & pressure)) &&
5020  (!(comp_dom.flags[i] & transom_on_water)))
5021  {
5022  //cout<<i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()<<" *** "<<bem_dphi_dn(i)<<endl;
5023  dst(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = bem_dphi_dn(i) - dphi_dn(i);
5024  }
5025  else if ( (!constraints.is_constrained(i)) &&
5026  (!(comp_dom.flags[i] & transom_on_water)) )
5027  {
5028  dst(i+comp_dom.vector_dh.n_dofs()) = bem_phi(i) - phi(i);
5029  }
5030  else if ( (comp_dom.flags[i] & transom_on_water) )
5031  {
5032  dst(i+comp_dom.vector_dh.n_dofs()) = bem_phi(i) - phi(i);
5033  }
5034  }
5035 
5036 
5037 
5038  dae_linear_step_residual = dae_nonlin_residual;
5039  dae_linear_step_residual.add(dst);
5040 
5041  cout<<"Linear step residual: "<<dae_linear_step_residual.l2_norm()<<endl;
5042 
5043 // for (unsigned int i=0; i<dst.size(); ++i)
5044 // cout<<i<<" "<<dst(i)<<" "<<src_yy(i)<<" "<<src_yp(i)<<" "<<src(i)<<endl;
5045 
5046 
5047  static unsigned int jac_evals = 0;
5048  jac_evals++;
5049  std::cout << "Jacobian matrix-vector product evaluations: " << jac_evals << std::endl;
5050 
5051 
5052  return 0;
5053 }
5054 
5055 
5062 template <int dim>
5064  Vector<double> &dst,
5065  const Vector<double> &src_yy,
5066  const Vector<double> &src_yp,
5067  const Vector<double> &src,
5068  const double alpha,
5069  const bool is_jacobian)
5070 {
5071  jacobian_matrix = 0;
5072  jacobian_dot_matrix = 0;
5073 
5074  static double old_time = -1000;
5075  dst = 0;
5076 
5077 
5078  //if (t != old_time)
5079  //{
5080  //comp_dom.old_map_points = comp_dom.map_points;
5081  //std::string filename1 = ( "new_ts_mesh.vtu" );
5082  //output_results(filename1, t, src_yy, src_yp);
5083  //}
5084 //*/
5085 
5086 
5087 
5088 
5089  const VectorView<double> nodes_positions(comp_dom.vector_dh.n_dofs(),src_yy.begin());
5090  const VectorView<double> nodes_velocities(comp_dom.vector_dh.n_dofs(),src_yp.begin());
5091  const VectorView<double> phi(comp_dom.dh.n_dofs(),src_yy.begin()+comp_dom.vector_dh.n_dofs());
5092  const VectorView<double> phi_time_derivs(comp_dom.dh.n_dofs(),src_yp.begin()+comp_dom.vector_dh.n_dofs());
5093  const VectorView<double> dphi_dn(comp_dom.dh.n_dofs(),src_yy.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
5094  const VectorView<double> dphi_dn_time_derivs(comp_dom.dh.n_dofs(),src_yp.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
5095 
5096  Point<3> hull_lin_vel;
5097  Point<3> hull_lin_displ;
5098  Point<3> hull_lin_vel_dot;
5099  Point<3> hull_lin_displ_dot;
5100  Point<3> hull_ang_vel;
5101  Point<3> hull_quat_vector;
5102  Point<3> hull_ang_vel_dot;
5103  Point<3> hull_quat_vector_dot;
5104  for (unsigned int d=0; d<3; ++d)
5105  {
5106  hull_lin_vel(d) = src_yy(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
5107  hull_lin_displ(d) = src_yy(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
5108  hull_lin_vel_dot(d) = src_yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
5109  hull_lin_displ_dot(d) = src_yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
5110  hull_ang_vel(d) = src_yy(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
5111  hull_quat_vector(d) = src_yy(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
5112  hull_ang_vel_dot(d) = src_yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
5113  hull_quat_vector_dot(d) = src_yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9+d);
5114  }
5115  double hull_quat_scalar = src_yy(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
5116  double hull_quat_scalar_dot = src_yp(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12);
5117 
5118  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5119  // cout<<3*i<<" "<<nodes_velocities(3*i)<<" "<<nodes_velocities(3*i+1)<<" "<<nodes_velocities(3*i+2)<<endl;
5120 
5121  bool new_time_step = false;
5122  if (t != old_time)
5123  {
5124  old_time = t;
5125  new_time_step = true;
5126  }
5127 
5128 
5129 
5130  // TO BE REMOVED
5131  DphiDt_sys_rhs.reinit (comp_dom.dh.n_dofs());
5132  DphiDt_sys_rhs_2.reinit (comp_dom.dh.n_dofs());
5133  DphiDt_sys_rhs_3.reinit (comp_dom.dh.n_dofs());
5134  DphiDt_sys_rhs_4.reinit (comp_dom.dh.n_dofs());
5135  DphiDt_sys_matrix.reinit(DphiDt_sparsity_pattern);
5136  DphiDt_sys_matrix_2.reinit(DphiDt_sparsity_pattern);
5137 
5138  //if(old_time < t)
5139  // {
5140  //std::string filename1 = ( "mesh.vtu" );
5141  //output_results(filename1, t, src_yy, src_yp);
5142  // }
5143 
5144 
5145  AssertDimension(dst.size(), src_yy.size());
5146  wind.set_time(t);
5147  inflow_norm_potential_grad.set_time(t);
5148  Vector<double> instantWindValue(dim);
5149  Point<dim> zero(0,0,0);
5150  wind.vector_value(zero,instantWindValue);
5151  std::cout<<std::endl<<"Simulation time= "<<t<<" Vinf= ";
5152  instantWindValue.print(std::cout,4,false,true);
5153  std::cout << "Ndofs ODE= " << dst.size();
5154  std::cout << " Ndofs BEM= " << comp_dom.dh.n_dofs();
5155  std::cout<<std::endl;
5156  wind.set_time(t);
5157 
5158  cout<<"Hull Rigid Displacement: "<<hull_lin_displ<<endl;
5159  cout<<"Restart Hull Rigid Displacement: "<<restart_hull_displacement<<endl;
5160  cout<<"Hull Rigid Velocity: "<<hull_lin_vel<<endl;
5161  cout<<"Hull Angular Velocity: "<<hull_ang_vel<<endl;
5162 
5163  // these two for loops set the jacobian for all the constrained (hanging node dofs)
5164  // first one is for position dofs
5165  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
5166  {
5167  if (vector_constraints.is_constrained(i))
5168  {
5169  jacobian_matrix.add(i,i,1.0);
5170  std::vector< std::pair< unsigned int, double > > entries = *vector_constraints.get_constraint_entries(i);
5171  for (unsigned int k=0; k<entries.size(); ++k)
5172  {
5173  //cout<<"* "<<i<<endl;
5174  //cout<<i<<" "<<entries[k].first<<" "<<-entries[k].second<<endl;
5175  jacobian_matrix.add(i,entries[k].first,-entries[k].second);
5176  }
5177  }
5178  }
5179 
5180  // second one is for potential and potential normal derivative dofs
5181  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5182  {
5183  //cout<<i<<" "<<comp_dom.surface_nodes(i)<<" ("<<comp_dom.support_points[i]<<")"<<endl;
5184  if (constraints.is_constrained(i))
5185  {
5186  jacobian_matrix.add(i+comp_dom.vector_dh.n_dofs(),i+comp_dom.vector_dh.n_dofs(),-1.0);
5187  jacobian_matrix.add(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),-1.0);
5188  std::vector< std::pair< unsigned int, double > > entries = *constraints.get_constraint_entries(i);
5189  for (unsigned int k=0; k<entries.size(); ++k)
5190  {
5191  //cout<<i<<" "<<entries[k].first<<" "<<-entries[k].second<<endl;
5192  jacobian_matrix.add(i+comp_dom.vector_dh.n_dofs(),entries[k].first+comp_dom.vector_dh.n_dofs(),entries[k].second);
5193  jacobian_matrix.add(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
5194  entries[k].first+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),entries[k].second);
5195  }
5196  }
5197  }
5198 
5200  // here we take care of the geometric part of the variables
5202 
5203 
5204  // these lines take care of the hull (and consequential hull internal grid nodes) displacement
5205  // these lines will only act when the time step is new
5206 
5207  //if (new_time_step)
5208  // {
5209  //double rigid_vertical_displacement = 0.01*sin(2.0*dealii::numbers::PI*t);
5210  //double rigid_angular_displacement = 0.01*sin(1.0*dealii::numbers::PI*t);
5211  //cout<<"Displacement: "<<rigid_vertical_displacement<<" "<<sin(2.0*(dealii::numbers::PI)*t)<<endl;
5212  // this is the displacement of the hull geometry (all projectors and smoothers will adapt
5213  // to the change)
5214 
5215 
5216  gp_Trsf reference_to_current_transformation = comp_dom.boat_model.set_current_position(hull_lin_displ,
5217  hull_quat_scalar,
5218  hull_quat_vector);
5219 
5220  // this moves the rigid_motion_map_points vector (target positions) for the internal nodes of the hull
5221  // mesh (all nodes except for the free surface ones)
5222  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5223  {
5224  if ( ((comp_dom.flags[i] & boat) &&
5225  !(comp_dom.flags[i] & near_water) ) ||
5226  (comp_dom.flags[i] & transom_on_water) )
5227  {
5228  //if (fabs(t-0.2) <1e-5)
5229  //cout<<"BEFORE: "<<comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i)<<" "
5230  // <<comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1)<<" "
5231  // <<comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)<<endl;
5232  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
5233  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
5234  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
5235  gp_Pnt boat_mesh_point = original_boat_mesh_point;
5236  // we first take this point (which is in the RESTART hull location) and transform it to be in the
5237  // REFERENCE configuration
5238  boat_mesh_point.Transform(restart_hull_location.Inverted());
5239 
5240  // now we use sacado to compute the residual at this dof, along with its derivatives with respect to
5241  // the 7 dofs associated to the rigid linear and angular displacements
5242  fad_double s_x,s_y,s_z,v_x,v_y,v_z,s;
5243 
5244  s_x = hull_lin_displ(0);
5245  s_y = hull_lin_displ(1);
5246  s_z = hull_lin_displ(2);
5247  v_x = hull_quat_vector(0);
5248  v_y = hull_quat_vector(1);
5249  v_z = hull_quat_vector(2);
5250  s = hull_quat_scalar;
5251 
5252  s_x.diff(0,7);
5253  s_y.diff(1,7);
5254  s_z.diff(2,7);
5255  v_x.diff(3,7);
5256  v_y.diff(4,7);
5257  v_z.diff(5,7);
5258  s.diff(6,7);
5259 
5260  Point<3,fad_double> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
5261  comp_dom.boat_model.reference_hull_baricenter(1),
5262  comp_dom.boat_model.reference_hull_baricenter(2));
5263 
5264  Point<3,fad_double> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
5265  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
5266  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
5267 
5268  Point<3,fad_double> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
5269  Point<3,fad_double> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
5270  Point<3,fad_double> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
5271 
5272  Point<3,fad_double> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
5273  Point<3,fad_double> rigid_lin_displ(s_x,s_y,s_z);
5274  Point<3,fad_double> target_point_pos(RotMatRow1*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5275  RotMatRow2*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5276  RotMatRow3*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos));
5277  target_point_pos += baricenter_pos;
5278  // now we have the point on the REFERENCE hull, and transform it to go onto the CURRENT hull
5279  //boat_mesh_point.Transform(reference_to_current_transformation);
5280  // the rigid motion map points is the difference between the reference point position and the
5281  // current (rigidly displaced) node position
5282 
5283  comp_dom.rigid_motion_map_points(3*i) = target_point_pos(0).val()-ref_point_pos(0).val();
5284  comp_dom.rigid_motion_map_points(3*i+1) = target_point_pos(1).val()-ref_point_pos(1).val();
5285  comp_dom.rigid_motion_map_points(3*i+2) = target_point_pos(2).val()-ref_point_pos(2).val();
5286 
5287  //if (fabs(t-0.2) <1e-5)
5288  //cout<<"AFTER: "<<Pnt(boat_mesh_point)<<" vs "<<Pnt(original_boat_mesh_point)<<endl;
5289  //cout<<"RMMP: "<<comp_dom.rigid_motion_map_points(3*i)<<" "
5290  // <<comp_dom.rigid_motion_map_points(3*i+1)<<" "
5291  // <<comp_dom.rigid_motion_map_points(3*i+2)<<endl;
5292  //cout<<"NN: "<<comp_dom.rigid_motion_map_points(3*i)+nodes_positions(3*i)+comp_dom.ref_points[3*i](0)<<" "
5293  // <<comp_dom.rigid_motion_map_points(3*i+1)+nodes_positions(3*i+1)+comp_dom.ref_points[3*i](1)<<" "
5294  // <<comp_dom.rigid_motion_map_points(3*i+2)+nodes_positions(3*i+2)+comp_dom.ref_points[3*i](2)<<endl;
5295  }
5296  }
5297 
5298  // }
5299 
5300 
5301 
5302 
5303 
5304  Vector<double> full_map_points(comp_dom.rigid_motion_map_points);
5305  full_map_points.add(nodes_positions);
5306  comp_dom.update_mapping(full_map_points);
5307  comp_dom.update_support_points();
5308 
5309 
5310  //we work on a local COPY of map_points
5311  working_map_points = comp_dom.map_points;
5312  nodes_pos_res = 0;
5313 
5314  //we enforce constraint on the new geometry assigned by the DAE solver
5315  vector_constraints.distribute(working_map_points);
5316 
5317  // as for now x and y coordinates of nodes are not moved (no surface smoothing)
5318  // so on x and y coordinates (except for water nodes) we only need to put a one
5319  // on the matrix diagonal
5320  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5321  {
5322  if ( !(comp_dom.flags[i] & near_boat) &&
5323  (comp_dom.flags[i] & water) &&
5324  (comp_dom.flags[i] & edge) &&
5325  !(comp_dom.flags[i] & transom_on_water) &&
5326  (!constraints.is_constrained(i)))
5327  {
5328  working_map_points(3*i) = comp_dom.old_map_points(3*i);
5329  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1);
5330  jacobian_matrix.add(3*i,3*i,1.0);
5331  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5332  if (comp_dom.flags[i] & near_inflow)
5333  {
5334  working_map_points(3*i+2) = comp_dom.old_map_points(3*i+2);
5335  jacobian_matrix.set(3*i+2,3*i+2,1.0);
5336  }
5337  //cout<<"& "<<3*i<<" "<<3*i+1<<endl;
5338  }
5339  else if ( !(comp_dom.flags[i] & near_water) &&
5340  (comp_dom.flags[i] & boat) &&
5341  (!constraints.is_constrained(i)))
5342  {
5343  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
5344  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
5345  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
5346  gp_Pnt boat_mesh_point = original_boat_mesh_point;
5347  // we first take this point (which is in the RESTART hull location) and transform it to be in the
5348  // REFERENCE configuration
5349  boat_mesh_point.Transform(restart_hull_location.Inverted());
5350  Point<3,fad_double> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
5351 
5352  working_map_points(3*i) = ref_point_pos(0).val()-comp_dom.ref_points[3*i](0)+comp_dom.rigid_motion_map_points(3*i);
5353  working_map_points(3*i+1) = ref_point_pos(1).val()-comp_dom.ref_points[3*i](1)+comp_dom.rigid_motion_map_points(3*i+1);
5354  working_map_points(3*i+2) = ref_point_pos(2).val()-comp_dom.ref_points[3*i](2)+comp_dom.rigid_motion_map_points(3*i+2);
5355  jacobian_matrix.add(3*i,3*i,1.0);
5356  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5357  jacobian_matrix.add(3*i+2,3*i+2,1.0);
5358  }
5359  else if ( !(comp_dom.flags[i] & near_water) &&
5360  !(comp_dom.flags[i] & water) &&
5361  !(comp_dom.flags[i] & boat) &&
5362  (!constraints.is_constrained(i)))
5363  {
5364  working_map_points(3*i) = comp_dom.old_map_points(3*i);
5365  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1);
5366  working_map_points(3*i+2) = comp_dom.old_map_points(3*i+2);
5367  jacobian_matrix.add(3*i,3*i,1.0);
5368  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5369  jacobian_matrix.add(3*i+2,3*i+2,1.0);
5370  //cout<<"&& "<<3*i<<" "<<3*i+1<<" "<<3*i+2<<endl;
5371  }
5372  else if ((comp_dom.flags[i] & transom_on_water) )
5373  {
5374  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
5375  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
5376  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
5377  gp_Pnt boat_mesh_point = original_boat_mesh_point;
5378  // we first take this point (which is in the RESTART hull location) and transform it to be in the
5379  // REFERENCE configuration
5380  boat_mesh_point.Transform(restart_hull_location.Inverted());
5381  Point<3,fad_double> ref_point_pos(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
5382 
5383  working_map_points(3*i) = ref_point_pos(0).val()-comp_dom.ref_points[3*i](0)+comp_dom.rigid_motion_map_points(3*i);
5384  working_map_points(3*i+1) = ref_point_pos(1).val()-comp_dom.ref_points[3*i](1)+comp_dom.rigid_motion_map_points(3*i+1);
5385  working_map_points(3*i+2) = ref_point_pos(2).val()-comp_dom.ref_points[3*i](2)+comp_dom.rigid_motion_map_points(3*i+2);
5386  jacobian_matrix.add(3*i,3*i,1.0);
5387  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5388  jacobian_matrix.add(3*i+2,3*i+2,1.0);
5389  }
5390  }
5391 
5392  // blending factor is needed to avoid that right after restart
5393  // the free surface mesh smoothing causes infinite horizontal nodes velocity:
5394  // in fact, at restars water line nodes are moved along water lines for surface
5395  // smoothing, while surrounding free surface nodes are still. as soon as
5396  // time integration is restarted the smoothing forces them to move of a finite
5397  // displacement over a zero time span. using this blending factor could be avoided if
5398  // surface smoothing was done at restarts too. but this is somehow troublesome as
5399  // the interpolation if potential on the new (smoothed) surface mesh is troublesome
5400  double blend_factor = 0.0;
5401  if (restart_flag)
5402  {
5403  }
5404  else
5405  {
5406 
5407  if (t - last_remesh_time < 0.5*remeshing_period)
5408  blend_factor = sin(3.141592654*(t-last_remesh_time)/remeshing_period);
5409  else
5410  blend_factor = 1.0;
5411  //std::cout<<"t "<<t<<" last_remesh_time "<<last_remesh_time<<" remeshing_period/5 "<<remeshing_period/5<<std::endl;
5412  std::cout<<"blend_factor = "<<blend_factor<<std::endl;
5413  }
5414 
5415  //this takes care of the right water line nodes projection (without smoothing)
5416  if (!comp_dom.no_boat)
5417  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5418  {
5419  fad_double s_x,s_y,s_z,v_x,v_y,v_z,s;
5420 
5421  s_x = hull_lin_displ(0);
5422  s_y = hull_lin_displ(1);
5423  s_z = hull_lin_displ(2);
5424  v_x = hull_quat_vector(0);
5425  v_y = hull_quat_vector(1);
5426  v_z = hull_quat_vector(2);
5427  s = hull_quat_scalar;
5428 
5429  s_x.diff(0,7);
5430  s_y.diff(1,7);
5431  s_z.diff(2,7);
5432  v_x.diff(3,7);
5433  v_y.diff(4,7);
5434  v_z.diff(5,7);
5435  s.diff(6,7);
5436 
5437  Point<3,fad_double> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
5438  comp_dom.boat_model.reference_hull_baricenter(1),
5439  comp_dom.boat_model.reference_hull_baricenter(2));
5440 
5441 
5442  Point<3,fad_double> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
5443  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
5444  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
5445 
5446  Point<3,fad_double> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
5447  Point<3,fad_double> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
5448  Point<3,fad_double> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
5449 
5450  if ( (comp_dom.flags[i] & water) &&
5451  (comp_dom.flags[i] & near_boat) &&
5452  (comp_dom.flags[i] & right_side) &&
5453  !(comp_dom.flags[i] & transom_on_water) &&
5454  (comp_dom.moving_point_ids[3] != i) &&
5455  (comp_dom.moving_point_ids[4] != i) &&
5456  (comp_dom.moving_point_ids[5] != i) &&
5457  (comp_dom.moving_point_ids[6] != i) ) // to avoid the bow and stern node
5458  {
5459  //cout<<"**** "<<i<<endl;
5460  Point<3> proj_node;
5461  Point<3> iges_normal;
5462  double iges_curvature;
5463  Point<3> direction(comp_dom.iges_normals[i](0),comp_dom.iges_normals[i](1),0.0);
5464  //if (fabs(comp_dom.old_iges_normals[i](0)) > 0.001)
5465  // cout<<3*i+1<<" "<<comp_dom.support_points[i]<<" ("<<comp_dom.old_iges_normals[i]<<")"<<endl;
5466  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
5467  direction(0) = 0.0;
5468  else
5469  direction(1) = 0.0;
5470  //if (fabs(comp_dom.iges_normals[i](0))<0.001)
5471  // cout<<3*i<<" dir: ("<<direction<<")"<<endl;
5472  comp_dom.boat_model.boat_water_line_right->assigned_axis_projection_and_diff_forms(proj_node,
5473  comp_dom.iges_normals[i],
5474  comp_dom.iges_mean_curvatures[i],
5475  comp_dom.support_points[i],
5476  direction); // hor normal dir projection
5477  //comp_dom.boat_model.boat_water_line_right->axis_projection_and_diff_forms(proj_node,
5478  // comp_dom.iges_normals[i],
5479  // comp_dom.iges_mean_curvatures[i],
5480  // comp_dom.support_points[i]); // y axis projection
5481  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
5482  {
5483  working_map_points(3*i) = comp_dom.old_map_points(3*i); // x of the node must not change
5484  working_map_points(3*i+1) = proj_node(1) - comp_dom.ref_points[3*i](1);
5485  }
5486  else
5487  {
5488  working_map_points(3*i) = proj_node(0) - comp_dom.ref_points[3*i](0);
5489  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1); // y of the node must not change
5490  }
5491  working_map_points(3*i+2) = proj_node(2) - comp_dom.ref_points[3*i](2);
5492 
5493  // here we compute the derivatives: we are basically computing the same residual on the tangent plane, which
5494  // will have the same derivatives as the surface
5495  gp_Pnt ref_point(proj_node(0),proj_node(1),proj_node(2));
5496  ref_point.Transform(reference_to_current_transformation.Inverted());
5497  gp_Vec curr_normal(comp_dom.iges_normals[i](0),comp_dom.iges_normals[i](1),comp_dom.iges_normals[i](2));
5498  gp_Dir ref_normal_dir(curr_normal);
5499  ref_normal_dir.Transform(reference_to_current_transformation.Inverted());
5500 
5501  Point<3,fad_double> ref_point_pos(ref_point.X(),ref_point.Y(),ref_point.Z());
5502  Point<3,fad_double> rigid_lin_displ(s_x,s_y,s_z);
5503  Point<3,fad_double> target_point_pos(RotMatRow1*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5504  RotMatRow2*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5505  RotMatRow3*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos));
5506  target_point_pos += baricenter_pos;
5507  Point<3,fad_double> ref_normal(ref_normal_dir.X(),ref_normal_dir.Y(),ref_normal_dir.Z());
5508  Point<3,fad_double> target_point_normal(RotMatRow1*ref_normal,
5509  RotMatRow2*ref_normal,
5510  RotMatRow3*ref_normal);
5511  Point<3,fad_double> guessed_point(comp_dom.support_points[i](0),comp_dom.support_points[i](1),comp_dom.support_points[i](2));
5512 
5513 
5514  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
5515  {
5516  fad_double residual = guessed_point(1)+
5517  target_point_normal(0)/target_point_normal(1)*(guessed_point(0)-target_point_pos(0))+
5518  target_point_normal(2)/target_point_normal(1)*(guessed_point(2)-target_point_pos(2))-
5519  target_point_pos(1);
5520  jacobian_matrix.add(3*i,3*i,1.0);
5521  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5522  jacobian_matrix.add(3*i+1,3*i+2,comp_dom.iges_normals[i](2)/comp_dom.iges_normals[i](1));
5523  jacobian_matrix.add(3*i+1,3*i,comp_dom.iges_normals[i](0)/comp_dom.iges_normals[i](1));
5524  for (unsigned int d=0; d<3; ++d)
5525  jacobian_matrix.add(3*i+1,comp_dom.vector_dh.n_dofs()+
5526  comp_dom.dh.n_dofs()+
5527  comp_dom.dh.n_dofs()+
5528  3+d,residual.fastAccessDx(d));
5529  for (unsigned int d=0; d<4; ++d)
5530  jacobian_matrix.add(3*i+1,comp_dom.vector_dh.n_dofs()+
5531  comp_dom.dh.n_dofs()+
5532  comp_dom.dh.n_dofs()+
5533  9+d,residual.fastAccessDx(3+d));
5534  }
5535  else
5536  {
5537  fad_double residual = guessed_point(0)+
5538  target_point_normal(1)/target_point_normal(0)*(guessed_point(1)-target_point_pos(1))+
5539  target_point_normal(2)/target_point_normal(0)*(guessed_point(2)-target_point_pos(2))-
5540  target_point_pos(1);
5541  jacobian_matrix.add(3*i,3*i,1.0);
5542  jacobian_matrix.add(3*i,3*i+2,comp_dom.iges_normals[i](2)/comp_dom.iges_normals[i](0));
5543  jacobian_matrix.add(3*i,3*i+1,comp_dom.iges_normals[i](1)/comp_dom.iges_normals[i](0));
5544  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5545  for (unsigned int d=0; d<3; ++d)
5546  jacobian_matrix.add(3*i,comp_dom.vector_dh.n_dofs()+
5547  comp_dom.dh.n_dofs()+
5548  comp_dom.dh.n_dofs()+
5549  3+d,residual.fastAccessDx(d));
5550  for (unsigned int d=0; d<4; ++d)
5551  jacobian_matrix.add(3*i,comp_dom.vector_dh.n_dofs()+
5552  comp_dom.dh.n_dofs()+
5553  comp_dom.dh.n_dofs()+
5554  9+d,residual.fastAccessDx(3+d));
5555  }
5556 
5557  // we're doing this thing on the water side, but the iges_normal and iges_mean curvature belong to the boat side
5558  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
5559  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
5560  {
5561  comp_dom.iges_normals[*pos] = comp_dom.iges_normals[i];
5562  comp_dom.iges_mean_curvatures[*pos] = comp_dom.iges_mean_curvatures[i];
5563  }
5564  }
5565  }
5566 
5567  //this takes care of the left water line nodes projection (without smoothing)
5568  if (!comp_dom.no_boat)
5569  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5570  {
5571  fad_double s_x,s_y,s_z,v_x,v_y,v_z,s;
5572 
5573  s_x = hull_lin_displ(0);
5574  s_y = hull_lin_displ(1);
5575  s_z = hull_lin_displ(2);
5576  v_x = hull_quat_vector(0);
5577  v_y = hull_quat_vector(1);
5578  v_z = hull_quat_vector(2);
5579  s = hull_quat_scalar;
5580 
5581  s_x.diff(0,7);
5582  s_y.diff(1,7);
5583  s_z.diff(2,7);
5584  v_x.diff(3,7);
5585  v_y.diff(4,7);
5586  v_z.diff(5,7);
5587  s.diff(6,7);
5588 
5589  Point<3,fad_double> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
5590  comp_dom.boat_model.reference_hull_baricenter(1),
5591  comp_dom.boat_model.reference_hull_baricenter(2));
5592 
5593  Point<3,fad_double> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
5594  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
5595  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
5596 
5597  Point<3,fad_double> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
5598  Point<3,fad_double> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
5599  Point<3,fad_double> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
5600 
5601  if ( (comp_dom.flags[i] & water) &&
5602  (comp_dom.flags[i] & near_boat) &&
5603  (comp_dom.flags[i] & left_side) &&
5604  !(comp_dom.flags[i] & transom_on_water) &&
5605  (comp_dom.moving_point_ids[3] != i) &&
5606  (comp_dom.moving_point_ids[4] != i) &&
5607  (comp_dom.moving_point_ids[5] != i) &&
5608  (comp_dom.moving_point_ids[6] != i) ) // to avoid the bow and stern node
5609  {
5610  //cout<<"**** "<<i<<endl;
5611  Point<3> proj_node;
5612  Point<3> iges_normal;
5613  double iges_curvature;
5614  Point<3> direction(comp_dom.iges_normals[i](0),comp_dom.iges_normals[i](1),0.0);
5615  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
5616  direction(0) = 0.0;
5617  else
5618  direction(1) = 0.0;
5619  comp_dom.boat_model.boat_water_line_left->assigned_axis_projection_and_diff_forms(proj_node,
5620  comp_dom.iges_normals[i],
5621  comp_dom.iges_mean_curvatures[i],
5622  comp_dom.support_points[i],
5623  direction); // hor normal dir projection
5624  //comp_dom.boat_model.boat_water_line_left->axis_projection_and_diff_forms(proj_node,
5625  // comp_dom.iges_normals[i],
5626  // comp_dom.iges_mean_curvatures[i],
5627  // comp_dom.support_points[i]); // y axis projection
5628  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
5629  {
5630  working_map_points(3*i) = comp_dom.old_map_points(3*i); // x of the node must not change
5631  working_map_points(3*i+1) = proj_node(1) - comp_dom.ref_points[3*i](1);
5632  }
5633  else
5634  {
5635  working_map_points(3*i) = proj_node(0) - comp_dom.ref_points[3*i](0);
5636  working_map_points(3*i+1) = comp_dom.old_map_points(3*i+1); // y of the node must not change
5637  }
5638  working_map_points(3*i+2) = proj_node(2) - comp_dom.ref_points[3*i](2);
5639 
5640  // here we compute the derivatives: we are basically computing the same residual on the tangent plane, which
5641  // will have the same derivatives as the surface
5642  gp_Pnt ref_point(proj_node(0),proj_node(1),proj_node(2));
5643  ref_point.Transform(reference_to_current_transformation.Inverted());
5644  gp_Vec curr_normal(comp_dom.iges_normals[i](0),comp_dom.iges_normals[i](1),comp_dom.iges_normals[i](2));
5645  gp_Dir ref_normal_dir(curr_normal);
5646  ref_normal_dir.Transform(reference_to_current_transformation.Inverted());
5647 
5648  Point<3,fad_double> ref_point_pos(ref_point.X(),ref_point.Y(),ref_point.Z());
5649  Point<3,fad_double> rigid_lin_displ(s_x,s_y,s_z);
5650  Point<3,fad_double> target_point_pos(RotMatRow1*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5651  RotMatRow2*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5652  RotMatRow3*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos));
5653  target_point_pos += baricenter_pos;
5654  Point<3,fad_double> ref_normal(ref_normal_dir.X(),ref_normal_dir.Y(),ref_normal_dir.Z());
5655  Point<3,fad_double> target_point_normal(RotMatRow1*ref_normal,
5656  RotMatRow2*ref_normal,
5657  RotMatRow3*ref_normal);
5658  Point<3,fad_double> guessed_point(comp_dom.support_points[i](0),comp_dom.support_points[i](1),comp_dom.support_points[i](2));
5659 
5660  if (fabs(comp_dom.old_iges_normals[i](0))<sqrt(3)/3*fabs(comp_dom.old_iges_normals[i](1)))
5661  {
5662  fad_double residual = guessed_point(1)+
5663  target_point_normal(0)/target_point_normal(1)*(guessed_point(0)-target_point_pos(0))+
5664  target_point_normal(2)/target_point_normal(1)*(guessed_point(2)-target_point_pos(2))-
5665  target_point_pos(1);
5666 
5667  jacobian_matrix.add(3*i,3*i,1.0);
5668  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5669  jacobian_matrix.add(3*i+1,3*i+2,comp_dom.iges_normals[i](2)/comp_dom.iges_normals[i](1));
5670  jacobian_matrix.add(3*i+1,3*i,comp_dom.iges_normals[i](0)/comp_dom.iges_normals[i](1));
5671  for (unsigned int d=0; d<3; ++d)
5672  jacobian_matrix.add(3*i+1,comp_dom.vector_dh.n_dofs()+
5673  comp_dom.dh.n_dofs()+
5674  comp_dom.dh.n_dofs()+
5675  3+d,residual.fastAccessDx(d));
5676  for (unsigned int d=0; d<4; ++d)
5677  jacobian_matrix.add(3*i+1,comp_dom.vector_dh.n_dofs()+
5678  comp_dom.dh.n_dofs()+
5679  comp_dom.dh.n_dofs()+
5680  9+d,residual.fastAccessDx(3+d));
5681  }
5682  else
5683  {
5684  fad_double residual = guessed_point(0)+
5685  target_point_normal(1)/target_point_normal(0)*(guessed_point(1)-target_point_pos(1))+
5686  target_point_normal(2)/target_point_normal(0)*(guessed_point(2)-target_point_pos(2))-
5687  target_point_pos(1);
5688  jacobian_matrix.add(3*i,3*i,1.0);
5689  jacobian_matrix.add(3*i,3*i+2,comp_dom.iges_normals[i](2)/comp_dom.iges_normals[i](0));
5690  jacobian_matrix.add(3*i,3*i+1,comp_dom.iges_normals[i](1)/comp_dom.iges_normals[i](0));
5691  jacobian_matrix.add(3*i+1,3*i+1,1.0);
5692  for (unsigned int d=0; d<3; ++d)
5693  jacobian_matrix.add(3*i,comp_dom.vector_dh.n_dofs()+
5694  comp_dom.dh.n_dofs()+
5695  comp_dom.dh.n_dofs()+
5696  3+d,residual.fastAccessDx(d));
5697  for (unsigned int d=0; d<4; ++d)
5698  jacobian_matrix.add(3*i,comp_dom.vector_dh.n_dofs()+
5699  comp_dom.dh.n_dofs()+
5700  comp_dom.dh.n_dofs()+
5701  9+d,residual.fastAccessDx(3+d));
5702  }
5703  //cout<<i<<" "<<temp_src(3*i+1)<<" ("<<comp_dom.iges_normals[i]<<")"<<endl;
5704 
5705  // we're doing this thing on the water side, but the iges_normal and iges_mean curvature belong to the boat side
5706  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
5707  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
5708  {
5709  comp_dom.iges_normals[*pos] = comp_dom.iges_normals[i];
5710  comp_dom.iges_mean_curvatures[*pos] = comp_dom.iges_mean_curvatures[i];
5711  }
5712  }
5713  }
5714 
5715  //this takes care of the bow and stern nodes
5716  if (!comp_dom.no_boat)
5717  for (unsigned int k=3; k<7; ++k)
5718  {
5719  fad_double s_x,s_y,s_z,v_x,v_y,v_z,s;
5720 
5721  s_x = hull_lin_displ(0);
5722  s_y = hull_lin_displ(1);
5723  s_z = hull_lin_displ(2);
5724  v_x = hull_quat_vector(0);
5725  v_y = hull_quat_vector(1);
5726  v_z = hull_quat_vector(2);
5727  s = hull_quat_scalar;
5728 
5729  s_x.diff(0,7);
5730  s_y.diff(1,7);
5731  s_z.diff(2,7);
5732  v_x.diff(3,7);
5733  v_y.diff(4,7);
5734  v_z.diff(5,7);
5735  s.diff(6,7);
5736 
5737  Point<3,fad_double> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
5738  comp_dom.boat_model.reference_hull_baricenter(1),
5739  comp_dom.boat_model.reference_hull_baricenter(2));
5740 
5741  Point<3,fad_double> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
5742  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
5743  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
5744 
5745  Point<3,fad_double> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
5746  Point<3,fad_double> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
5747  Point<3,fad_double> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
5748 
5749  unsigned int i = comp_dom.moving_point_ids[k];
5750  //cout<<"Moving point id: "<<i<<endl;
5751  {
5752  Point <3> dP0 = comp_dom.support_points[i];
5753  Point <3> dP;
5754  //this is the horizontal plane
5755  Handle(Geom_Plane) horPlane = new Geom_Plane(0.,0.,1.,-dP0(2));
5756  Handle(Geom_Curve) curve;
5757  TopLoc_Location L = comp_dom.boat_model.current_loc;
5758  TopLoc_Location L_inv = L.Inverted();
5759  //gp_Pnt test_point(0.0,0.0,0.0);
5760  //test_point.Transform(L_inv.Transformation());
5761  //cout<<"####### "<<Pnt(test_point)<<endl;
5762  horPlane->Transform(L_inv.Transformation());
5763  if (comp_dom.boat_model.is_transom)
5764  {
5765  if (k==3 || k==4)
5766  curve = comp_dom.boat_model.equiv_keel_bspline;
5767  else if (k == 6)
5768  curve = comp_dom.boat_model.left_transom_bspline;
5769  else
5770  curve = comp_dom.boat_model.right_transom_bspline;
5771  }
5772  else
5773  {
5774  curve = comp_dom.boat_model.equiv_keel_bspline;
5775  }
5776 
5777  TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(curve);
5778  edge.Location(L);
5779  BRepAdaptor_Curve AC(edge);
5780  gp_Pnt P;
5781  gp_Vec V1;
5782  GeomAPI_IntCS Intersector(curve, horPlane);
5783  int npoints = Intersector.NbPoints();
5784 
5785  AssertThrow((npoints != 0), ExcMessage("Keel or transom curve is not intersecting with horizontal plane!"));
5786  double minDistance=1e7;
5787  double t,u,v;
5788  for (int j=0; j<npoints; ++j)
5789  {
5790  gp_Pnt int_point = Intersector.Point(j+1);
5791  int_point.Transform(L.Transformation());
5792  Point<3> inters = Pnt(int_point);
5793  Intersector.Parameters(j+1,u,v,t);
5794  if (dP0.distance(inters) < minDistance)
5795  {
5796  minDistance = dP0.distance(inters);
5797  dP = inters;
5798  AC.D1(t,P,V1);
5799  }
5800  }
5801 
5802 
5803 
5804  //cout<<"Check plane-curve intersection:"<<endl;
5805  //cout<<"Origin: "<<dP0<<" Proj: "<<dP<<" dist: "<<minDistance<<endl;
5806  //cout<<Pnt(P)<<endl;
5807  /*
5808  // here temporarily for kcs hull tests
5809  if (minDistance > 0.5*comp_dom.boat_model.boatWetLength)
5810  {
5811  Standard_Real First = curve->FirstParameter();
5812  Standard_Real Last = curve->LastParameter();
5813  gp_Pnt PIn(0.0,0.0,0.0);
5814  gp_Pnt PFin(0.0,0.0,0.0);
5815  gp_Vec VIn;
5816  gp_Vec VFin;
5817  curve->D1(First,PIn,VIn);
5818  curve->D1(Last,PFin,VFin);
5819  cout<<"New part one: "<<Pnt(PIn)<<" | "<<Pnt(PFin)<<endl;
5820  if (dP0.distance(Pnt(PIn)) < dP0.distance(Pnt(PFin)))
5821  {
5822  double delta_z = dP0(2) - PIn.Z();
5823  dP = Point<3>(PIn.X()+delta_z*VIn.X()/VIn.Z(),PIn.Y()+delta_z*VIn.Y()/VIn.Z(),dP0(2));
5824  V1 = VIn;
5825  }
5826  else
5827  {
5828  double delta_z = dP0(2) - PFin.Z();
5829  dP = Point<3>(PFin.X()+delta_z*VFin.X()/VFin.Z(),PIn.Y()+delta_z*VFin.Y()/VFin.Z(),dP0(2));
5830  V1 = VFin;
5831  }
5832  cout<<"New part two: "<<dP<<" | "<<V1.X()<<" "<<V1.Y()<<" "<<V1.Z()<<" | "<<dP0<<endl;
5833  }
5834  */
5835  //cout<<k<<"("<<i<<") ---> ("<<dP0<<") vs ("<<dP<<")"<<endl;
5836  working_map_points(3*i) = dP(0)-comp_dom.ref_points[3*i](0);
5837  working_map_points(3*i+1) = dP(1)-comp_dom.ref_points[3*i](1);
5838  working_map_points(3*i+2) = dP(2)-comp_dom.ref_points[3*i](2);
5839  comp_dom.edges_tangents[3*i] = V1.X();
5840  comp_dom.edges_tangents[3*i+1] = V1.Y();
5841  comp_dom.edges_tangents[3*i+2] = V1.Z();
5842 
5843  // here we compute the derivatives: we are basically computing the same residual on the tangent plane, which
5844  // will have the same derivatives as the surface
5845  gp_Pnt ref_point(dP(0),dP(1),dP(2));
5846  ref_point.Transform(reference_to_current_transformation.Inverted());
5847  gp_Vec curr_tangent(V1.X(),V1.Y(),V1.Z());
5848  gp_Dir ref_tangent_dir(curr_tangent);
5849  ref_tangent_dir.Transform(reference_to_current_transformation.Inverted());
5850 
5851  Point<3,fad_double> ref_point_pos(ref_point.X(),ref_point.Y(),ref_point.Z());
5852  Point<3,fad_double> rigid_lin_displ(s_x,s_y,s_z);
5853  Point<3,fad_double> target_point_pos(RotMatRow1*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5854  RotMatRow2*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos),
5855  RotMatRow3*(ref_point_pos+(fad_double(-1.0))*ref_baricenter_pos));
5856  target_point_pos += baricenter_pos;
5857 
5858  Point<3,fad_double> ref_tangent(ref_tangent_dir.X(),ref_tangent_dir.Y(),ref_tangent_dir.Z());
5859  Point<3,fad_double> target_point_tangent(RotMatRow1*ref_tangent,
5860  RotMatRow2*ref_tangent,
5861  RotMatRow3*ref_tangent);
5862 
5863  Point<3,fad_double> guessed_point(comp_dom.support_points[i](0),comp_dom.support_points[i](1),comp_dom.support_points[i](2));
5864 
5865  fad_double residual_x = guessed_point(0) -
5866  target_point_tangent(0)/target_point_tangent(2)*(guessed_point(2)-target_point_pos(2)) -
5867  target_point_pos(0);
5868  fad_double residual_y = guessed_point(1) -
5869  target_point_tangent(1)/target_point_tangent(2)*(guessed_point(2)-target_point_pos(2)) -
5870  target_point_pos(1);
5871 
5872 
5873  //cout<<"oooyooo "<<comp_dom.map_points(3*i+1)-working_map_points(3*i+1)<<" vs "<<residual_y.val()<<" --> "
5874  // <<comp_dom.map_points(3*i+1)-working_map_points(3*i+1)-residual_y.val()<<endl;
5875 
5876  jacobian_matrix.set(3*i,3*i,1.0);
5877 
5878  jacobian_matrix.set(3*i,3*i+2,-comp_dom.edges_tangents(3*i)/comp_dom.edges_tangents(3*i+2));
5879 
5880  for (unsigned int d=0; d<3; ++d)
5881  jacobian_matrix.set(3*i,comp_dom.vector_dh.n_dofs()+
5882  comp_dom.dh.n_dofs()+
5883  comp_dom.dh.n_dofs()+
5884  3+d,residual_x.fastAccessDx(d));
5885  for (unsigned int d=0; d<4; ++d)
5886  jacobian_matrix.set(3*i,comp_dom.vector_dh.n_dofs()+
5887  comp_dom.dh.n_dofs()+
5888  comp_dom.dh.n_dofs()+
5889  9+d,residual_x.fastAccessDx(3+d));
5890  jacobian_matrix.set(3*i+1,3*i+1,1.0);
5891  jacobian_matrix.set(3*i+1,3*i+2,-comp_dom.edges_tangents(3*i+1)/comp_dom.edges_tangents(3*i+2));
5892  for (unsigned int d=0; d<3; ++d)
5893  jacobian_matrix.set(3*i+1,comp_dom.vector_dh.n_dofs()+
5894  comp_dom.dh.n_dofs()+
5895  comp_dom.dh.n_dofs()+
5896  3+d,residual_y.fastAccessDx(d));
5897  for (unsigned int d=0; d<4; ++d)
5898  jacobian_matrix.set(3*i+1,comp_dom.vector_dh.n_dofs()+
5899  comp_dom.dh.n_dofs()+
5900  comp_dom.dh.n_dofs()+
5901  9+d,residual_y.fastAccessDx(3+d));
5902  //cout<<i<<" (point) "<<comp_dom.support_points[i]<<endl;
5903  //cout<<i<<" (edges_tangents) "<<comp_dom.edges_tangents(3*i)<<","<<comp_dom.edges_tangents(3*i+1)<<","<<comp_dom.edges_tangents(3*i+2)<<endl;
5904  }
5905  }
5906 
5907  // this cycle hooks the boat and far field double nodes
5908  // to their water twins that have been moved
5909  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
5910  {
5911  if ( (comp_dom.flags[i] & water) &&
5912  (comp_dom.flags[i] & edge) )
5913  {
5914  fad_double s_x,s_y,s_z,v_x,v_y,v_z,s;
5915 
5916  s_x = hull_lin_displ(0);
5917  s_y = hull_lin_displ(1);
5918  s_z = hull_lin_displ(2);
5919  v_x = hull_quat_vector(0);
5920  v_y = hull_quat_vector(1);
5921  v_z = hull_quat_vector(2);
5922  s = hull_quat_scalar;
5923 
5924  s_x.diff(0,10);
5925  s_y.diff(1,10);
5926  s_z.diff(2,10);
5927  v_x.diff(3,10);
5928  v_y.diff(4,10);
5929  v_z.diff(5,10);
5930  s.diff(6,10);
5931 
5932  fad_double map_x,map_y,map_z;
5933 
5934  map_x = nodes_positions(3*i);
5935  map_y = nodes_positions(3*i+1);
5936  map_z = nodes_positions(3*i+2);
5937 
5938  map_x.diff(7,10);
5939  map_y.diff(8,10);
5940  map_z.diff(9,10);
5941 
5942  Point<3,fad_double> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
5943  comp_dom.boat_model.reference_hull_baricenter(1),
5944  comp_dom.boat_model.reference_hull_baricenter(2));
5945 
5946  Point<3,fad_double> baricenter_pos(s_x+comp_dom.boat_model.reference_hull_baricenter(0),
5947  s_y+comp_dom.boat_model.reference_hull_baricenter(1),
5948  s_z+comp_dom.boat_model.reference_hull_baricenter(2));
5949 
5950  Point<3,fad_double> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
5951  Point<3,fad_double> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
5952  Point<3,fad_double> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
5953 
5954  gp_Pnt original_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.old_map_points(3*i),
5955  comp_dom.ref_points[3*i](1)+comp_dom.old_map_points(3*i+1),
5956  comp_dom.ref_points[3*i](2)+comp_dom.old_map_points(3*i+2)));
5957  gp_Pnt boat_mesh_point = original_boat_mesh_point;
5958  // we first take this point (which is in the RESTART hull location) and transform it to be in the
5959  // REFERENCE configuration
5960  boat_mesh_point.Transform(restart_hull_location.Inverted());
5961 
5962  Point<3,fad_double> pp_orig_ref(boat_mesh_point.X(),boat_mesh_point.Y(),boat_mesh_point.Z());
5963 
5964  Point<3,fad_double> map_p_transf_ref(RotMatRow1*(pp_orig_ref+(fad_double(-1.0))*ref_baricenter_pos)+s_x-boat_mesh_point.X()+map_x,
5965  RotMatRow2*(pp_orig_ref+(fad_double(-1.0))*ref_baricenter_pos)+s_y-boat_mesh_point.Y()+map_y,
5966  RotMatRow3*(pp_orig_ref+(fad_double(-1.0))*ref_baricenter_pos)+s_z-boat_mesh_point.Z()+map_z);
5967 
5968 
5969  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
5970  duplicates.erase(i);
5971  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
5972  {
5973  //cout<<*pos<<"("<<i<<") "<<comp_dom.map_points(i)<<" vs "<<comp_dom.map_points(*pos)<<" diff "<<comp_dom.map_points(i)-comp_dom.map_points(*pos)<<endl;
5974  for (unsigned int k=0; k<3; k++)
5975  {
5976  working_map_points(3*(*pos)+k) = comp_dom.map_points(3*i+k);
5977 
5978  jacobian_matrix.add(3*(*pos)+k,3*(*pos)+k,1.0);
5979  if (comp_dom.flags[i] & transom_on_water)
5980  {
5981 
5982  for (unsigned int d=0; d<3; d++)
5983  jacobian_matrix.add(3*(*pos)+k,3*i+d,-map_p_transf_ref(k).fastAccessDx(7+d));
5984 
5985  for (unsigned int d=0; d<3; d++)
5986  jacobian_matrix.add(3*(*pos)+k,comp_dom.vector_dh.n_dofs()+
5987  comp_dom.dh.n_dofs()+
5988  comp_dom.dh.n_dofs()+3+d,-map_p_transf_ref(k).fastAccessDx(d));
5989 
5990  for (unsigned int d=0; d<4; d++)
5991  jacobian_matrix.add(3*(*pos)+k,comp_dom.vector_dh.n_dofs()+
5992  comp_dom.dh.n_dofs()+
5993  comp_dom.dh.n_dofs()+9+d,-map_p_transf_ref(k).fastAccessDx(d+3));
5994  }
5995  else
5996  {
5997  jacobian_matrix.add(3*(*pos)+k,3*i+k,-1.0);
5998  }
5999  }
6000  }
6001  }
6002  }
6003 
6004 
6005  nodes_pos_res = working_map_points;
6006  nodes_pos_res*=-1;
6007  nodes_pos_res.add(comp_dom.map_points);
6008 
6009  //cout<<"?? "<<nodes_pos_res(1674)<<" ("<<comp_dom.map_points(1674)<<" vs "<<working_map_points(1674)<<")"<<endl;
6010 
6011 
6012 
6014  // here we take care of the bem part of the variables
6016  //cout<<"BEFORE "<<endl;
6017  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
6018  // if (constraints.is_constrained(i))
6019  // cout<<i<<" "<<src_yy(i+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs())<<endl;
6020 
6021  bem_phi = (const Vector<double> &)phi;
6022  constraints.distribute(bem_phi);
6023 
6024  bem_dphi_dn = (const Vector<double> &)dphi_dn;
6025  constraints.distribute(bem_dphi_dn);
6026 
6027  //cout<<"AFTER "<<endl;
6028  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
6029  // if (constraints.is_constrained(i))
6030  // cout<<i<<" "<<src_yy(i+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs())<<endl;
6031 
6032 
6033  Vector<double> bem_bc(comp_dom.dh.n_dofs());
6034  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
6035  {
6036  if ((comp_dom.flags[i] & water) ||
6037  (comp_dom.flags[i] & pressure) )
6038  bem_bc(i) = phi(i);
6039  else
6040  bem_bc(i) = dphi_dn(i);
6041  }
6042 
6043  // trying a fix for transom stern nodes
6044  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
6045  {
6046  if ( comp_dom.flags[i] & transom_on_water )
6047  {
6048  comp_dom.surface_nodes(i) = 0;
6049  comp_dom.other_nodes(i) = 1;
6050  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
6051  duplicates.erase(i);
6052  bem_bc(i) = 0;
6053  jacobian_matrix.add(i+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),
6054  i+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),
6055  -1.0);
6056  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
6057  {
6058  bem_bc(i) += bem_dphi_dn(*pos)/duplicates.size();
6059  jacobian_matrix.add(i+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),
6060  *pos+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),
6061  1.0/duplicates.size());
6062  }
6063  bem_dphi_dn(i) = bem_bc(i);
6064  }
6065  }
6066  // trying a fix for water/pressure nodes (pressure side)
6067  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
6068  {
6069  if ( (comp_dom.flags[i] & pressure) && (comp_dom.flags[i] & near_water) )
6070  {
6071  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
6072  duplicates.erase(i);
6073  //cout<<i<<" "<<bem_bc(i)<<" "<<phi(i)<<" "<<dphi_dn(i)<<endl;
6074  unsigned int count=0;
6075  bem_bc(i) = 0;
6076  jacobian_matrix.add(i+comp_dom.vector_dh.n_dofs(),
6077  i+comp_dom.vector_dh.n_dofs(),
6078  -1.0);
6079  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
6080  if (comp_dom.flags[*pos] & water)
6081  count++;
6082 
6083  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
6084  {
6085  if (comp_dom.flags[*pos] & water)
6086  {
6087  bem_bc(i) += phi(*pos)/count;
6088  //cout<<*pos<<" ("<<i<<") "<<bem_bc(i)<<" "<<phi(*pos)<<" "<<dphi_dn(*pos)<<" ? "<<count<<endl;
6089  jacobian_matrix.add(i+comp_dom.vector_dh.n_dofs(),
6090  *pos+comp_dom.vector_dh.n_dofs(),
6091  1.0/count);
6092  }
6093  }
6094  bem_phi(i) = bem_bc(i);
6095  }
6096  }
6097 
6098 
6099  if ( (sync_bem_with_geometry == true) || (new_time_step) )
6100  {
6101  //bem.assemble_system();
6102  //bem.residual(bem_residual, phi, dphi_dn);
6103  bem.solve(bem_phi, bem_dphi_dn, bem_bc);
6104  }
6105  else
6106  {
6107  //bem.residual(bem_residual, phi, dphi_dn);
6108  bem.solve_system(bem_phi, bem_dphi_dn, bem_bc);
6109  }
6110 
6111 
6112  // this is to enforce constraints in a more strict way
6113  // the vector given back by bem has constraints
6114  // imposed up to the bem GMRES tolerance
6115  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
6116  {
6117  if ( constraints.is_constrained(i))
6118  {
6119  bem_phi(i) = 0;
6120  bem_dphi_dn(i) = 0;
6121  std::vector< std::pair< unsigned int, double > > entries = *constraints.get_constraint_entries(i);
6122  for (unsigned int k=0; k<entries.size(); ++k)
6123  {
6124  bem_phi(i) += entries[k].second*phi(entries[k].first);
6125  bem_dphi_dn(i) += entries[k].second*dphi_dn(entries[k].first);
6126  }
6127  }
6128  }
6129 
6130 
6132  // here we compute eta_dry (just for a check)
6133  Vector<double> wind_valuee(dim);
6134  wind.vector_value(Point<3>(0.0,0.0,0.0),wind_valuee);
6135  Point<dim> Vinff;
6136  for (unsigned int i = 0; i < dim; i++)
6137  Vinff(i) = wind_valuee(i);
6138  double eta_dryy = 1.0;
6139  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom && sqrt(Vinff*Vinff) > 0.0)
6140  {
6141  double transom_beamm = comp_dom.boat_model.CurrentPointRightTransom(1) - comp_dom.boat_model.CurrentPointLeftTransom(1);
6142  double transom_draftt = -comp_dom.boat_model.CurrentPointCenterTransom(2);
6143  double transom_aspect_ratioo = transom_beamm/transom_draftt;
6144  //cout<<restart_transom_right_tangent<<endl;
6145  //cout<<"b: "<<transom_beam.val()<<" d:"<<transom_draft.val()<<" "<<"AR: "<<transom_aspect_ratio.val()<<endl;
6146  double FrTr = sqrt(Vinff*Vinff)/sqrt(9.81*transom_draftt);
6147  double ReTr = sqrt(9.81*pow(transom_draftt,3.0))/1.307e-6;
6148  eta_dryy = 0.05*pow(FrTr,2.834)*pow(transom_aspect_ratioo,0.1352)*pow(ReTr,0.01338);
6149  if (eta_dryy > 1.0)
6150  eta_dryy = 1.0;
6151 
6152  cout<<"Current eta_dry: "<<eta_dryy<<endl;
6153  }
6154 
6156  // here we take care of the free surface boundary condition (differential)
6157  // part of the variables, and the boat neumann condition variables
6159 
6160 
6161 
6162 // building reference cell
6163  Triangulation<2> ref_triangulation;
6164 
6165  std::vector<Point<2> > ref_vertices;
6166  std::vector<CellData<2> > ref_cells;
6167  SubCellData ref_subcelldata;
6168 
6169  ref_vertices.resize(4);
6170  ref_vertices[0](0)= 0.0;
6171  ref_vertices[0](1)= 0.0; //ref_vertices[0](2)=0.0;
6172  ref_vertices[1](0)= 1.0;
6173  ref_vertices[1](1)= 0.0; //ref_vertices[1](2)=0.0;
6174  ref_vertices[2](0)= 0.0;
6175  ref_vertices[2](1)= 1.0; //ref_vertices[2](2)=0.0;
6176  ref_vertices[3](0)= 1.0;
6177  ref_vertices[3](1)= 1.0; //ref_vertices[3](2)=0.0;
6178 
6179  ref_cells.resize(1);
6180 
6181  ref_cells[0].vertices[0]=0;
6182  ref_cells[0].vertices[1]=1;
6183  ref_cells[0].vertices[2]=3;
6184  ref_cells[0].vertices[3]=2;
6185  ref_cells[0].material_id = 1;
6186 
6187  GridTools::delete_unused_vertices (ref_vertices, ref_cells, ref_subcelldata);
6189 
6190  ref_triangulation.create_triangulation_compatibility(ref_vertices, ref_cells, ref_subcelldata );
6191 
6192  FE_Q<2> fe(1);
6193 
6194 
6195  DoFHandler<2> ref_dh(ref_triangulation);
6196  ref_dh.distribute_dofs(fe);
6197 
6198  FEValues<2> ref_fe_v(StaticMappingQ1<2>::mapping, fe, *comp_dom.quadrature,
6199  update_values | update_gradients |
6200  update_quadrature_points |
6201  update_JxW_values);
6202 
6203  const unsigned int n_q_points = ref_fe_v.n_quadrature_points;
6204  const unsigned int dofs_per_cell = fe.dofs_per_cell;
6205 
6206  //typedef typename DoFHandler<dim-1,dim>::active_cell_iterator cell_it;
6207  //typedef typename Triangulation<dim-1,dim>::active_cell_iterator tria_it;
6209  ref_fe_v.reinit(ref_cell);
6210 
6212 
6213 // test: let's try assemble actual mass matrix
6214  double g = 9.81;
6215  DphiDt_sys_matrix = 0;
6216  DphiDt_sys_solution = 0;
6217  DphiDt_sys_solution_2 = 0;
6218  DphiDt_sys_solution_3 = 0;
6219  DphiDt_sys_rhs = 0;
6220  DphiDt_sys_rhs_2 = 0;
6221  DphiDt_sys_rhs_3 = 0;
6222  DphiDt_sys_rhs_4 = 0;
6223 
6224 
6225 //let's build the residual on the free surface cells (differential components)
6226  std::vector<double> eta_res(comp_dom.dh.n_dofs(),0.0);
6227  std::vector<double> phi_res(comp_dom.dh.n_dofs(),0.0);
6228  std::vector<double> dphi_dn_res(comp_dom.dh.n_dofs(),0.0);
6229  std::vector<double> x_smoothing_res(comp_dom.dh.n_dofs(),0.0);
6230  std::vector<double> y_smoothing_res(comp_dom.dh.n_dofs(),0.0);
6231 // we'll need Vinf
6232  Vector<double> wind_value(dim);
6233  wind.vector_value(Point<3>(0.0,0.0,0.0),wind_value);
6234  Point<dim> Vinf;
6235  for (unsigned int i = 0; i < dim; i++)
6236  Vinf(i) = wind_value(i);
6237 
6238  double amplitude = 0.02;
6239  double rho = 1025.1;
6240  double ref_height;
6241  double Fn;
6242  if (comp_dom.no_boat)
6243  {
6244  Fn = Vinf(0)/sqrt(max_z_coor_value*g);
6245  ref_height = amplitude;
6246  }
6247  else
6248  {
6249  ref_height = fabs(comp_dom.boat_model.PointMidBot(2));
6250  Fn = Vinf(0)/sqrt(comp_dom.boat_model.boatWetLength*g);
6251  }
6252 
6253  //this is to assign correct values to the (possible) exact pressure to be used in pressure boundary condition
6254  Vector <double> ex_press(comp_dom.dh.n_dofs());
6255  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
6256  {
6257  if (comp_dom.flags[i] & pressure && !(comp_dom.flags[i] & near_water) )
6258  {
6259  double k=0.62994;
6260  double omega=2.4835;
6261  double h=5.5;
6262  double a=0.00;
6263  double time_factor = 1.0;
6264  double time_factor_deriv = 0.0;
6265  double ramp_length = 20.0;
6266  if (t<ramp_length)
6267  {
6268  time_factor = 0.5*sin(3.141592654*(t)/ramp_length-3.141592654/2)+0.5;
6269  time_factor_deriv = 0.5*3.141592654/ramp_length*cos(3.141592654*(t)/ramp_length-3.141592654/2);
6270  }
6271  double dphi_dt = omega*omega*a/k*cosh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*cos(k*comp_dom.support_points[i](0)+omega*t)*time_factor +
6272  omega*a/k*cosh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*sin(k*comp_dom.support_points[i](0)+omega*t)*time_factor_deriv;
6273  Point<3> grad_phi(omega*a*cosh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*cos(k*comp_dom.support_points[i](0)+omega*t)*time_factor,
6274  0.0*time_factor,
6275  omega*a*sinh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*sin(k*comp_dom.support_points[i](0)+omega*t)*time_factor);
6276 
6277 
6278 
6279  ex_press(i) = ( -dphi_dt - 0.5*(grad_phi*grad_phi) -
6280  grad_phi(0)*instantWindValue(0)-grad_phi(1)*instantWindValue(1)-grad_phi(2)*instantWindValue(2) -
6281  comp_dom.support_points[i](2)*g ) * rho;
6282  }
6283  }
6284 
6285 
6286  FullMatrix<double> local_DphiDt_matrix (dofs_per_cell, dofs_per_cell);
6287  FullMatrix<double> local_DphiDt_matrix_2 (dofs_per_cell, dofs_per_cell);
6288  Vector<double> local_DphiDt_rhs (dofs_per_cell);
6289  Vector<double> local_DphiDt_rhs_2 (dofs_per_cell);
6290  Vector<double> local_DphiDt_rhs_3 (dofs_per_cell);
6291  Vector<double> local_DphiDt_rhs_4 (dofs_per_cell);
6292 
6293  cell_it
6294  cell = comp_dom.dh.begin_active(),
6295  endc = comp_dom.dh.end();
6296 
6297  std::vector<fad_double> ref_coors(3*dofs_per_cell);
6298  std::vector<fad_double> coors(3*dofs_per_cell);
6299  std::vector<fad_double> phis(dofs_per_cell);
6300  std::vector<fad_double> dphi_dns(dofs_per_cell);
6301  std::vector<fad_double> ref_coors_dot(3*dofs_per_cell);
6302  std::vector<fad_double> coors_dot(3*dofs_per_cell);
6303  std::vector<fad_double> phis_dot(dofs_per_cell);
6304  std::vector<fad_double> dphi_dns_dot(dofs_per_cell);
6305  std::vector<fad_double> x_displs(dofs_per_cell);
6306  std::vector<fad_double> y_displs(dofs_per_cell);
6307 
6308  std::vector<fad_double> hull_baricenter_displ(3);
6309  std::vector<fad_double> hull_baricenter_vel(3);
6310  std::vector<fad_double> hull_quaternion(4);
6311  std::vector<fad_double> hull_omega(3);
6312 
6313  std::vector<fad_double> loc_eta_res(dofs_per_cell);
6314  std::vector<fad_double> loc_phi_res(dofs_per_cell);
6315  std::vector<fad_double> loc_dphi_dn_res(dofs_per_cell);
6316  std::vector<fad_double> loc_x_smooth_res(dofs_per_cell);
6317  std::vector<fad_double> loc_y_smooth_res(dofs_per_cell);
6318  Point<3,fad_double> loc_pressure_force;
6319  Point<3,fad_double> loc_pressure_moment;
6320  Point<3> pressure_force(0.0,0.0,0.0);
6321  Point<3> pressure_moment(0.0,0.0,0.0);
6322 
6323  std::vector< std::vector<fad_double> > loc_stiffness_matrix(dofs_per_cell);
6324  std::vector< std::vector<fad_double> > loc_mass_matrix(dofs_per_cell);
6325  std::vector< std::vector<fad_double> > loc_supg_mass_matrix(dofs_per_cell);
6326 
6327  for (unsigned int i=0; i<dofs_per_cell; ++i)
6328  {
6329  loc_stiffness_matrix[i].resize(dofs_per_cell);
6330  loc_mass_matrix[i].resize(dofs_per_cell);
6331  loc_supg_mass_matrix[i].resize(dofs_per_cell);
6332  }
6333 
6334  std::vector<Point<dim> > initial_support_points(comp_dom.dh.n_dofs());
6335  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
6336  {
6337  initial_support_points[i] = Point<3>(comp_dom.ref_points[3*i](0)+comp_dom.initial_map_points(3*i),
6338  comp_dom.ref_points[3*i](1)+comp_dom.initial_map_points(3*i+1),
6339  comp_dom.ref_points[3*i](2)+comp_dom.initial_map_points(3*i+2));
6340  }
6341 
6342 
6343  std::vector<unsigned int> local_dof_indices(dofs_per_cell);
6344 
6345 
6346  for (; cell!=endc; ++cell)
6347  {
6348 
6349  //if (cell->material_id() == comp_dom.free_sur_ID1 ||
6350  // cell->material_id() == comp_dom.free_sur_ID2 ||
6351  // cell->material_id() == comp_dom.free_sur_ID3 ||
6352  // cell->material_id() == comp_dom.wall_sur_ID1 ||
6353  // cell->material_id() == comp_dom.wall_sur_ID2 ||
6354  // cell->material_id() == comp_dom.wall_sur_ID3 )
6355  {
6356  //if (fabs(t-0.005) < 1e-4)
6357  //std::cout<<std::endl;
6358  //std::cout<<"Cell: "<<cell<<std::endl;
6359 
6360  local_DphiDt_matrix = 0;
6361  local_DphiDt_matrix_2 = 0;
6362  local_DphiDt_rhs = 0;
6363  local_DphiDt_rhs_2 = 0;
6364  local_DphiDt_rhs_3 = 0;
6365  local_DphiDt_rhs_4 = 0;
6366 
6367  loc_pressure_force = Point<3,fad_double>(0.0,0.0,0.0);
6368  loc_pressure_moment = Point<3,fad_double>(0.0,0.0,0.0);
6369 
6370  cell->get_dof_indices(local_dof_indices);
6371  for (unsigned int i=0; i<dofs_per_cell; ++i)
6372  {
6373  loc_eta_res[i] = 0;
6374  loc_phi_res[i] = 0;
6375  loc_dphi_dn_res[i] = 0;
6376  loc_x_smooth_res[i] = 0;
6377  loc_y_smooth_res[i] = 0;
6378  for (unsigned int j=0; j<dofs_per_cell; ++j)
6379  {
6380  loc_mass_matrix[i][j] = 0;
6381  loc_supg_mass_matrix[i][j] = 0;
6382  loc_stiffness_matrix[i][j] = 0;
6383  }
6384  //cout<<local_dof_indices[i]<<" ";
6385  }
6386  /*
6387  for (unsigned int i=0; i<dofs_per_cell; ++i)
6388  {
6389  if (local_dof_indices[i]== 44)
6390  {
6391  cout<<"44!!: "<<cell<<endl;
6392  for (unsigned int k=0; k<dofs_per_cell; ++k)
6393  {
6394  for (unsigned int j=0; j<3; ++j)
6395  {
6396  cout<<3*local_dof_indices[k]+j<<" ";
6397  }
6398  cout<<local_dof_indices[k]+comp_dom.vector_dh.n_dofs()<<" ";
6399  cout<<local_dof_indices[k]+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()<<" ";
6400  }
6401  cout<<endl;
6402  }
6403  }
6404  */
6405 
6406  for (unsigned int j=0; j<3; ++j)
6407  {
6408  hull_baricenter_vel[j] = hull_lin_vel(j);
6409  hull_baricenter_displ[j] = hull_lin_displ(j);
6410  hull_omega[j] = hull_ang_vel(j);
6411  hull_quaternion[j] = hull_quat_vector(j);
6412  hull_baricenter_vel[j].diff(10*dofs_per_cell+j,10*dofs_per_cell+13);
6413  hull_baricenter_displ[j].diff(10*dofs_per_cell+3+j,10*dofs_per_cell+13);
6414  hull_omega[j].diff(10*dofs_per_cell+6+j,10*dofs_per_cell+13);
6415  hull_quaternion[j].diff(10*dofs_per_cell+9+j,10*dofs_per_cell+13);
6416  }
6417  hull_quaternion[3] = hull_quat_scalar;
6418  hull_quaternion[3].diff(10*dofs_per_cell+12,10*dofs_per_cell+13);
6419 
6420  Point<3,fad_double> ref_baricenter_pos(comp_dom.boat_model.reference_hull_baricenter(0),
6421  comp_dom.boat_model.reference_hull_baricenter(1),
6422  comp_dom.boat_model.reference_hull_baricenter(2));
6423 
6424  Point<3,fad_double> baricenter_pos(hull_baricenter_displ[0]+comp_dom.boat_model.reference_hull_baricenter(0),
6425  hull_baricenter_displ[1]+comp_dom.boat_model.reference_hull_baricenter(1),
6426  hull_baricenter_displ[2]+comp_dom.boat_model.reference_hull_baricenter(2));
6427 
6428  Point<3,fad_double> RotMatRow1(1-2*hull_quaternion[1]*hull_quaternion[1]-2*hull_quaternion[2]*hull_quaternion[2],
6429  2*hull_quaternion[0]*hull_quaternion[1]-2*hull_quaternion[3]*hull_quaternion[2],
6430  2*hull_quaternion[0]*hull_quaternion[2]+2*hull_quaternion[3]*hull_quaternion[1]);
6431  Point<3,fad_double> RotMatRow2(2*hull_quaternion[0]*hull_quaternion[1]+2*hull_quaternion[3]*hull_quaternion[2],
6432  1-2*hull_quaternion[0]*hull_quaternion[0]-2*hull_quaternion[2]*hull_quaternion[2],
6433  2*hull_quaternion[1]*hull_quaternion[2]-2*hull_quaternion[3]*hull_quaternion[0]);
6434  Point<3,fad_double> RotMatRow3(2*hull_quaternion[0]*hull_quaternion[2]-2*hull_quaternion[3]*hull_quaternion[1],
6435  2*hull_quaternion[1]*hull_quaternion[2]+2*hull_quaternion[3]*hull_quaternion[0],
6436  1-2*hull_quaternion[1]*hull_quaternion[1]-2*hull_quaternion[0]*hull_quaternion[0]);
6437 
6438 
6439  for (unsigned int i=0; i<dofs_per_cell; ++i)
6440  if ( ((comp_dom.flags[local_dof_indices[i]] & boat) &&
6441  !(comp_dom.flags[local_dof_indices[i]] & near_water) ) ||
6442  (comp_dom.flags[local_dof_indices[i]] & transom_on_water) )
6443  {
6444  Point<3> reference_point_position(comp_dom.ref_points[3*local_dof_indices[i]](0)+
6445  comp_dom.map_points(3*local_dof_indices[i])-
6446  comp_dom.rigid_motion_map_points(3*local_dof_indices[i]),
6447  comp_dom.ref_points[3*local_dof_indices[i]](1)+
6448  comp_dom.map_points(3*local_dof_indices[i]+1)-
6449  comp_dom.rigid_motion_map_points(3*local_dof_indices[i]+1),
6450  comp_dom.ref_points[3*local_dof_indices[i]](2)+
6451  comp_dom.map_points(3*local_dof_indices[i]+2)-
6452  comp_dom.rigid_motion_map_points(3*local_dof_indices[i]+2));
6453 
6454  for (unsigned int j=0; j<3; ++j)
6455  {
6456  ref_coors[3*i+j] = reference_point_position(j);
6457  (ref_coors[3*i+j]).diff(3*i+j,10*dofs_per_cell+13);
6458 
6459  //cout<<"TESTTTTTT:::: "<<coors[3*i+j]-comp_dom.support_points[local_dof_indices[i]](j)<<endl;
6460  ref_coors_dot[3*i+j] = nodes_velocities(3*local_dof_indices[i]+j);
6461  (ref_coors_dot[3*i+j]).diff(3*i+j+5*dofs_per_cell,10*dofs_per_cell+13);
6462  }
6463  Point<3,fad_double> sacado_orig_point(ref_coors[3*i],ref_coors[3*i+1],ref_coors[3*i+2]);
6464  Point<3,fad_double> sacado_curr_point(RotMatRow1*(sacado_orig_point+(fad_double(-1.0))*ref_baricenter_pos)+
6465  baricenter_pos(0),
6466  RotMatRow2*(sacado_orig_point+(fad_double(-1.0))*ref_baricenter_pos)+
6467  baricenter_pos(1),
6468  RotMatRow3*(sacado_orig_point+(fad_double(-1.0))*ref_baricenter_pos)+
6469  baricenter_pos(2));
6470  //cout<<"Orig: "<<sacado_orig_point<<endl;//(0)<<" "<<sacado_orig_point(1).val()<<" "<<sacado_orig_point(2).val()<<endl;
6471  //cout<<"Point "<<local_dof_indices[i]<<endl;
6472  //cout<<"Curr sacado: "<<sacado_curr_point(0).val()<<" "<<sacado_curr_point(1).val()<<" "<<sacado_curr_point(2).val()<<endl;
6473  //cout<<"Curr true: "<<comp_dom.ref_points[3*local_dof_indices[i]](0)+comp_dom.map_points(3*local_dof_indices[i])+comp_dom.rigid_motion_map_points(3*local_dof_indices[i])<<" "
6474  // <<comp_dom.ref_points[3*local_dof_indices[i]](1)+comp_dom.map_points(3*local_dof_indices[i]+1)+comp_dom.rigid_motion_map_points(3*local_dof_indices[i]+1)<<" "
6475  // <<comp_dom.ref_points[3*local_dof_indices[i]](2)+comp_dom.map_points(3*local_dof_indices[i]+2)+comp_dom.rigid_motion_map_points(3*local_dof_indices[i]+2)<<endl;
6476  //cout<<"Mismatch: "<<comp_dom.ref_points[3*local_dof_indices[i]](0)+comp_dom.map_points(3*local_dof_indices[i])-sacado_curr_point(0).val()<<" "
6477  // <<comp_dom.ref_points[3*local_dof_indices[i]](1)+comp_dom.map_points(3*local_dof_indices[i]+1)-sacado_curr_point(1).val()<<" "
6478  // <<comp_dom.ref_points[3*local_dof_indices[i]](2)+comp_dom.map_points(3*local_dof_indices[i]+2)-sacado_curr_point(2).val()<<endl;
6479 
6480  gp_Pnt original_target_boat_mesh_point = Pnt(Point<3>(comp_dom.ref_points[3*local_dof_indices[i]](0)+comp_dom.old_map_points(3*i),
6481  comp_dom.ref_points[3*local_dof_indices[i]](1)+comp_dom.old_map_points(3*i+1),
6482  comp_dom.ref_points[3*local_dof_indices[i]](2)+comp_dom.old_map_points(3*i+2)));
6483  gp_Pnt target_boat_mesh_point = original_target_boat_mesh_point;
6484  // we first take this point (which is in the RESTART hull location) and transform it to be in the
6485  // REFERENCE configuration
6486  target_boat_mesh_point.Transform(restart_hull_location.Inverted());
6487  Point<3,fad_double> target_ref_point(target_boat_mesh_point.X(),target_boat_mesh_point.Y(),target_boat_mesh_point.Z());
6488  Point<3,fad_double> sacado_target_point(RotMatRow1*(target_ref_point+(fad_double(-1.0))*ref_baricenter_pos)+
6489  baricenter_pos(0),
6490  RotMatRow2*(target_ref_point+(fad_double(-1.0))*ref_baricenter_pos)+
6491  baricenter_pos(1),
6492  RotMatRow3*(target_ref_point+(fad_double(-1.0))*ref_baricenter_pos)+
6493  baricenter_pos(2));
6494 
6495  //questa velocità RIGIDA va preparata utilizzando i TARGET POINTS, altrimenti contiene due volte la derivata rispetto
6496  //a map_points.rigid_motions_map_points
6497  Point<3,fad_double> sacado_non_rig_vel(ref_coors_dot[3*i],ref_coors_dot[3*i+1],ref_coors_dot[3*i+2]);
6498  Point<3,fad_double> sacado_rig_vel(hull_omega[1]*(sacado_target_point[2]-baricenter_pos(2))-
6499  hull_omega[2]*(sacado_target_point[1]-baricenter_pos(1))+hull_baricenter_vel[0],
6500  hull_omega[2]*(sacado_target_point[0]-baricenter_pos(0))-
6501  hull_omega[0]*(sacado_target_point[2]-baricenter_pos(2))+hull_baricenter_vel[1],
6502  hull_omega[0]*(sacado_target_point[1]-baricenter_pos(1))-
6503  hull_omega[1]*(sacado_target_point[0]-baricenter_pos(0))+hull_baricenter_vel[2]);
6504 
6505  //if (comp_dom.ref_points[3*i].distance(Point<3>(-2.388065,0.0,-0.355460)) < 0.005)
6506  // {
6507  // cout<<"Non Rigid Vel: "<<sacado_non_rig_vel(0).val()<<" "<<sacado_non_rig_vel(1).val()<<" "<<sacado_non_rig_vel(2).val()<<endl;
6508  // cout<<"Rigid Vel: "<<sacado_rig_vel(0).val()<<" "<<sacado_rig_vel(1).val()<<" "<<sacado_rig_vel(2).val()<<endl;
6509  // }
6510  for (unsigned int j=0; j<3; ++j)
6511  {
6512  coors[3*i+j] = sacado_curr_point(j);
6513  coors_dot[3*i+j] = sacado_non_rig_vel(j)+sacado_rig_vel(j);
6514  }
6515  }
6516  else
6517  for (unsigned int j=0; j<3; ++j)
6518  {
6519  coors[3*i+j] = comp_dom.support_points[local_dof_indices[i]](j);
6520  (coors[3*i+j]).diff(3*i+j,10*dofs_per_cell+13);
6521  coors_dot[3*i+j] = nodes_velocities(3*local_dof_indices[i]+j);
6522  (coors_dot[3*i+j]).diff(3*i+j+5*dofs_per_cell,10*dofs_per_cell+13);
6523  }
6524  for (unsigned int i=0; i<dofs_per_cell; ++i)
6525  {
6526  phis[i] = phi(local_dof_indices[i]);
6527  phis[i].diff(i+3*dofs_per_cell,10*dofs_per_cell+13);
6528  phis_dot[i] = phi_time_derivs(local_dof_indices[i]);
6529  phis_dot[i].diff(i+8*dofs_per_cell,10*dofs_per_cell+13);
6530  dphi_dns[i] = dphi_dn(local_dof_indices[i]);
6531  dphi_dns[i].diff(i+4*dofs_per_cell,10*dofs_per_cell+13);
6532  dphi_dns_dot[i] = dphi_dn_time_derivs(local_dof_indices[i]);
6533  dphi_dns_dot[i].diff(i+9*dofs_per_cell,10*dofs_per_cell+13);
6534  //std::cout<<i<<"--> "<<local_dof_indices[i]<<"--------->"<<bem_phi(local_dof_indices[i])<<" "<<bem_dphi_dn(local_dof_indices[i])<<endl;
6535  }
6536 
6537  //just in case of additional pressure to be added past wet transom stern
6538  fad_double eta_dry = 1.0;
6539  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom && sqrt(Vinf*Vinf) > 0.0)
6540  {
6541  gp_Pnt ref_left_transom_pnt = Pnt(restart_transom_left_point);
6542  gp_Pnt ref_right_transom_pnt = Pnt(restart_transom_right_point);
6543  gp_Pnt ref_center_transom_pnt = Pnt(restart_transom_center_point);
6544  // we first take these points (which is in the RESTART hull location) and transform it to be in the
6545  // REFERENCE configuration
6546  ref_left_transom_pnt.Transform(restart_hull_location.Inverted());
6547  ref_right_transom_pnt.Transform(restart_hull_location.Inverted());
6548  ref_center_transom_pnt.Transform(restart_hull_location.Inverted());
6549  Point<3,fad_double> ref_left_transom_point(ref_left_transom_pnt.X(),ref_left_transom_pnt.Y(),ref_left_transom_pnt.Z());
6550  Point<3,fad_double> ref_right_transom_point(ref_right_transom_pnt.X(),ref_right_transom_pnt.Y(),ref_right_transom_pnt.Z());
6551  Point<3,fad_double> ref_center_transom_point(ref_center_transom_pnt.X(),ref_center_transom_pnt.Y(),ref_center_transom_pnt.Z());
6552  Point<3,fad_double> curr_left_transom_point(baricenter_pos(0)+
6553  RotMatRow1*(ref_left_transom_point+(fad_double(-1.0))*ref_baricenter_pos),
6554  baricenter_pos(1)+
6555  RotMatRow2*(ref_left_transom_point+(fad_double(-1.0))*ref_baricenter_pos),
6556  baricenter_pos(2)+
6557  RotMatRow3*(ref_left_transom_point+(fad_double(-1.0))*ref_baricenter_pos));
6558  Point<3,fad_double> curr_right_transom_point(baricenter_pos(0)+
6559  RotMatRow1*(ref_right_transom_point+(fad_double(-1.0))*ref_baricenter_pos),
6560  baricenter_pos(1)+
6561  RotMatRow2*(ref_right_transom_point+(fad_double(-1.0))*ref_baricenter_pos),
6562  baricenter_pos(2)+
6563  RotMatRow3*(ref_right_transom_point+(fad_double(-1.0))*ref_baricenter_pos));
6564  Point<3,fad_double> curr_center_transom_point(baricenter_pos(0)+
6565  RotMatRow1*(ref_center_transom_point+(fad_double(-1.0))*ref_baricenter_pos),
6566  baricenter_pos(1)+
6567  RotMatRow2*(ref_center_transom_point+(fad_double(-1.0))*ref_baricenter_pos),
6568  baricenter_pos(2)+
6569  RotMatRow3*(ref_center_transom_point+(fad_double(-1.0))*ref_baricenter_pos));
6570  fad_double transom_beam = restart_transom_right_point(1) - restart_transom_left_point(1) +
6571  restart_transom_right_tangent(1)/restart_transom_right_tangent(2)*(curr_right_transom_point(2)-restart_transom_right_point(2))-
6572  restart_transom_left_tangent(1)/restart_transom_left_tangent(2)*(curr_left_transom_point(2)-restart_transom_left_point(2));
6573  fad_double transom_draft = -curr_center_transom_point(2);
6574  fad_double transom_aspect_ratio = transom_beam/transom_draft;
6575  //cout<<restart_transom_right_tangent<<endl;
6576  //cout<<"b: "<<transom_beam.val()<<" d:"<<transom_draft.val()<<" "<<"AR: "<<transom_aspect_ratio.val()<<endl;
6577  fad_double FrT = sqrt(Vinf*Vinf)/sqrt(9.81*transom_draft);
6578  fad_double ReT = sqrt(9.81*pow(transom_draft,3.0))/1.307e-6;
6579  eta_dry = 0.05*pow(FrT,2.834)*pow(transom_aspect_ratio,0.1352)*pow(ReT,0.01338);
6580  if (eta_dry.val() > 1)
6581  eta_dry = 1.0;
6582  if (cell == comp_dom.dh.begin_active())
6583  cout<<"Sacado eta_dry: "<<eta_dry.val()<<endl;
6584  }
6585 
6586  // computation of displacements
6587  for (unsigned int i=0; i<dofs_per_cell; ++i)
6588  {
6589  x_displs[i] = coors[3*i] - comp_dom.ref_points[3*local_dof_indices[i]](0);
6590  y_displs[i] = coors[3*i+1] - comp_dom.ref_points[3*local_dof_indices[i]](1);
6591  //cout<<i<<" "<<coors[3*i].val()<<" "<<comp_dom.ref_points[3*local_dof_indices[i]](0)<<" "<<comp_dom.support_points[local_dof_indices[i]](0)<<endl;
6592  //cout<<i<<" "<<coors[3*i+1].val()<<" "<<comp_dom.ref_points[3*local_dof_indices[i]](1)<<" "<<comp_dom.support_points[local_dof_indices[i]](1)<<endl;
6593  }
6594  // computation of cell center
6595  Point<3,fad_double> center(0.0,0.0,0.0);
6596  for (unsigned int i=0; i<dofs_per_cell; ++i)
6597  {
6598  center += (Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]))/fad_double(dofs_per_cell);
6599  }
6600  // computation of cell diameter
6601  fad_double cell_diameter = 0.0;
6602  for (unsigned int i=0; i<dofs_per_cell; ++i)
6603  {
6604  fad_double dof_center_distance = sqrt( (center(0)-coors[3*i])*(center(0)-coors[3*i])+
6605  (center(1)-coors[3*i+1])*(center(1)-coors[3*i+1])+
6606  (center(2)-coors[3*i+2])*(center(2)-coors[3*i+2]) );
6607  cell_diameter += 2.0*(dof_center_distance)/dofs_per_cell;
6608  }
6609 
6611 
6612  std::vector<fad_double> eta_dot_rhs_fun(n_q_points);
6613  std::vector<fad_double> phi_dot_rhs_fun(n_q_points);
6614  std::vector< Point<3,fad_double> > fluid_vel(n_q_points);
6615  std::vector<fad_double> q_JxW(n_q_points);
6616 
6617 
6618  for (unsigned int q=0; q<n_q_points; ++q)
6619  {
6620  Point<3,fad_double> q_point(fad_double(0.0),fad_double(0.0),fad_double(0.0));
6621  Point<3,fad_double> u_deriv_pos(fad_double(0.0),fad_double(0.0),fad_double(0.0));
6622  Point<3,fad_double> v_deriv_pos(fad_double(0.0),fad_double(0.0),fad_double(0.0));
6623  fad_double u_deriv_phi = fad_double(0.0);
6624  fad_double v_deriv_phi = fad_double(0.0);
6625  fad_double q_dphi_dn = fad_double(0.0);
6626  fad_double q_phi_dot = fad_double(0.0);
6627  fad_double q_x_dot = fad_double(0.0);
6628  fad_double q_y_dot = fad_double(0.0);
6629  fad_double q_z_dot = fad_double(0.0);
6630  fad_double q_eta = fad_double(0.0);
6631  fad_double q_ex_press = fad_double(0.0);
6632  Point<3,fad_double> q_init(fad_double(0.0),fad_double(0.0),fad_double(0.0));
6633  cout.precision(10);
6634  for (unsigned int i=0; i<dofs_per_cell; ++i)
6635  {
6636  unsigned int index = local_dof_indices[i];
6637  q_point += fad_double(ref_fe_v.shape_value(i,q))*Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]);
6638  u_deriv_pos += fad_double(ref_fe_v.shape_grad(i,q)[0])*Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]);
6639  v_deriv_pos += fad_double(ref_fe_v.shape_grad(i,q)[1])*Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2]);
6640  u_deriv_phi += fad_double(ref_fe_v.shape_grad(i,q)[0])*phis[i];
6641  v_deriv_phi += fad_double(ref_fe_v.shape_grad(i,q)[1])*phis[i];
6642  q_dphi_dn += fad_double(ref_fe_v.shape_value(i,q))*dphi_dns[i];
6643  q_phi_dot += fad_double(ref_fe_v.shape_value(i,q))*phis_dot[i];
6644  q_x_dot += fad_double(ref_fe_v.shape_value(i,q))*coors_dot[3*i];
6645  q_y_dot += fad_double(ref_fe_v.shape_value(i,q))*coors_dot[3*i+1];
6646  q_z_dot += fad_double(ref_fe_v.shape_value(i,q))*coors_dot[3*i+2];
6647  q_eta += fad_double(ref_fe_v.shape_value(i,q))*coors[3*i+2];
6648  q_ex_press += fad_double(ref_fe_v.shape_value(i,q))*ex_press[local_dof_indices[i]];
6649  q_init(0) += ref_fe_v.shape_value(i,q)*fad_double(initial_support_points[local_dof_indices[i]](0));
6650  q_init(1) += ref_fe_v.shape_value(i,q)*fad_double(initial_support_points[local_dof_indices[i]](1));
6651  q_init(2) += ref_fe_v.shape_value(i,q)*fad_double(initial_support_points[local_dof_indices[i]](2));
6652  //q_init += ref_fe_v.shape_value(i,q)*comp_dom.ref_points[3*local_dof_indices[i]];
6653  //std::cout<<i<<"-------> "<<u_deriv_pos<<" "<<v_deriv_pos<<" "<<u_deriv_phi<<" "<<v_deriv_phi<<endl;
6654  //std::cout<<i<<"-------> "<<coors[3*i]<<" "<<coors[3*i+1]<<" "<<coors[3*i+2]<<" "<<endl;
6655  //cout<<"Earlier: "<<"i "<<i<<" q "<<q<<" "<<ref_fe_v.shape_value(i,q)*gg(2).val()<<endl;
6656  }
6657  Point<3> cen = cell->center();
6658  if (fabs(cen(2)) > 1e-5 )
6659  {
6660  q_init(0) += (hull_baricenter_displ[0]-fad_double(restart_hull_displacement(0)));
6661  q_init(1) += (hull_baricenter_displ[1]-fad_double(restart_hull_displacement(1)));
6662  q_init(2) += (hull_baricenter_displ[2]-fad_double(restart_hull_displacement(2)));
6663  }
6664  fad_double transom_added_pressure = 0.0;
6665 
6666  Point<3,fad_double> q_normal(u_deriv_pos(1)*v_deriv_pos(2)-u_deriv_pos(2)*v_deriv_pos(1),
6667  u_deriv_pos(2)*v_deriv_pos(0)-u_deriv_pos(0)*v_deriv_pos(2),
6668  u_deriv_pos(0)*v_deriv_pos(1)-u_deriv_pos(1)*v_deriv_pos(0));
6669  //std::cout<<"q_normal="<<q_normal<<std::endl;
6670  //std::cout<<"q_y_dot="<<q_y_dot<<std::endl;
6671  fad_double q_jac_det = q_normal.norm();
6672  q_normal/=q_jac_det;
6673  fad_double a = 1.0/((u_deriv_pos*u_deriv_pos)*(v_deriv_pos*v_deriv_pos)-(u_deriv_pos*v_deriv_pos)*(u_deriv_pos*v_deriv_pos));
6674  fad_double d11 = a*(u_deriv_pos(0)*v_deriv_pos*v_deriv_pos-v_deriv_pos(0)*u_deriv_pos*v_deriv_pos);
6675  fad_double d21 = a*(u_deriv_pos(1)*v_deriv_pos*v_deriv_pos-v_deriv_pos(1)*u_deriv_pos*v_deriv_pos);
6676  fad_double d31 = a*(u_deriv_pos(2)*v_deriv_pos*v_deriv_pos-v_deriv_pos(2)*u_deriv_pos*v_deriv_pos);
6677  fad_double d12 = a*(v_deriv_pos(0)*u_deriv_pos*u_deriv_pos-u_deriv_pos(0)*u_deriv_pos*v_deriv_pos);
6678  fad_double d22 = a*(v_deriv_pos(1)*u_deriv_pos*u_deriv_pos-u_deriv_pos(1)*u_deriv_pos*v_deriv_pos);
6679  fad_double d32 = a*(v_deriv_pos(2)*u_deriv_pos*u_deriv_pos-u_deriv_pos(2)*u_deriv_pos*v_deriv_pos);
6680  Point<3,fad_double> phi_surf_grad(d11*u_deriv_phi+d12*v_deriv_phi,
6681  d21*u_deriv_phi+d22*v_deriv_phi,
6682  d31*u_deriv_phi+d32*v_deriv_phi);
6683  Point<3,fad_double> phi_surf_grad_corrected(phi_surf_grad(0) - phi_surf_grad(2)*q_normal(0)/q_normal(2),
6684  phi_surf_grad(1) - phi_surf_grad(2)*q_normal(1)/q_normal(2),
6685  0.0);
6686  Point<3,fad_double> phi_grad = phi_surf_grad + q_normal*q_dphi_dn;
6687 
6688  //std::cout<<"q_point="<<q_point<<" q_normal="<<q_normal<<" q_dphi_dn="<<q_dphi_dn<<std::endl;
6689  //cout<<q<<" phi_grad("<<phi_grad<<") phi_surf_grad("<<phi_surf_grad<<")"<<endl;
6690  Point<3,fad_double> eta_grad(-q_normal(0)/q_normal(2),-q_normal(1)/q_normal(2),0.0);
6691  Point<3,fad_double> q_nodes_vel(q_x_dot,q_y_dot,q_z_dot);
6692  fluid_vel[q] = Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2))) + phi_grad;
6693  fad_double fluid_vel_norm = fluid_vel[q].norm();
6694  fad_double horiz_fluid_vel_norm = sqrt(pow(fluid_vel[q](0),2.0)+pow(fluid_vel[q](1),2.0));
6695  fad_double eta_grad_norm = eta_grad.norm();
6696  if (fluid_vel_norm < 1e-3)
6697  fluid_vel_norm = -8.0e+05*pow(fluid_vel_norm,3.0) + 1.7e+03*pow(fluid_vel_norm,2.0) + 0.0001;
6698  if (horiz_fluid_vel_norm < 1e-3)
6699  horiz_fluid_vel_norm = -8.0e+05*pow(horiz_fluid_vel_norm,3.0) + 1.7e+03*pow(horiz_fluid_vel_norm,2.0) + 0.0001;
6700  if (eta_grad_norm < 1e-3)
6701  eta_grad_norm = -8.0e+05*pow(eta_grad_norm,3.0) + 1.7e+03*pow(eta_grad_norm,2.0) + 0.0001;
6702  Point<3,fad_double> horiz_vel_unit_vect(fluid_vel[q](0)/horiz_fluid_vel_norm,fluid_vel[q](1)/horiz_fluid_vel_norm,0.0);
6703  //fad_double cell_diameter;
6704  //for (unsigned int i=0; i<dofs_per_cell; ++i)
6705  // {
6706  // cell_diameter += pow(fluid_vel[q]*(Point<3,fad_double>(coors[3*i],coors[3*i+1],coors[3*i+2])-center),2.0)/dofs_per_cell;
6707  // }
6708  //cell_diameter = sqrt(cell_diameter)*2;
6709 
6710  fad_double breaking_wave_added_pressure = 0.0;
6711  if ( (cell->material_id() == comp_dom.free_sur_ID1 ||
6712  cell->material_id() == comp_dom.free_sur_ID2 ||
6713  cell->material_id() == comp_dom.free_sur_ID3 ))
6714  if (sqrt(q_eta*q_eta+eta_grad*eta_grad*pow(Fn,4.0))-0.1725*Fn*Fn > 0)
6715  //if (eta_grad.norm() > 3.0)
6716  {
6717  //breaking_wave_added_pressure = pow(eta_grad*horiz_vel_unit_vect-7.0,2.0)*rho*g*cell_diameter;
6718  //cout<<"Breaking wave damping ON at "<<q_point(0).val()<<","<<q_point(1).val()<<","<<q_point(2).val();
6719  //cout<<"1) ("<<eta_grad(0).val()<<","<<eta_grad(1).val()<<","<<eta_grad(2).val()<<") * ("<<fluid_vel[q](0).val()<<","<<fluid_vel[q](1).val()<<","<<fluid_vel[q](2).val()<<")"<<endl;
6720  //cout<<"2) "<<q_eta.val()<<" "<<" "<<pow(Fn,4.0)<<" "<<0.1725*Fn*Fn<<endl;
6721  breaking_wave_added_pressure = pow(sqrt(q_eta*q_eta+eta_grad*eta_grad*pow(Fn,4.0))-0.1725*Fn*Fn,2.0);
6722  //if (breaking_wave_added_pressure < 0)
6723  // {
6724  // cout<<"1: "<<breaking_wave_added_pressure.val()<<endl;
6725  // }
6726  fad_double factor;
6727  if (q_eta+0.117*Fn*Fn < 0)
6728  factor = 0;
6729  else if (q_eta+0.117*Fn*Fn < 0.01)
6730  factor = pow(-1.0000e+04*pow(q_eta+0.117*Fn*Fn,3.0)+2.0000e+02*pow(q_eta+0.117*Fn*Fn,2.0),2.0);
6731  else
6732  factor = 2.0*(q_eta+0.117*Fn*Fn);
6733  if (eta_grad*fluid_vel[q] > 0 )
6734  breaking_wave_added_pressure *= eta_grad*eta_grad*factor;
6735  else
6736  breaking_wave_added_pressure *= eta_grad*eta_grad*factor*0.2;
6737  //if (breaking_wave_added_pressure < 0)
6738  // {
6739  // cout<<"2: "<<breaking_wave_added_pressure.val()<<" factor: "<<factor<<endl;
6740  // }
6741  //cout<<"3) "<<breaking_wave_added_pressure.val()<<" "<<endl;
6742  breaking_wave_added_pressure *= rho*g/ref_height/12.0*(fluid_vel[q]*eta_grad)/fluid_vel_norm/eta_grad_norm;
6743  //if (breaking_wave_added_pressure < 0)
6744  // {
6745  // cout<<"3: "<<breaking_wave_added_pressure.val()<<endl;
6746  // }
6747  //fad_double test = fluid_vel[q]*eta_grad;
6748  //fad_double test2 = 1/fluid_vel_norm/eta_grad_norm;
6749  //cout<<"4) "<<breaking_wave_added_pressure.val()<<" "<<test.val()<<" "<<test2.val()<<" "<<rho*g/ref_height*2.0<<endl;
6750  //cout<<"4) "<<breaking_wave_added_pressure.val()<<" "<<rho<<" "<<g<<" "<<ref_height<<endl;
6751  //cout<<"Breaking wave damping ON at "<<q_point(0).val()<<","<<q_point(1).val()<<","<<q_point(2).val()<<" ---> "<<breaking_wave_added_pressure.val()<<endl;
6752  //cout<<"0) "<<breaking_wave_added_pressure.val()<<" "<<endl;
6753  }
6754  /*
6755  // this if is needed to compute the pressure patch behind the transom stern
6756  // pressure is estimated via Doctors regression formulas
6757  if (comp_dom.boat_model.is_transom)
6758  if ( (cell->material_id() == comp_dom.free_sur_ID1 ||
6759  cell->material_id() == comp_dom.free_sur_ID2 ||
6760  cell->material_id() == comp_dom.free_sur_ID3 ))
6761  if ( (q_point(1) < comp_dom.boat_model.PointRightTransom(1)) &&
6762  (q_point(1) > comp_dom.boat_model.PointLeftTransom(1)) )
6763  {
6764  if (q_point(1) < 0)
6765  curve = comp_dom.boat_model.left_transom_bspline;
6766  else
6767  curve = comp_dom.boat_model.right_transom_bspline;
6768  //this is the horizontal plane
6769  Handle(Geom_Plane) zxPlane = new Geom_Plane(0.,1.,0.,q_point(1));
6770  Handle(Geom_Curve) curve;
6771  GeomAPI_IntCS Intersector(curve, horPlane);
6772  gp_Pnt P;
6773  gp_Vec V1;
6774  int npoints = Intersector.NbPoints();
6775  AssertThrow((npoints != 0), ExcMessage("Keel or transom curve is not intersecting with horizontal plane!"));
6776 
6777  double minDistance=1e7;
6778  double t,u,v;
6779  for (int j=0; j<npoints;++j)
6780  {
6781  Point<3> inters = Pnt(Intersector.Point(j+1));
6782  Intersector.Parameters(j+1,u,v,t);
6783  if (dP0.distance(inters) < minDistance)
6784  {
6785  minDistance = dP0.distance(inters);
6786  dP = inters;
6787  curve->D1(t,P,V1);
6788  }
6789  }
6790  }
6791  */
6792  /*
6793  if (q_point(0).val()<102 &&
6794  q_point(0).val()>36.9 &&
6795  abs(q_point(1).val())< 5.6 &&
6796  abs(q_point(2).val())< 0.5 &&
6797  fabs(t-0.005) < 1e-4 )
6798  {
6799  std::cout<<"q_point=("<<q_point(0).val()<<","<<q_point(1).val()<<","<<q_point(2).val()<<") q_dphi_dn="<<q_dphi_dn.val()<<endl;
6800  std::cout<<"phi_grad=("<<phi_grad(0).val()<<","<<phi_grad(1).val()<<","<<phi_grad(2).val()<<")"<<endl;
6801  std::cout<<"fluid_vel=("<<fluid_vel[q](0).val()<<","<<fluid_vel[q](1).val()<<","<<fluid_vel[q](2).val()<<")"<<endl;
6802  std::cout<<"q_nodes_vel=("<<q_nodes_vel(0).val()<<","<<q_nodes_vel(1).val()<<","<<q_nodes_vel(2).val()<<")"<<endl;
6803  std::cout<<"phi_surf_grad_corrected=("<<phi_surf_grad_corrected(0).val()<<","<<phi_surf_grad_corrected(1).val()<<","<<phi_surf_grad_corrected(2).val()<<")"<<endl;
6804  cout<<"Elevations: "<<q_eta.val()<<" VS "<<q_init(2)<<endl;
6805  cout<<q<<" erhs("<<eta_dot_rhs_fun[q].val()<<") prhs("<<phi_dot_rhs_fun[q].val()<<")"<<endl;
6806  //std::cout<<"local_DphiDt_rhs_2(i)="<<local_DphiDt_rhs_2(i)<<"local_DphiDt_rhs_2(i) ="<<local_DphiDt_rhs_2(i)<<")"<<endl;
6807  }
6808  */
6809  transom_added_pressure = (1-eta_dry)*fad_double(g*q_init(2));
6810  //if (q_eta.val() > 1e-5)
6811  //cout<<"Later: "<<q_point(2)*gg(2)<<endl;
6812  q_JxW[q] = q_jac_det*ref_fe_v.JxW(q);
6813 
6814  //cout<<cell<<" "<<q<<" "<<phi_dot_rhs_fun[q]<<endl;
6815  //cout<<cell<<" "<<q<<" "<<q_JxW[q]<<endl;
6816  //cout.precision(0);
6817  //if ( (q_point(1).val() < comp_dom.boat_model.PointRightTransom(1)) &&
6818  // (q_point(1).val() >= 0.0) &&
6819  // (q_point(0).val() > comp_dom.boat_model.PointCenterTransom(0)-fabs(comp_dom.boat_model.PointCenterTransom(2)) ) &&
6820  // (q_point(0).val() < comp_dom.boat_model.PointCenterTransom(0)+5*fabs(comp_dom.boat_model.PointCenterTransom(2)) ) )
6821  // {
6822  //cout<<(int)cell->material_id()<<endl;
6823  //cout<<q<<" "<<q_point(0).val()<<","<<q_point(1).val()<<","<<q_point(2).val()<<endl;
6824  // cout<<transom_added_pressure.val()-g*q_eta.val()<<" ("<<transom_added_pressure.val()<<" vs "<<g*q_eta.val()<<")"<<endl;
6825  //cout<<q<<" fvel("<<fluid_vel[q]<<") fvel_norm="<<fluid_vel_norm<<" q_JxW="<<q_JxW[q]<<endl;
6826  //cout<<q<<" erhs("<<eta_dot_rhs_fun[q]<<") prhs("<<phi_dot_rhs_fun[q]<<")"<<endl;
6827  //cout<<q<<" phi_grad("<<phi_surf_grad_corrected(0).val()<<","<<phi_surf_grad_corrected(1).val()<<","<<phi_surf_grad_corrected(2).val()<<")"<<endl;// phi_surf_grad("<<phi_surf_grad<<")"<<endl;
6828  //cout<<q<<" "<<phi_dot_rhs_fun[q].val()<<endl;//" "<<phi_dot_rhs_fun[q].val()<<endl;
6829  // }
6830  if (cell->material_id() == comp_dom.free_sur_ID1 ||
6831  cell->material_id() == comp_dom.free_sur_ID2 ||
6832  cell->material_id() == comp_dom.free_sur_ID3 )
6833  {
6834  //cout<<q<<" "<<phi_dot_rhs_fun[q].val()<<endl;
6835  fad_double wave_damping_pressure = 0.0;
6836  //if (comp_dom.no_boat && q_point(0).val() > 0.0)
6837  fad_double Lx_boat = comp_dom.boat_model.boatWetLength;
6838  if (q_point(0).val() > Lx_boat*2.0)
6839  wave_damping_pressure = -fad_double(1.0)*pow(q_point(0).val()-Lx_boat*2.0,2.0)/pow(Lx_boat*4.0,2.0)*q_dphi_dn;
6840 
6841  eta_dot_rhs_fun[q] = phi_grad*Point<3,fad_double>(fad_double(0.0),fad_double(0.0),fad_double(1.0)) +
6842  eta_grad*(q_nodes_vel-fluid_vel[q]);
6843  phi_dot_rhs_fun[q] = phi_grad*phi_grad/2 - q_point*gg + phi_surf_grad_corrected*(q_nodes_vel-fluid_vel[q])-
6844  breaking_wave_added_pressure +
6845  + (1-eta_dry)*fad_double(g*q_init(2)) + wave_damping_pressure;
6846  //if ( (q_point(0).val() < 3.10) && (q_point(0).val() > 3.03) &&
6847  // (q_point(1).val() < 0.12) && (q_point(1).val() > 0) &&
6848  // (q_point(2).val() > -1.0) )
6849  // cout<<phi_dot_rhs_fun[q].val()<<endl;
6850  for (unsigned int i=0; i<dofs_per_cell; ++i)
6851  {
6852  Point<3,fad_double> N_i_surf_grad(d11*ref_fe_v.shape_grad(i,q)[0]+d12*ref_fe_v.shape_grad(i,q)[1],
6853  d21*ref_fe_v.shape_grad(i,q)[0]+d22*ref_fe_v.shape_grad(i,q)[1],
6854  d31*ref_fe_v.shape_grad(i,q)[0]+d32*ref_fe_v.shape_grad(i,q)[1]);
6855  fad_double N_i_supg = fad_double(ref_fe_v.shape_value(i,q)) +
6856  N_i_surf_grad*fluid_vel[q]/fluid_vel_norm*cell_diameter/sqrt(2);
6857  loc_eta_res[i] -= eta_dot_rhs_fun[q]*N_i_supg*q_JxW[q];
6858  loc_phi_res[i] -= phi_dot_rhs_fun[q]*N_i_supg*q_JxW[q];
6859  loc_x_smooth_res[i] -= blend_factor*0*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6860  loc_y_smooth_res[i] -= blend_factor*0*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6861  local_DphiDt_rhs(i) += (phi_dot_rhs_fun[q]*N_i_supg*q_JxW[q]).val();
6862  local_DphiDt_rhs_2(i) += (eta_dot_rhs_fun[q]*N_i_supg*q_JxW[q]).val();
6863  //local_DphiDt_rhs_4(i) += (breaking_wave_added_pressure*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6864  //local_DphiDt_rhs_4(i) += (transom_added_pressure*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6865  local_DphiDt_rhs_4(i) += (wave_damping_pressure*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6866  //cout<<q<<" "<<i<<" "<<phi_grad(2)<<" "<<eta_grad<<" "<<q_nodes_vel-fluid_vel[q]<<endl;
6867  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
6868  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_rhs_fun[q].val()<<" "<<q_JxW[q].val()<<endl;
6869 
6870  //cout<<q<<" "<<i<<" "<<q_JxW[q]<<endl;
6871  for (unsigned int j=0; j<dofs_per_cell; ++j)
6872  {
6873  //loc_eta_res[i] += fad_double(ref_fe_v.shape_value(j,q))*coors_dot[3*j+2]*N_i_supg*q_JxW[q];
6874  //loc_phi_res[i] += fad_double(ref_fe_v.shape_value(j,q))*phis_dot[j]*N_i_supg*q_JxW[q];
6875  //local_DphiDt_matrix.add(i,j,ref_fe_v.shape_value(j,q)*(N_i_supg*q_JxW[q]).val());
6876  loc_supg_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*N_i_supg*q_JxW[q];
6877  Point<3,fad_double> N_j_surf_grad(d11*ref_fe_v.shape_grad(j,q)[0]+d12*ref_fe_v.shape_grad(j,q)[1],
6878  d21*ref_fe_v.shape_grad(j,q)[0]+d22*ref_fe_v.shape_grad(j,q)[1],
6879  d31*ref_fe_v.shape_grad(j,q)[0]+d32*ref_fe_v.shape_grad(j,q)[1]);
6880  loc_stiffness_matrix[i][j] += N_i_surf_grad*N_j_surf_grad*q_JxW[q];
6881  }
6882  //if (fmax(abs(loc_eta_res[i].val()),abs(loc_phi_res[i].val()))>1e-6)
6883  // cout<<q<<" "<<i<<" "<<loc_eta_res[i].val()<<"("<<coors_dot[3*i+2].val()<<") "<<loc_phi_res[i].val()<<"("<<phis_dot[i].val()<<") "<<endl;
6884  }
6885 
6886  }
6887 
6888  if (cell->material_id() == comp_dom.pressure_sur_ID )
6889  {
6890  //cout<<q<<" "<<phi_dot_rhs_fun[q].val()<<endl;
6891  //fad_double pressure = -q_point*gg*fad_double(rho);
6892  phi_dot_rhs_fun[q] = -q_ex_press/fad_double(rho) + phi_grad*phi_grad/2 - q_point*gg +
6893  phi_grad*(q_nodes_vel-fluid_vel[q]);
6894  for (unsigned int i=0; i<dofs_per_cell; ++i)
6895  {
6896  Point<3,fad_double> N_i_surf_grad(d11*ref_fe_v.shape_grad(i,q)[0]+d12*ref_fe_v.shape_grad(i,q)[1],
6897  d21*ref_fe_v.shape_grad(i,q)[0]+d22*ref_fe_v.shape_grad(i,q)[1],
6898  d31*ref_fe_v.shape_grad(i,q)[0]+d32*ref_fe_v.shape_grad(i,q)[1]);
6899  fad_double N_i_supg = fad_double(ref_fe_v.shape_value(i,q)) +
6900  N_i_surf_grad*fluid_vel[q]/fluid_vel_norm*cell_diameter/sqrt(2);
6901  loc_phi_res[i] -= phi_dot_rhs_fun[q]*N_i_supg*q_JxW[q];
6902  loc_x_smooth_res[i] -= blend_factor*0*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6903  loc_y_smooth_res[i] -= blend_factor*0*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6904  local_DphiDt_rhs(i) += (phi_dot_rhs_fun[q]*N_i_supg*q_JxW[q]).val();
6905  //local_DphiDt_rhs_4(i) += (breaking_wave_added_pressure*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6906  //local_DphiDt_rhs_4(i) += (transom_added_pressure*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6907  local_DphiDt_rhs_4(i) += (0*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6908  //cout<<q<<" "<<i<<" ("<<phi_surf_grad_corrected(0).val()<<","<<phi_surf_grad_corrected(1).val()<<","<<phi_surf_grad_corrected(2).val()<<") ("<<q_nodes_vel(0).val()-fluid_vel[q](0).val()<<","<<q_nodes_vel(1).val()-fluid_vel[q](1).val()<<","<<q_nodes_vel(2).val()-fluid_vel[q](2).val()<<")"<<endl;
6909  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
6910  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_rhs_fun[q].val()<<" "<<q_JxW[q].val()<<" "<<loc_phi_res[i].val()<<endl;
6911 
6912  //cout<<q<<" "<<i<<" "<<q_JxW[q]<<endl;
6913  for (unsigned int j=0; j<dofs_per_cell; ++j)
6914  {
6915  //loc_eta_res[i] += fad_double(ref_fe_v.shape_value(j,q))*coors_dot[3*j+2]*N_i_supg*q_JxW[q];
6916  //loc_phi_res[i] += fad_double(ref_fe_v.shape_value(j,q))*phis_dot[j]*N_i_supg*q_JxW[q];
6917  //local_DphiDt_matrix.add(i,j,ref_fe_v.shape_value(j,q)*(N_i_supg*q_JxW[q]).val());
6918  loc_supg_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*N_i_supg*q_JxW[q];
6919  Point<3,fad_double> N_j_surf_grad(d11*ref_fe_v.shape_grad(j,q)[0]+d12*ref_fe_v.shape_grad(j,q)[1],
6920  d21*ref_fe_v.shape_grad(j,q)[0]+d22*ref_fe_v.shape_grad(j,q)[1],
6921  d31*ref_fe_v.shape_grad(j,q)[0]+d32*ref_fe_v.shape_grad(j,q)[1]);
6922  loc_stiffness_matrix[i][j] += N_i_surf_grad*N_j_surf_grad*q_JxW[q];
6923  }
6924  //if (fmax(abs(loc_eta_res[i].val()),abs(loc_phi_res[i].val()))>1e-6)
6925  // cout<<q<<" "<<i<<" "<<loc_eta_res[i].val()<<"("<<coors_dot[3*i+2].val()<<") "<<loc_phi_res[i].val()<<"("<<phis_dot[i].val()<<") "<<endl;
6926  }
6927 
6928  }
6929 
6930  if (cell->material_id() == comp_dom.wall_sur_ID1 ||
6931  cell->material_id() == comp_dom.wall_sur_ID2 ||
6932  cell->material_id() == comp_dom.wall_sur_ID3 )
6933  {
6934  Point<3,fad_double> VV_inf(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2)));
6935  fad_double dphi_dt = q_phi_dot - q_nodes_vel*phi_grad;
6936  //if (q==10)
6937  // {
6938  // cout<<"VEL: "<<q_nodes_vel(0).val()<<" "<<q_nodes_vel(1).val()<<" "<<q_nodes_vel(2).val()<<endl;
6939  // cout<<dphi_dt.val()<<" "<<q_phi_dot.val()<<" "<<(q_nodes_vel*phi_grad).val()<<endl;
6940  // }
6941  fad_double local_pressure = -(fad_double(rho)*(dphi_dt+q_point*gg+phi_grad*(phi_grad/2.0+VV_inf))*q_JxW[q]);
6942  loc_pressure_force += local_pressure*q_normal;
6943 
6944  Point<3,fad_double> q_mom((q_point(1)-baricenter_pos(1))*q_normal(2)-(q_point(2)-baricenter_pos(2))*q_normal(1),
6945  (q_point(2)-baricenter_pos(2))*q_normal(0)-(q_point(0)-baricenter_pos(0))*q_normal(2),
6946  (q_point(0)-baricenter_pos(0))*q_normal(1)-(q_point(1)-baricenter_pos(1))*q_normal(0));
6947  q_mom = q_mom*local_pressure;
6948  loc_pressure_moment+= q_mom;
6949  for (unsigned int i=0; i<dofs_per_cell; ++i)
6950  {
6951  loc_dphi_dn_res[i] -= (q_normal*(q_nodes_vel-VV_inf))*
6952  fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6953  //cout<<q<<" "<<i<<" "<<-(q_normal*Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2)))).val()<<" "<<cell->center()<<" "<<endl;
6954  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
6955  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_res_fun[q].val()<<" "<<q_JxW[q].val()<<endl;
6956  local_DphiDt_rhs_3(i) += (-(q_normal*(q_nodes_vel-VV_inf))*
6957  fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6958  //cout<<"**** "<<loc_dphi_dn_res[i].val()<<" "<<local_DphiDt_rhs_3(i)<<" "<<loc_dphi_dn_res[i].val()+local_DphiDt_rhs_3(i)<<endl;
6959  for (unsigned int j=0; j<dofs_per_cell; ++j)
6960  {
6961  //loc_dphi_dn_res[i] += fad_double(ref_fe_v.shape_value(i,q))*fad_double(ref_fe_v.shape_value(j,q))*dphi_dns[j]*q_JxW[q];
6962  loc_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6963  }
6964  //if (abs(loc_dphi_dn_res[i].val())>1e-7)
6965  // cout<<q<<" "<<i<<" "<<loc_dphi_dn_res[i].val()<<endl;
6966  }
6967  }
6968 
6969  if (cell->material_id() == comp_dom.inflow_sur_ID1 ||
6970  cell->material_id() == comp_dom.inflow_sur_ID2 )
6971  {
6972  for (unsigned int i=0; i<dofs_per_cell; ++i)
6973  {
6974  //fad_double k=0.62994; fad_double omega=2.4835; fad_double h=5.5; fad_double a=0.1;
6975  //fad_double inflow_norm_pot_grad = omega*a*cosh(k*(q_point(2)+h))/sinh(k*h)*cos(k*q_point(0)-omega*t);
6976  //fad_double inflow_norm_pot_grad = k*a*cos(k*q_point(0)-omega*t);
6977  //if (t<40.0)
6978  // inflow_norm_pot_grad *= 0.5*sin(3.141592654*(t)/40.0-3.141592654/2)+0.5;
6979  //cout<<q<<" "<<i<<" "<<inflow_norm_pot_grad.val()<<" x: "<<q_point(0).val()<<" z: "<<q_point(2).val()<<endl;
6980  //loc_dphi_dn_res[i] -= inflow_norm_pot_grad*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6981  loc_dphi_dn_res[i] -= -(inflow_norm_potential_grad.value(Point<3>(q_point(0).val(),q_point(1).val(),q_point(2).val())))*
6982  fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6983  //cout<<q<<" "<<i<<" "<<-(inflow_norm_potential_grad.value(Point<3>(q_point(0).val(),q_point(1).val(),q_point(2).val())))<<" "<<cell->center()<<" "<<endl;
6984  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
6985  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_res_fun[q].val()<<" "<<q_JxW[q].val()<<endl;
6986  local_DphiDt_rhs_3(i) += inflow_norm_potential_grad.value(Point<3>(q_point(0).val(),q_point(1).val(),q_point(2).val()))*
6987  (fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q]).val();
6988  //cout<<"**** "<<loc_dphi_dn_res[i].val()<<" "<<local_DphiDt_rhs_3(i)<<" "<<loc_dphi_dn_res[i].val()+local_DphiDt_rhs_3(i)<<endl;
6989  for (unsigned int j=0; j<dofs_per_cell; ++j)
6990  {
6991  //loc_dphi_dn_res[i] += fad_double(ref_fe_v.shape_value(i,q))*fad_double(ref_fe_v.shape_value(j,q))*dphi_dns[j]*q_JxW[q];
6992  loc_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
6993  }
6994  //if (abs(loc_dphi_dn_res[i].val())>1e-7)
6995  // cout<<q<<" "<<i<<" "<<loc_dphi_dn_res[i].val()<<endl;
6996  }
6997  }
6998 
6999  if (cell->material_id() != comp_dom.wall_sur_ID1 &&
7000  cell->material_id() != comp_dom.wall_sur_ID2 &&
7001  cell->material_id() != comp_dom.wall_sur_ID3 &&
7002  cell->material_id() != comp_dom.free_sur_ID1 &&
7003  cell->material_id() != comp_dom.free_sur_ID2 &&
7004  cell->material_id() != comp_dom.free_sur_ID3 &&
7005  cell->material_id() != comp_dom.inflow_sur_ID1 &&
7006  cell->material_id() != comp_dom.inflow_sur_ID2 &&
7007  cell->material_id() != comp_dom.pressure_sur_ID)
7008  {
7009  for (unsigned int i=0; i<dofs_per_cell; ++i)
7010  {
7011  loc_dphi_dn_res[i] -= 0;
7012  //cout<<q<<" "<<i<<" "<<-(q_normal*Point<3,fad_double>(fad_double(Vinf(0)),fad_double(Vinf(1)),fad_double(Vinf(2)))).val()<<" "<<cell->center()<<" "<<endl;
7013  //cout<<q<<" "<<i<<" "<<N_i_surf_grad<<" "<<fluid_vel[q]/fluid_vel_norm<<" "<<cell_diameter/sqrt(2)<<endl;
7014  //cout<<q<<" "<<i<<" "<<N_i_supg.val()<<" "<<phi_dot_res_fun[q].val()<<" "<<q_JxW[q].val()<<endl;
7015  local_DphiDt_rhs_3(i) += 0;
7016  //cout<<"**** "<<loc_dphi_dn_res[i].val()<<" "<<local_DphiDt_rhs_3(i)<<" "<<loc_dphi_dn_res[i].val()+local_DphiDt_rhs_3(i)<<endl;
7017  for (unsigned int j=0; j<dofs_per_cell; ++j)
7018  {
7019  //loc_dphi_dn_res[i] += fad_double(ref_fe_v.shape_value(i,q))*fad_double(ref_fe_v.shape_value(j,q))*dphi_dns[j]*q_JxW[q];
7020  loc_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
7021  }
7022  //if (abs(loc_dphi_dn_res[i].val())>1e-7)
7023  // cout<<q<<" "<<i<<" "<<loc_dphi_dn_res[i].val()<<endl;
7024  }
7025  }
7026 
7027  for (unsigned int i=0; i<dofs_per_cell; ++i)
7028  {
7029  Point<3,fad_double> N_i_surf_grad(d11*ref_fe_v.shape_grad(i,q)[0]+d12*ref_fe_v.shape_grad(i,q)[1],
7030  d21*ref_fe_v.shape_grad(i,q)[0]+d22*ref_fe_v.shape_grad(i,q)[1],
7031  d31*ref_fe_v.shape_grad(i,q)[0]+d32*ref_fe_v.shape_grad(i,q)[1]);
7032  fad_double N_i_supg = fad_double(ref_fe_v.shape_value(i,q)) +
7033  N_i_surf_grad*fluid_vel[q]/fluid_vel_norm*cell_diameter/sqrt(2);
7034  for (unsigned int j=0; j<dofs_per_cell; ++j)
7035  {
7036  local_DphiDt_matrix.add(i,j,ref_fe_v.shape_value(j,q)*(N_i_supg*q_JxW[q]).val());
7037  local_DphiDt_matrix_2.add(i,j,ref_fe_v.shape_value(j,q)*ref_fe_v.shape_value(i,q)*(q_JxW[q]).val());
7038  //loc_supg_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*N_i_supg*q_JxW[q];
7039  //loc_mass_matrix[i][j] += fad_double(ref_fe_v.shape_value(j,q))*fad_double(ref_fe_v.shape_value(i,q))*q_JxW[q];
7040  }
7041  }
7042  }
7043 
7044  for (unsigned int i=0; i<dofs_per_cell; ++i)
7045  {
7046  DphiDt_sys_rhs(local_dof_indices[i]) += local_DphiDt_rhs(i);
7047  DphiDt_sys_rhs_2(local_dof_indices[i]) += local_DphiDt_rhs_2(i);
7048  DphiDt_sys_rhs_3(local_dof_indices[i]) += local_DphiDt_rhs_3(i);
7049  DphiDt_sys_rhs_4(local_dof_indices[i]) += local_DphiDt_rhs_4(i);
7050  for (unsigned int j=0; j<dofs_per_cell; ++j)
7051  {
7052  DphiDt_sys_matrix.add(local_dof_indices[i],local_dof_indices[j],local_DphiDt_matrix(i,j));
7053  DphiDt_sys_matrix_2.add(local_dof_indices[i],local_dof_indices[j],local_DphiDt_matrix_2(i,j));
7054  }
7055  }
7056 
7057  if (cell->material_id() == comp_dom.free_sur_ID1 ||
7058  cell->material_id() == comp_dom.free_sur_ID2 ||
7059  cell->material_id() == comp_dom.free_sur_ID3 )
7060  {
7061  for (unsigned int i=0; i<dofs_per_cell; ++i)
7062  {
7063  //if ( (cell->center()(0) < 3.20) && (cell->center()(0) > 3.03) &&
7064  // (cell->center()(1) < 0.12) && (cell->center()(1) > 0) &&
7065  // (cell->center()(2) > -1.0) )
7066  // cout<<local_dof_indices[i]<<" ***** "<<phis_dot[i].val()<<" "<<phis[i].val()<<" "<<dphi_dns[i].val()<<endl;
7067  for (unsigned int j=0; j<dofs_per_cell; ++j)
7068  {
7069  //if ( (cell->center()(0) < 3.20) && (cell->center()(0) > 3.03) &&
7070  // (cell->center()(1) < 0.12) && (cell->center()(1) > 0) &&
7071  // (cell->center()(2) > -1.0) )
7072  // cout<<" o***** "<<loc_supg_mass_matrix[i][j].val()<<endl;
7073  loc_eta_res[i] += loc_supg_mass_matrix[i][j]*coors_dot[3*j+2];
7074  loc_phi_res[i] += loc_supg_mass_matrix[i][j]*phis_dot[j];
7075  //if (fabs(t<0.005)<1e-4) {cout<<cell<<" "<<i<<" "<<phis_dot[j]<<endl;}
7076  loc_x_smooth_res[i] += loc_stiffness_matrix[i][j]*(x_displs[j]-(1-blend_factor)*comp_dom.old_map_points(3*local_dof_indices[j]));
7077  loc_y_smooth_res[i] += loc_stiffness_matrix[i][j]*(y_displs[j]-(1-blend_factor)*comp_dom.old_map_points(3*local_dof_indices[j]+1));
7078  }
7079  if ( !constraints.is_constrained(local_dof_indices[i]) &&
7080  !(comp_dom.flags[local_dof_indices[i]] & transom_on_water) )
7081  {
7082  unsigned int ii = local_dof_indices[i];
7083  if (!(comp_dom.flags[local_dof_indices[i]] & near_inflow))
7084  eta_res[ii] += loc_eta_res[i].val();
7085  phi_res[ii] += loc_phi_res[i].val();
7086  //cout<<"* "<<cell<<" "<<local_dof_indices[i]<<" "<<loc_phi_res[i]<<endl;
7087  for (unsigned int j=0; j<dofs_per_cell; ++j)
7088  {
7089  unsigned int jj = local_dof_indices[j];
7090  if (!(comp_dom.flags[local_dof_indices[i]] & near_inflow))
7091  {
7092  for (unsigned int k=0; k<dim; ++k)
7093  jacobian_matrix.add(3*ii+2,
7094  3*jj+k,
7095  loc_eta_res[i].fastAccessDx(3*j+k));
7096  jacobian_matrix.add(3*ii+2,
7097  jj+comp_dom.vector_dh.n_dofs(),
7098  loc_eta_res[i].fastAccessDx(3*dofs_per_cell+j));
7099  jacobian_matrix.add(3*ii+2,
7100  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7101  loc_eta_res[i].fastAccessDx(4*dofs_per_cell+j));
7102  }
7103  for (unsigned int k=0; k<dim; ++k)
7104  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7105  3*jj+k,
7106  loc_phi_res[i].fastAccessDx(3*j+k));
7107  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7108  jj+comp_dom.vector_dh.n_dofs(),
7109  loc_phi_res[i].fastAccessDx(3*dofs_per_cell+j));
7110  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7111  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7112  loc_phi_res[i].fastAccessDx(4*dofs_per_cell+j));
7113  if (!(comp_dom.flags[local_dof_indices[i]] & near_inflow))
7114  {
7115  for (unsigned int k=0; k<dim; ++k)
7116  jacobian_dot_matrix.add(3*ii+2,
7117  3*jj+k,
7118  loc_eta_res[i].fastAccessDx(5*dofs_per_cell+3*j+k));
7119  jacobian_dot_matrix.add(3*ii+2,
7120  jj+comp_dom.vector_dh.n_dofs(),
7121  loc_eta_res[i].fastAccessDx(8*dofs_per_cell+j));
7122  jacobian_dot_matrix.add(3*ii+2,
7123  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7124  loc_eta_res[i].fastAccessDx(9*dofs_per_cell+j));
7125  }
7126  for (unsigned int k=0; k<dim; ++k)
7127  jacobian_dot_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7128  3*jj+k,
7129  loc_phi_res[i].fastAccessDx(5*dofs_per_cell+3*j+k));
7130  jacobian_dot_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7131  jj+comp_dom.vector_dh.n_dofs(),
7132  loc_phi_res[i].fastAccessDx(8*dofs_per_cell+j));
7133  jacobian_dot_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7134  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7135  loc_phi_res[i].fastAccessDx(9*dofs_per_cell+j));
7136  }
7137  if (!(comp_dom.flags[local_dof_indices[i]] & near_inflow))
7138  {
7139  for (unsigned int k=0; k<dim; ++k)
7140  jacobian_matrix.add(3*ii+2,
7141  k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7142  loc_eta_res[i].fastAccessDx(k+10*dofs_per_cell));
7143  for (unsigned int k=0; k<dim; ++k)
7144  jacobian_matrix.add(3*ii+2,
7145  k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7146  loc_eta_res[i].fastAccessDx(k+3+10*dofs_per_cell));
7147  for (unsigned int k=0; k<dim; ++k)
7148  jacobian_matrix.add(3*ii+2,
7149  k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7150  loc_eta_res[i].fastAccessDx(k+6+10*dofs_per_cell));
7151  for (unsigned int k=0; k<4; ++k)
7152  jacobian_matrix.add(3*ii+2,
7153  k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7154  loc_eta_res[i].fastAccessDx(k+9+10*dofs_per_cell));
7155  }
7156  for (unsigned int k=0; k<dim; ++k)
7157  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7158  k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7159  loc_phi_res[i].fastAccessDx(k+10*dofs_per_cell));
7160  for (unsigned int k=0; k<dim; ++k)
7161  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7162  k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7163  loc_phi_res[i].fastAccessDx(k+3+10*dofs_per_cell));
7164  for (unsigned int k=0; k<dim; ++k)
7165  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7166  k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7167  loc_phi_res[i].fastAccessDx(k+6+10*dofs_per_cell));
7168  for (unsigned int k=0; k<4; ++k)
7169  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7170  k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7171  loc_phi_res[i].fastAccessDx(k+9+10*dofs_per_cell));
7172 
7173  }
7174  if ( !(constraints.is_constrained(local_dof_indices[i])) &&
7175  !(comp_dom.flags[local_dof_indices[i]] & edge) )
7176  {
7177  unsigned int ii = local_dof_indices[i];
7178  //if (local_dof_indices[i] == 601)
7179  // cout<<"££MATCH££ "<<local_dof_indices[i]<<": "<<loc_x_smooth_res[i]<<endl;
7180  x_smoothing_res[ii] += loc_x_smooth_res[i].val();
7181  y_smoothing_res[ii] += loc_y_smooth_res[i].val();
7182  for (unsigned int j=0; j<dofs_per_cell; ++j)
7183  {
7184  //if (local_dof_indices[i] == 601)
7185  // {
7186  // cout<<"("<<local_dof_indices[j]<<")"<<endl;
7187  // for (unsigned int k=0; k<dim; ++k)
7188  // cout<<"(-"<<coors[3*j+k]<<"-)"<<endl;
7189  // }
7190  unsigned int jj = local_dof_indices[j];
7191  for (unsigned int k=0; k<dim; ++k)
7192  jacobian_matrix.add(3*ii,
7193  3*jj+k,
7194  loc_x_smooth_res[i].fastAccessDx(3*j+k));
7195  jacobian_matrix.add(3*ii,
7196  jj+comp_dom.vector_dh.n_dofs(),
7197  loc_x_smooth_res[i].fastAccessDx(3*dofs_per_cell+j));
7198  jacobian_matrix.add(3*ii,
7199  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7200  loc_x_smooth_res[i].fastAccessDx(4*dofs_per_cell+j));
7201 
7202 
7203  for (unsigned int k=0; k<dim; ++k)
7204  jacobian_matrix.add(3*ii+1,
7205  3*jj+k,
7206  loc_y_smooth_res[i].fastAccessDx(3*j+k));
7207  jacobian_matrix.add(3*ii+1,
7208  jj+comp_dom.vector_dh.n_dofs(),
7209  loc_y_smooth_res[i].fastAccessDx(3*dofs_per_cell+j));
7210  jacobian_matrix.add(3*ii+1,
7211  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7212  loc_y_smooth_res[i].fastAccessDx(4*dofs_per_cell+j));
7213  }
7214  for (unsigned int k=0; k<dim; ++k)
7215  jacobian_matrix.add(3*ii,
7216  k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7217  loc_x_smooth_res[i].fastAccessDx(k+3+10*dofs_per_cell));
7218  for (unsigned int k=0; k<4; ++k)
7219  jacobian_matrix.add(3*ii,
7220  k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7221  loc_x_smooth_res[i].fastAccessDx(k+9+10*dofs_per_cell));
7222  for (unsigned int k=0; k<dim; ++k)
7223  jacobian_matrix.add(3*ii+1,
7224  k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7225  loc_y_smooth_res[i].fastAccessDx(k+3+10*dofs_per_cell));
7226  for (unsigned int k=0; k<dim; ++k)
7227  jacobian_matrix.add(3*ii+1,
7228  k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7229  loc_y_smooth_res[i].fastAccessDx(k+9+10*dofs_per_cell));
7230  }
7231  }
7232  }
7233  if (cell->material_id() == comp_dom.pressure_sur_ID)
7234  {
7235  for (unsigned int i=0; i<dofs_per_cell; ++i)
7236  {
7237  for (unsigned int j=0; j<dofs_per_cell; ++j)
7238  {
7239  loc_phi_res[i] += loc_supg_mass_matrix[i][j]*phis_dot[j];
7240  //if (fabs(t<0.005)<1e-4) {cout<<cell<<" "<<i<<" "<<phis_dot[j]<<endl;}
7241  }
7242 
7243  if ( !constraints.is_constrained(local_dof_indices[i]) &&
7244  !(comp_dom.flags[local_dof_indices[i]] & near_water))
7245  {
7246  unsigned int ii = local_dof_indices[i];
7247  phi_res[ii] += loc_phi_res[i].val();
7248  //cout<<"* "<<cell<<" "<<local_dof_indices[i]<<" "<<loc_phi_res[i]<<endl;
7249  for (unsigned int j=0; j<dofs_per_cell; ++j)
7250  {
7251  unsigned int jj = local_dof_indices[j];
7252  //if (local_dof_indices[i]==44)
7253  // {
7254  // cout<<"44!!!: "<<cell<<endl;
7255  // for (unsigned int k=0; k<dim; ++k)
7256  // cout<<3*jj+k<<" ";
7257  // cout<<jj+comp_dom.vector_dh.n_dofs()<<" ";
7258  // cout<<jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()<<" ";
7259  // cout<<endl;
7260  // }
7261  //for (unsigned int k=0; k<dim; ++k)
7262  //cout<<"ooo "<<loc_phi_res[i].fastAccessDx(3*j+k)<<endl;
7263  for (unsigned int k=0; k<dim; ++k)
7264  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7265  3*jj+k,
7266  loc_phi_res[i].fastAccessDx(3*j+k));
7267  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7268  jj+comp_dom.vector_dh.n_dofs(),
7269  loc_phi_res[i].fastAccessDx(3*dofs_per_cell+j));
7270  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7271  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7272  loc_phi_res[i].fastAccessDx(4*dofs_per_cell+j));
7273  for (unsigned int k=0; k<dim; ++k)
7274  jacobian_dot_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7275  3*jj+k,
7276  loc_phi_res[i].fastAccessDx(5*dofs_per_cell+3*j+k));
7277  jacobian_dot_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7278  jj+comp_dom.vector_dh.n_dofs(),
7279  loc_phi_res[i].fastAccessDx(8*dofs_per_cell+j));
7280  jacobian_dot_matrix.add(ii+comp_dom.vector_dh.n_dofs(),
7281  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7282  loc_phi_res[i].fastAccessDx(9*dofs_per_cell+j));
7283  }
7284  }
7285 
7286  }
7287  }
7288  if (cell->material_id() != comp_dom.free_sur_ID1 &&
7289  cell->material_id() != comp_dom.free_sur_ID2 &&
7290  cell->material_id() != comp_dom.free_sur_ID3 )
7291  {
7292 
7293  if (cell->material_id() == comp_dom.wall_sur_ID1 ||
7294  cell->material_id() == comp_dom.wall_sur_ID2 ||
7295  cell->material_id() == comp_dom.wall_sur_ID3 )
7296  {
7297  for (unsigned int d=0; d<3; ++d)
7298  {
7299  pressure_force(d)+=loc_pressure_force(d).val();
7300  pressure_moment(d)+=loc_pressure_moment(d).val();
7301  }
7302  for (unsigned int j=0; j<dofs_per_cell; ++j)
7303  {
7304  unsigned int jj = local_dof_indices[j];
7305 
7306  if (is_hull_x_translation_imposed != true)
7307  {
7308  for (unsigned int d=0; d<3; ++d)
7309  jacobian_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7310  3*jj+d,
7311  -loc_pressure_force(0).fastAccessDx(3*j+d));
7312  jacobian_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7313  comp_dom.vector_dh.n_dofs()+jj,
7314  -loc_pressure_force(0).fastAccessDx(j+3*dofs_per_cell));
7315  jacobian_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7316  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7317  -loc_pressure_force(0).fastAccessDx(j+4*dofs_per_cell));
7318  for (unsigned int d=0; d<3; ++d)
7319  jacobian_dot_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7320  3*jj+d,
7321  -loc_pressure_force(0).fastAccessDx(3*j+d+5*dofs_per_cell));
7322  jacobian_dot_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7323  comp_dom.vector_dh.n_dofs()+jj,
7324  -loc_pressure_force(0).fastAccessDx(j+8*dofs_per_cell));
7325  jacobian_dot_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7326  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7327  -loc_pressure_force(0).fastAccessDx(j+9*dofs_per_cell));
7328  }
7329  if (is_hull_y_translation_imposed != true)
7330  {
7331  for (unsigned int d=0; d<3; ++d)
7332  jacobian_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7333  3*jj+d,
7334  -loc_pressure_force(1).fastAccessDx(3*j+d));
7335  jacobian_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7336  comp_dom.vector_dh.n_dofs()+jj,
7337  -loc_pressure_force(1).fastAccessDx(j+3*dofs_per_cell));
7338  jacobian_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7339  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7340  -loc_pressure_force(1).fastAccessDx(j+4*dofs_per_cell));
7341  for (unsigned int d=0; d<3; ++d)
7342  jacobian_dot_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7343  3*jj+d,
7344  -loc_pressure_force(1).fastAccessDx(3*j+d+5*dofs_per_cell));
7345  jacobian_dot_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7346  comp_dom.vector_dh.n_dofs()+jj,
7347  -loc_pressure_force(1).fastAccessDx(j+8*dofs_per_cell));
7348  jacobian_dot_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7349  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7350  -loc_pressure_force(1).fastAccessDx(j+9*dofs_per_cell));
7351  }
7352  if (is_hull_z_translation_imposed != true)
7353  {
7354  for (unsigned int d=0; d<3; ++d)
7355  jacobian_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7356  3*jj+d,
7357  -loc_pressure_force(2).fastAccessDx(3*j+d));
7358  jacobian_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7359  comp_dom.vector_dh.n_dofs()+jj,
7360  -loc_pressure_force(2).fastAccessDx(j+3*dofs_per_cell));
7361  jacobian_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7362  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7363  -loc_pressure_force(2).fastAccessDx(j+4*dofs_per_cell));
7364  for (unsigned int d=0; d<3; ++d)
7365  jacobian_dot_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7366  3*jj+d,
7367  -loc_pressure_force(2).fastAccessDx(3*j+d+5*dofs_per_cell));
7368  jacobian_dot_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7369  comp_dom.vector_dh.n_dofs()+jj,
7370  -loc_pressure_force(2).fastAccessDx(j+8*dofs_per_cell));
7371  jacobian_dot_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7372  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7373  -loc_pressure_force(2).fastAccessDx(j+9*dofs_per_cell));
7374  }
7375 
7376  //if (is_hull_x_translation_imposed != true)
7377  /*
7378  {
7379  for (unsigned int d=0;d<3;++d)
7380  jacobian_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7381  3*jj+d,
7382  -loc_pressure_moment(0).fastAccessDx(3*j+d));
7383  jacobian_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7384  comp_dom.vector_dh.n_dofs()+jj,
7385  -loc_pressure_moment(0).fastAccessDx(j+3*dofs_per_cell));
7386  jacobian_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7387  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7388  -loc_pressure_moment(0).fastAccessDx(j+4*dofs_per_cell));
7389  for (unsigned int d=0;d<3;++d)
7390  jacobian_dot_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7391  3*jj+d,
7392  -loc_pressure_moment(0).fastAccessDx(3*j+d+5*dofs_per_cell));
7393  jacobian_dot_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7394  comp_dom.vector_dh.n_dofs()+jj,
7395  -loc_pressure_moment(0).fastAccessDx(j+8*dofs_per_cell));
7396  jacobian_dot_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7397  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7398  -loc_pressure_moment(0).fastAccessDx(j+9*dofs_per_cell));
7399  }
7400  */
7401  //if (is_hull_y_translation_imposed != true)
7402  {
7403  for (unsigned int d=0; d<3; ++d)
7404  jacobian_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7405  3*jj+d,
7406  -loc_pressure_moment(1).fastAccessDx(3*j+d));
7407  jacobian_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7408  comp_dom.vector_dh.n_dofs()+jj,
7409  -loc_pressure_moment(1).fastAccessDx(j+3*dofs_per_cell));
7410  jacobian_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7411  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7412  -loc_pressure_moment(1).fastAccessDx(j+4*dofs_per_cell));
7413  for (unsigned int d=0; d<3; ++d)
7414  jacobian_dot_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7415  3*jj+d,
7416  -loc_pressure_moment(1).fastAccessDx(3*j+d+5*dofs_per_cell));
7417  jacobian_dot_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7418  comp_dom.vector_dh.n_dofs()+jj,
7419  -loc_pressure_moment(1).fastAccessDx(j+8*dofs_per_cell));
7420  jacobian_dot_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7421  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7422  -loc_pressure_moment(1).fastAccessDx(j+9*dofs_per_cell));
7423  }
7424  /*
7425  //if (is_hull_z_translation_imposed != true)
7426  {
7427  for (unsigned int d=0;d<3;++d)
7428  jacobian_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7429  3*jj+d,
7430  -loc_pressure_moment(2).fastAccessDx(3*j+d));
7431  jacobian_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7432  comp_dom.vector_dh.n_dofs()+jj,
7433  -loc_pressure_moment(2).fastAccessDx(j+3*dofs_per_cell));
7434  jacobian_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7435  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7436  -loc_pressure_moment(2).fastAccessDx(j+4*dofs_per_cell));
7437  for (unsigned int d=0;d<3;++d)
7438  jacobian_dot_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7439  3*jj+d,
7440  -loc_pressure_moment(2).fastAccessDx(3*j+d+5*dofs_per_cell));
7441  jacobian_dot_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7442  comp_dom.vector_dh.n_dofs()+jj,
7443  -loc_pressure_moment(2).fastAccessDx(j+8*dofs_per_cell));
7444  jacobian_dot_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7445  comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+jj,
7446  -loc_pressure_moment(2).fastAccessDx(j+9*dofs_per_cell));
7447  }
7448  */
7449  }
7450 
7451  if (is_hull_x_translation_imposed != true)
7452  {
7453 
7454  for (unsigned int d=0; d<3; ++d)
7455  jacobian_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7456  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7457  -loc_pressure_force(0).fastAccessDx(d+10*dofs_per_cell));
7458  for (unsigned int d=0; d<3; ++d)
7459  jacobian_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7460  d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7461  -loc_pressure_force(0).fastAccessDx(d+3+10*dofs_per_cell));
7462  for (unsigned int d=0; d<3; ++d)
7463  jacobian_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7464  d+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7465  -loc_pressure_force(0).fastAccessDx(d+6+10*dofs_per_cell));
7466  for (unsigned int d=0; d<4; ++d)
7467  jacobian_matrix.add(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7468  d+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7469  -loc_pressure_force(0).fastAccessDx(d+9+10*dofs_per_cell));
7470  }
7471  if (is_hull_y_translation_imposed != true)
7472  {
7473  for (unsigned int d=0; d<3; ++d)
7474  jacobian_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7475  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7476  -loc_pressure_force(1).fastAccessDx(d+10*dofs_per_cell));
7477  for (unsigned int d=0; d<3; ++d)
7478  jacobian_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7479  d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7480  -loc_pressure_force(1).fastAccessDx(d+3+10*dofs_per_cell));
7481  for (unsigned int d=0; d<3; ++d)
7482  jacobian_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7483  d+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7484  -loc_pressure_force(1).fastAccessDx(d+6+10*dofs_per_cell));
7485  for (unsigned int d=0; d<4; ++d)
7486  jacobian_matrix.add(1+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7487  d+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7488  -loc_pressure_force(1).fastAccessDx(d+9+10*dofs_per_cell));
7489  }
7490  if (is_hull_z_translation_imposed != true)
7491  {
7492  for (unsigned int d=0; d<3; ++d)
7493  jacobian_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7494  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7495  -loc_pressure_force(2).fastAccessDx(d+10*dofs_per_cell));
7496  for (unsigned int d=0; d<3; ++d)
7497  jacobian_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7498  d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7499  -loc_pressure_force(2).fastAccessDx(d+3+10*dofs_per_cell));
7500  for (unsigned int d=0; d<3; ++d)
7501  jacobian_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7502  d+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7503  -loc_pressure_force(2).fastAccessDx(d+6+10*dofs_per_cell));
7504  for (unsigned int d=0; d<4; ++d)
7505  jacobian_matrix.add(2+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7506  d+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7507  -loc_pressure_force(2).fastAccessDx(d+9+10*dofs_per_cell));
7508  }
7509 
7510  //if (is_hull_y_translation_imposed != true)
7511  /*
7512  {
7513  for (unsigned int d=0;d<3;++d)
7514  jacobian_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7515  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7516  -loc_pressure_moment(0).fastAccessDx(d+10*dofs_per_cell));
7517  for (unsigned int d=0;d<3;++d)
7518  jacobian_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7519  d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7520  -loc_pressure_moment(0).fastAccessDx(d+3+10*dofs_per_cell));
7521  for (unsigned int d=0;d<3;++d)
7522  jacobian_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7523  d+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7524  -loc_pressure_moment(0).fastAccessDx(d+6+10*dofs_per_cell));
7525  for (unsigned int d=0;d<4;++d)
7526  jacobian_matrix.add(6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7527  d+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7528  -loc_pressure_moment(0).fastAccessDx(d+9+10*dofs_per_cell));
7529  }
7530  */
7531  //if (is_hull_y_translation_imposed != true)
7532  {
7533  for (unsigned int d=0; d<3; ++d)
7534  jacobian_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7535  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7536  -loc_pressure_moment(1).fastAccessDx(d+10*dofs_per_cell));
7537  for (unsigned int d=0; d<3; ++d)
7538  jacobian_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7539  d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7540  -loc_pressure_moment(1).fastAccessDx(d+3+10*dofs_per_cell));
7541  for (unsigned int d=0; d<3; ++d)
7542  jacobian_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7543  d+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7544  -loc_pressure_moment(1).fastAccessDx(d+6+10*dofs_per_cell));
7545  for (unsigned int d=0; d<4; ++d)
7546  jacobian_matrix.add(7+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7547  d+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7548  -loc_pressure_moment(1).fastAccessDx(d+9+10*dofs_per_cell));
7549  }
7550  /*
7551  //if (is_hull_y_translation_imposed != true)
7552  {
7553  for (unsigned int d=0;d<3;++d)
7554  jacobian_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7555  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7556  -loc_pressure_moment(2).fastAccessDx(d+10*dofs_per_cell));
7557  for (unsigned int d=0;d<3;++d)
7558  jacobian_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7559  d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7560  -loc_pressure_moment(2).fastAccessDx(d+3+10*dofs_per_cell));
7561  for (unsigned int d=0;d<3;++d)
7562  jacobian_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7563  d+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7564  -loc_pressure_moment(2).fastAccessDx(d+6+10*dofs_per_cell));
7565  for (unsigned int d=0;d<4;++d)
7566  jacobian_matrix.add(8+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7567  d+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7568  -loc_pressure_moment(2).fastAccessDx(d+9+10*dofs_per_cell));
7569  }
7570  */
7571  }
7572 
7573  for (unsigned int i=0; i<dofs_per_cell; ++i)
7574  {
7575  unsigned int ii = local_dof_indices[i];
7576  for (unsigned int j=0; j<dofs_per_cell; ++j)
7577  {
7578  loc_dphi_dn_res[i] += loc_mass_matrix[i][j]*dphi_dns[j];
7579  }
7580  if (!constraints.is_constrained(ii))
7581  {
7582  dphi_dn_res[ii] += loc_dphi_dn_res[i].val();
7583 
7584  for (unsigned int j=0; j<dofs_per_cell; ++j)
7585  {
7586  unsigned int jj = local_dof_indices[j];
7587  for (unsigned int k=0; k<dim; ++k)
7588  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7589  3*jj+k,
7590  loc_dphi_dn_res[i].fastAccessDx(3*j+k));
7591  for (unsigned int k=0; k<dim; ++k)
7592  jacobian_dot_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7593  3*jj+k,
7594  loc_dphi_dn_res[i].fastAccessDx(5*dofs_per_cell+3*j+k));
7595  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7596  jj+comp_dom.vector_dh.n_dofs(),
7597  loc_dphi_dn_res[i].fastAccessDx(3*dofs_per_cell+j));
7598  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7599  jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7600  loc_dphi_dn_res[i].fastAccessDx(4*dofs_per_cell+j));
7601  }
7602  for (unsigned int k=0; k<dim; ++k)
7603  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7604  k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7605  loc_dphi_dn_res[i].fastAccessDx(k+10*dofs_per_cell));
7606  for (unsigned int k=0; k<dim; ++k)
7607  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7608  k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7609  loc_dphi_dn_res[i].fastAccessDx(k+3+10*dofs_per_cell));
7610  for (unsigned int k=0; k<dim; ++k)
7611  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7612  k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7613  loc_dphi_dn_res[i].fastAccessDx(k+6+10*dofs_per_cell));
7614  for (unsigned int k=0; k<4; ++k)
7615  jacobian_matrix.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
7616  k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7617  loc_dphi_dn_res[i].fastAccessDx(k+9+10*dofs_per_cell));
7618  }
7619  }
7620  }
7621  }
7622  }
7623 
7624 //let's build the residual (and jacobian) on the hull displacements and velocities (differential components)
7625  Point<3> hull_lin_vel_res(0.0,0.0,0.0);
7626  Point<3> hull_lin_displ_res(0.0,0.0,0.0);
7627 
7628  Point<3> g_vec(0.0,0.0,-g);
7629 
7630  hull_lin_vel_res+= comp_dom.boat_model.boat_mass*hull_lin_vel_dot;
7631 // this jacobian will be completed by the derivatives of the pressure force with respect to all the dofs
7632  for (unsigned int d=0; d<3; ++d)
7633  jacobian_dot_matrix.add(d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7634  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7635  comp_dom.boat_model.boat_mass);
7636 
7637 
7638  hull_lin_displ_res+= hull_lin_displ_dot - hull_lin_vel;
7639  for (unsigned int d=0; d<3; ++d)
7640  {
7641  jacobian_dot_matrix.add(d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7642  d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7643  1.0);
7644  jacobian_matrix.add(d+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7645  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7646  -1.0);
7647  }
7648 
7649 //once looping on the cells is over, the pressure force and moment are ready: let's
7650 //add them to the residual for the boat acceleration
7651  cout<<"The current pressure force is: "<<pressure_force<<endl;
7652  cout<<"The current pressure moment is: "<<pressure_moment<<endl;
7653  if (is_hull_x_translation_imposed)
7654  {
7655  Point<1> time(t);
7656  //double accel = hull_x_axis_translation.laplacian(time);
7657  Point<1> delta_t(1e-5);
7658  double accel = ( hull_x_axis_translation.value(time+delta_t) -
7659  2*hull_x_axis_translation.value(time) +
7660  hull_x_axis_translation.value(time+(-1.0*delta_t)) ) / delta_t(0) / delta_t(0);
7661  cout<<"********Test Laplacian x: "<<accel<<endl;
7662  hull_lin_vel_res(0)-= accel*comp_dom.boat_model.boat_mass;
7663  }
7664  else
7665  {
7666  hull_lin_vel_res(0)-= pressure_force(0);
7667  }
7668 
7669  if (is_hull_y_translation_imposed)
7670  {
7671  Point<1> time(t);
7672  //double accel = hull_y_axis_translation.laplacian(time);
7673  Point<1> delta_t(1e-5);
7674  double accel = ( hull_y_axis_translation.value(time+delta_t) -
7675  2*hull_y_axis_translation.value(time) +
7676  hull_y_axis_translation.value(time+(-1.0*delta_t)) ) / delta_t(0) / delta_t(0);
7677  cout<<"********Test Laplacian y: "<<accel<<endl;
7678  hull_lin_vel_res(1)-= accel*comp_dom.boat_model.boat_mass;
7679  }
7680  else
7681  {
7682  hull_lin_vel_res(1)-= pressure_force(1);
7683  }
7684 
7685  if (is_hull_z_translation_imposed)
7686  {
7687  Point<1> time(t);
7688  //double accel = hull_z_axis_translation.laplacian(time);
7689  Point<1> delta_t(1e-5);
7690  double accel = ( hull_z_axis_translation.value(time+delta_t) -
7691  2*hull_z_axis_translation.value(time) +
7692  hull_z_axis_translation.value(time+(-1.0*delta_t)) ) / delta_t(0) / delta_t(0);
7693  //double accel = -0.01*pow(2.0*dealii::numbers::PI,2.0)*sin(2.0*dealii::numbers::PI*t);
7694  cout<<"********Test Laplacian z: "<<accel<<endl;
7695  hull_lin_vel_res(2)-= accel*comp_dom.boat_model.boat_mass;
7696  }
7697  else
7698  {
7699  hull_lin_vel_res(2)-= pressure_force(2);
7700  hull_lin_vel_res(2)-= (-g*comp_dom.boat_model.boat_mass);
7701  cout<<"************ "<<pressure_force(2)<<" vs "<<-g *comp_dom.boat_model.boat_mass<<endl;
7702  }
7703 
7704  Point<3,fad_double> hull_quaternions_vect_res(0.0,0.0,0.0);
7705  fad_double hull_quaternions_scal_res;
7706  fad_double omega_x,omega_y,omega_z,v_x,v_y,v_z,s;
7707  fad_double omega_x_dot,omega_y_dot,omega_z_dot,v_x_dot,v_y_dot,v_z_dot,s_dot;
7708 
7709  omega_x_dot = hull_ang_vel_dot(0);
7710  omega_y_dot = hull_ang_vel_dot(1);
7711  omega_z_dot = hull_ang_vel_dot(2);
7712  v_x_dot = hull_quat_vector_dot(0);
7713  v_y_dot = hull_quat_vector_dot(1);
7714  v_z_dot = hull_quat_vector_dot(2);
7715  s_dot = hull_quat_scalar_dot;
7716  omega_x = hull_ang_vel(0);
7717  omega_y = hull_ang_vel(1);
7718  omega_z = hull_ang_vel(2);
7719  v_x = hull_quat_vector(0);
7720  v_y = hull_quat_vector(1);
7721  v_z = hull_quat_vector(2);
7722  s = hull_quat_scalar;
7723 
7724  omega_x_dot.diff(0,14);
7725  omega_y_dot.diff(1,14);
7726  omega_z_dot.diff(2,14);
7727  v_x_dot.diff(3,14);
7728  v_y_dot.diff(4,14);
7729  v_z_dot.diff(5,14);
7730  s_dot.diff(6,14);
7731  omega_x.diff(7,14);
7732  omega_y.diff(8,14);
7733  omega_z.diff(9,14);
7734  v_x.diff(10,14);
7735  v_y.diff(11,14);
7736  v_z.diff(12,14);
7737  s.diff(13,14);
7738 
7739  Point<3,fad_double> RotMatRow1(1-2*v_y*v_y-2*v_z*v_z, 2*v_x*v_y-2*s*v_z, 2*v_x*v_z+2*s*v_y);
7740  Point<3,fad_double> RotMatRow2(2*v_x*v_y+2*s*v_z, 1-2*v_x*v_x-2*v_z*v_z, 2*v_y*v_z-2*s*v_x);
7741  Point<3,fad_double> RotMatRow3(2*v_x*v_z-2*s*v_y, 2*v_y*v_z+2*s*v_x, 1-2*v_y*v_y-2*v_x*v_x);
7742  Point<3,fad_double> RelInertiaMatRow1(comp_dom.Ixx,comp_dom.Ixy,comp_dom.Ixz);
7743  Point<3,fad_double> RelInertiaMatRow2(comp_dom.Ixy,comp_dom.Iyy,comp_dom.Iyz);
7744  Point<3,fad_double> RelInertiaMatRow3(comp_dom.Ixz,comp_dom.Iyz,comp_dom.Izz);
7745 
7746  Point<3,fad_double> servMatRow1(RotMatRow1*RelInertiaMatRow1, RotMatRow1*RelInertiaMatRow2, RotMatRow1*RelInertiaMatRow3);
7747  Point<3,fad_double> servMatRow2(RotMatRow2*RelInertiaMatRow1, RotMatRow2*RelInertiaMatRow2, RotMatRow2*RelInertiaMatRow3);
7748  Point<3,fad_double> servMatRow3(RotMatRow3*RelInertiaMatRow1, RotMatRow3*RelInertiaMatRow2, RotMatRow3*RelInertiaMatRow3);
7749 
7750  Point<3,fad_double> AbsInertiaMatRow1(servMatRow1*RotMatRow1, servMatRow1*RotMatRow2, servMatRow1*RotMatRow3);
7751  Point<3,fad_double> AbsInertiaMatRow2(servMatRow2*RotMatRow1, servMatRow2*RotMatRow2, servMatRow2*RotMatRow3);
7752  Point<3,fad_double> AbsInertiaMatRow3(servMatRow3*RotMatRow1, servMatRow3*RotMatRow2, servMatRow3*RotMatRow3);
7753 
7754  Point<3,fad_double> omega(omega_x,omega_y,omega_z);
7755 
7756  Point<3,fad_double> WMatRow1( 0.0, -omega_z, omega_y);
7757  Point<3,fad_double> WMatRow2( omega_z, 0.0, -omega_x);
7758  Point<3,fad_double> WMatRow3(-omega_y, omega_x, 0.0);
7759 
7760  Point<3,fad_double> sservMatRow1(WMatRow1*AbsInertiaMatRow1, WMatRow1*AbsInertiaMatRow2, WMatRow1*AbsInertiaMatRow3);
7761  Point<3,fad_double> sservMatRow2(WMatRow2*AbsInertiaMatRow1, WMatRow2*AbsInertiaMatRow2, WMatRow2*AbsInertiaMatRow3);
7762  Point<3,fad_double> sservMatRow3(WMatRow3*AbsInertiaMatRow1, WMatRow3*AbsInertiaMatRow2, WMatRow3*AbsInertiaMatRow3);
7763 
7764  Point<3,fad_double> omega_dot(omega_x_dot,omega_y_dot,omega_z_dot);
7765 
7766  Point<3,fad_double> vv(v_x,v_y,v_z);
7767  vv/=sqrt(v_x*v_x+v_y*v_y+v_z*v_z+s*s);
7768 
7769  fad_double ss = s/sqrt(v_x*v_x+v_y*v_y+v_z*v_z+s*s);
7770 
7771 
7772  Point<3,fad_double> vv_dot(v_x_dot,v_y_dot,v_z_dot);
7773 
7774  Point<3,fad_double> rhs_quat_vect(ss*omega_x+WMatRow1*vv,ss*omega_y+WMatRow2*vv,ss*omega_z+WMatRow1*vv);
7775  /*
7776  Point<3,fad_double> hull_ang_vel_res(omega_x_dot,omega_y_dot,omega_z_dot);
7777 
7778  for (unsigned int k=0; k<3; ++k)
7779  {
7780  jacobian_dot_matrix.add(6+k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7781  6+k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7782  1.0);
7783  }
7784  */
7785 
7786  Point<3,fad_double> hull_ang_vel_res(AbsInertiaMatRow1*omega_dot, AbsInertiaMatRow2*omega_dot, AbsInertiaMatRow3*omega_dot);
7787  hull_ang_vel_res = hull_ang_vel_res + Point<3,fad_double>(sservMatRow1*omega,sservMatRow3*omega,sservMatRow3*omega);
7788 //cout<<"OOOOOOOOOOOOO "<<hull_ang_vel_res<<endl;
7789  for (unsigned int k=0; k<3; ++k)
7790  {
7791  for (unsigned int d=0; d<7; ++d)
7792  jacobian_dot_matrix.add(6+k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7793  6+d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7794  hull_ang_vel_res(k).fastAccessDx(d));
7795  for (unsigned int d=0; d<7; ++d)
7796  jacobian_matrix.add(6+k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7797  6+d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7798  hull_ang_vel_res(k).fastAccessDx(7+d));
7799  }
7800 
7801 //for (unsigned int k=0; k<3; ++k)
7802 // {
7803 // //hull_ang_vel_res(k) = hull_ang_vel_res(k) - 1.0*(t<10.0? t/10.0:1.0)*pressure_moment(k);
7804 // }
7805 //hull_ang_vel_res(1) = hull_ang_vel_res(1) + 25.0*(t<4.0? t/4.0:1.0)*pow(numbers::PI/2.0,2.0)*cos(numbers::PI/2.0*t);
7806  cout<<"Moment Fraction Considered: "<<(t<10.0? 0.0:(t<15.0? (t-10.0)/5.0:1.0))<<endl;
7807  hull_ang_vel_res(1) = hull_ang_vel_res(1) - pressure_moment(1);
7808 
7809  hull_quaternions_scal_res = s_dot + omega*vv/2.0;
7810 
7811  for (unsigned int k=0; k<3; ++k)
7812  {
7813  hull_quaternions_vect_res(k) = vv_dot(k) - rhs_quat_vect(k)/2.0;
7814  }
7815 
7816  for (unsigned int k=0; k<3; ++k)
7817  {
7818  for (unsigned int d=0; d<7; ++d)
7819  jacobian_dot_matrix.add(9+k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7820  6+d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7821  hull_quaternions_vect_res(k).fastAccessDx(d));
7822  for (unsigned int d=0; d<7; ++d)
7823  jacobian_matrix.add(9+k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7824  6+d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7825  hull_quaternions_vect_res(k).fastAccessDx(7+d));
7826  }
7827  for (unsigned int d=0; d<7; ++d)
7828  jacobian_dot_matrix.add(12+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7829  6+d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7830  hull_quaternions_scal_res.fastAccessDx(d));
7831  for (unsigned int d=0; d<7; ++d)
7832  jacobian_matrix.add(12+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7833  6+d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
7834  hull_quaternions_scal_res.fastAccessDx(7+d));
7835 
7836  Vector<double> hull_rigid_modes_res(13);
7837  for (unsigned int k=0; k<3; ++k)
7838  {
7839  hull_rigid_modes_res(k) = hull_lin_vel_res(k);
7840  hull_rigid_modes_res(k+3) = hull_lin_displ_res(k);
7841  hull_rigid_modes_res(k+6) = hull_ang_vel_res(k).val();
7842  }
7843  for (unsigned int k=0; k<3; ++k)
7844  {
7845  hull_rigid_modes_res(k+9) = hull_quaternions_vect_res(k).val();
7846  }
7847  hull_rigid_modes_res(12) = hull_quaternions_scal_res.val();
7848 //for (unsigned int i=0; i<comp_dom.dh.n_dofs();++i)
7849 // cout<<i<<"---> "<<eta_res[i]<<endl;;
7850 
7851  /*
7852  typedef const unsigned int *SparsityPattern::iterator;
7853  if (fabs(t-0.231589)<0.00001)
7854  {
7855  for (unsigned int i=0; i<this->n_dofs(); ++i)
7856  for (SparsityPattern::iterator col=DphiDt_sparsity_pattern.begin(i); col!=DphiDt_sparsity_pattern.end(i); ++col)
7857  {
7858  unsigned int j = col->column();
7859  cout<<" "<<i<<" "<<j<<" "<<DphiDt_sys_matrix(i,j)<<" "<<DphiDt_sys_matrix_2(i,j)<<endl;
7860  }
7861  }
7862  */
7863 
7864 
7865 
7866  SparseMatrix<double> DphiDt_sys_matrix_copy;
7867  DphiDt_sys_matrix_copy.reinit(DphiDt_sparsity_pattern);
7868  DphiDt_sys_matrix_copy.copy_from(DphiDt_sys_matrix);
7869 
7870  SparseMatrix<double> DphiDt_sys_matrix_copy_2;
7871  DphiDt_sys_matrix_copy_2.reinit(DphiDt_sparsity_pattern);
7872  DphiDt_sys_matrix_copy_2.copy_from(DphiDt_sys_matrix_2);
7873 
7874  constraints.condense(DphiDt_sys_matrix,DphiDt_sys_rhs);
7875  constraints.condense(DphiDt_sys_matrix_copy,DphiDt_sys_rhs_2);
7876  constraints.condense(DphiDt_sys_matrix_2,DphiDt_sys_rhs_3);
7877  constraints.condense(DphiDt_sys_matrix_copy_2,DphiDt_sys_rhs_4);
7878 
7879 
7880  SparseDirectUMFPACK DphiDt_direct;
7881  SparseDirectUMFPACK DphiDt_direct_copy;
7882  SparseDirectUMFPACK DphiDt_direct_copy_2;
7883  SparseDirectUMFPACK DphiDt_direct_2;
7884 
7885  DphiDt_direct.initialize(DphiDt_sys_matrix);
7886  DphiDt_direct_copy.initialize(DphiDt_sys_matrix_copy);
7887  DphiDt_direct_copy_2.initialize(DphiDt_sys_matrix_copy_2);
7888  DphiDt_direct_2.initialize(DphiDt_sys_matrix_2);
7889 
7890  DphiDt_direct.vmult(DphiDt_sys_solution, DphiDt_sys_rhs); // solving for phi_dot
7891  constraints.distribute(DphiDt_sys_solution);
7892  //cout<<"---------"<<endl;
7893  //cout<<DphiDt_sys_solution<<endl;
7894  //cout<<"---------"<<endl;
7895  DphiDt_direct_copy.vmult(DphiDt_sys_solution_2, DphiDt_sys_rhs_2); // solving for eta_dot
7896  constraints.distribute(DphiDt_sys_solution_2);
7897  DphiDt_direct_2.vmult(DphiDt_sys_solution_3, DphiDt_sys_rhs_3); // solving for dphi_dn
7898  constraints.distribute(DphiDt_sys_solution_3);
7899  DphiDt_direct_copy_2.vmult(break_wave_press, DphiDt_sys_rhs_4); // solving for eta_dot
7900  constraints.distribute(break_wave_press);
7901 
7902  Vector<double> RES(DphiDt_sys_solution.size());
7903  DphiDt_sys_matrix.vmult(RES,DphiDt_sys_solution_2);
7904  RES*=-1.0;
7905  RES.add(DphiDt_sys_rhs_2);
7906  RES*=-1.0;
7907 
7908  //for (unsigned int i=0; i<comp_dom.dh.n_dofs();i++)
7909  // {
7910  // if (constraints.is_constrained(i) == 0)
7911  // cout<<"*eta_dot("<<i<<") "<<DphiDt_sys_solution_2(i)<<" res("<<i<<") "<<RES(i)<<" eta_res("<<i<<") "<<eta_res[i]<<endl;
7912  // }
7913 //*/
7914 
7915  /*
7916  SparseDirectUMFPACK DphiDt_direct;
7917  SparseDirectUMFPACK DphiDt_direct_2;
7918  SparseDirectUMFPACK DphiDt_direct_3;
7919 
7920  DphiDt_direct.initialize(DphiDt_sys_matrix);
7921  DphiDt_direct_2.initialize(DphiDt_sys_matrix);
7922  DphiDt_direct_3.initialize(DphiDt_sys_matrix_2);
7923 
7924  DphiDt_direct.vmult(DphiDt_sys_solution, DphiDt_sys_rhs);
7925  constraints.distribute(DphiDt_sys_solution);
7926  DphiDt_direct_2.vmult(DphiDt_sys_solution_2, DphiDt_sys_rhs_2);
7927  constraints.distribute(DphiDt_sys_solution_2);
7928  DphiDt_direct_3.vmult(DphiDt_sys_solution_3, DphiDt_sys_rhs_3);
7929  constraints.distribute(DphiDt_sys_solution_3);
7930 
7931  Vector<double> test_phi(comp_dom.dh.n_dofs());
7932  DphiDt_sys_matrix.vmult(test_phi,(const Vector<double>&)phi_time_derivs);
7933 
7934  Vector<double> eta_dot(comp_dom.dh.n_dofs());
7935  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
7936  eta_dot(i) = nodes_velocities(3*i+2);
7937  Vector<double> test_eta(comp_dom.dh.n_dofs());
7938 
7939  Vector<double> test_dphi_dn(comp_dom.dh.n_dofs());
7940  DphiDt_sys_matrix_2.vmult(test_dphi_dn,(const Vector<double>&)dphi_dn);
7941 
7942  //DphiDt_sys_matrix.vmult(test_phi,(const Vector<double>&)phi_time_derivs);
7943  DphiDt_sys_matrix.vmult(test_eta,eta_dot);
7944  */
7945  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
7946  // if ( (sys_comp(i+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs()) == 4) )//&& (fabs(test_phi(i)-DphiDt_sys_rhs(i)-phi_res[i])>1e-15))
7947  // cout<<i<<" "<<test_dphi_dn(i)-DphiDt_sys_rhs_3(i)<<" "<<dphi_dn_res[i]<<" ("<<test_dphi_dn(i)-DphiDt_sys_rhs_3(i)-dphi_dn_res[i]<<")"<<endl;
7948 
7949  //cout<<i<<" "<<test_phi(i)-DphiDt_sys_rhs(i)<<" "<<phi_res[i]<<" ("<<test_phi(i)-DphiDt_sys_rhs(i)-phi_res[i]<<")"<<endl;
7950  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
7951  // if ( (sys_comp(3*i+2) == 1) )//&& (fabs(test_eta(i)-DphiDt_sys_rhs_2(i)-eta_res[i])>1e-15))
7952  // {
7953  // cout<<i<<" "<<test_eta(i)<<" "<<DphiDt_sys_rhs_2(i)<<" ("<<test_eta(i)-DphiDt_sys_rhs_2(i)<<")"<<endl;
7954  //cout<<i<<" "<<test_eta(i)-DphiDt_sys_rhs_2(i)<<" "<<eta_res[i]<<" ("<<test_eta(i)-DphiDt_sys_rhs_2(i)-eta_res[i]<<")"<<endl;
7955  //cout<<DphiDt_sys_solution_2(i)<<" vs "<<eta_dot(i)<<" ---> "<<DphiDt_sys_solution_2(i)-eta_dot(i)<<endl;
7956  // }
7957  double residual_counter_0 = 0;
7958  double residual_counter_1 = 0;
7959  double residual_counter_2 = 0;
7960  double residual_counter_3 = 0;
7961  double residual_counter_4 = 0;
7962  double residual_counter_5 = 0;
7963  double residual_counter_6 = 0;
7964  double residual_counter_7 = 0;
7965  double residual_counter_8 = 0;
7966  double residual_counter_9 = 0;
7967  double residual_counter_10 = 0;
7968  double residual_counter_11 = 0;
7969  double residual_counter_12 = 0;
7970 
7971  for (unsigned int i=0; i<sys_comp.size(); ++i)
7972  switch ((int) sys_comp(i))
7973  {
7974  case 0:
7975  // Alg. X
7976  dst(i) = nodes_pos_res(i);
7977  //if ((fabs(dst(i)) > 1e-4) && fabs(t-1.1)<1e-6)
7978  // std::cout<<"i --> "<<i<<" (0) "<<dst(i)<<" "<<comp_dom.vector_support_points[i]<<std::endl;
7979  residual_counter_0 += fabs(dst(i)*dst(i));
7980  break;
7981  case 1:
7982  dst(i) = eta_res[int((i-2)/3)];
7983  //std::cout<<i<<" --> "<<int((i-2)/3)<<" (1) "<<dst(i)<<" "<<comp_dom.support_points[int((i-2)/3)]<<std::endl;
7984  residual_counter_1 += fabs(dst(i)*dst(i));
7985  break;
7986  case 2:
7987  dst(i) = bem_phi(i-comp_dom.vector_dh.n_dofs()) - src_yy(i);
7988  //std::cout<<"i --> "<<i<<" (2) "<<dst(i)<<std::endl;
7989  residual_counter_2 += fabs(dst(i)*dst(i));
7990  break;
7991  case 3:
7992  dst(i) = phi_res[i-comp_dom.vector_dh.n_dofs()];
7993  //if (fabs(phi_res[i-comp_dom.vector_dh.n_dofs()]) > 1e-5)
7994  //std::cout<<"i --> "<<i<<" (3) "<<dst(i)<<" "<<comp_dom.support_points[i-comp_dom.vector_dh.n_dofs()]<<std::endl;
7995  residual_counter_3 += fabs(dst(i)*dst(i));
7996  break;
7997  case 4:
7998  dst(i) = //bem_dphi_dn(i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs()) - src_yy(i);
7999  dphi_dn_res[i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs()];
8000  //DphiDt_sys_solution_3(i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs()) - src_yy(i);
8001  //std::cout<<"i --> "<<i<<" (4) "<<dst(i)<<std::endl;
8002  residual_counter_4 += fabs(dst(i)*dst(i));
8003  break;
8004  case 5:
8005  dst(i) = bem_dphi_dn(i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs()) - src_yy(i);
8006  //std::cout<<"i --> "<<i<<" (5) "<<dst(i)<<std::endl;
8007  residual_counter_5 += fabs(dst(i)*dst(i));
8008  break;
8009  case 6:
8010  dst(i) = bem_phi(i-comp_dom.vector_dh.n_dofs()) - src_yy(i);
8011  //std::cout<<"i --> "<<i<<" (6) "<<dst(i)<<std::endl;
8012  residual_counter_6 += fabs(dst(i)*dst(i));
8013  break;
8014  case 7:
8015  dst(i) = bem_dphi_dn(i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs()) - src_yy(i);
8016  //bem_residual(i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs());
8017  //std::cout<<"i --> "<<i<<" (7) "<<dst(i)<<std::endl;
8018  residual_counter_7 += fabs(dst(i)*dst(i));
8019  break;
8020  case 8:
8021  dst(i) = x_smoothing_res[int((i)/3)];
8022  //if (dst(i)>1e-6)
8023  // std::cout<<"i --> "<<i<<" (8) "<<dst(i)<<" *** "<<comp_dom.vector_support_points[i]<<std::endl;
8024  residual_counter_8 += fabs(dst(i)*dst(i));
8025  break;
8026  case 9:
8027  dst(i) = y_smoothing_res[int((i-1)/3)];
8028  //std::cout<<"i --> "<<i<<" (9) "<<dst(i)<<std::endl;
8029  residual_counter_9 += fabs(dst(i)*dst(i));
8030  break;
8031  case 10:
8032  dst(i) = bem_phi(i-comp_dom.vector_dh.n_dofs()) - src_yy(i);
8033  //std::cout<<"i --> "<<i<<" (10) "<<dst(i)<<" ("<<bem_phi(i-comp_dom.vector_dh.n_dofs())<<" vs "<<src_yy(i)<<")"<<std::endl;
8034  residual_counter_10 += fabs(dst(i)*dst(i));
8035  break;
8036  case 11:
8037  //cout<<i<<" ++++++ "<<i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs()-comp_dom.dh.n_dofs()<<endl;
8038  dst(i) = hull_rigid_modes_res(i-comp_dom.vector_dh.n_dofs()-comp_dom.dh.n_dofs()-comp_dom.dh.n_dofs());
8039  //std::cout<<"i --> "<<i<<" (11) "<<dst(i)<<" ("<<bem_phi(i-comp_dom.vector_dh.n_dofs())<<" vs "<<src_yy(i)<<")"<<std::endl;
8040  residual_counter_11 += fabs(dst(i)*dst(i));
8041  break;
8042  default:
8043  Assert(false, ExcInternalError());
8044  break;
8045  }
8046  std::cout << "Current total residual: " << dst.l2_norm() << std::endl;
8047  std::cout << "Current generic algebraic coords residual: " << sqrt(residual_counter_0) << std::endl;
8048  std::cout << "Current differential coords residual: " << sqrt(residual_counter_1) << std::endl;
8049  std::cout << "Current algebraic potential residual: " << sqrt(residual_counter_2) << std::endl;
8050  std::cout << "Current differential potential residual: " << sqrt(residual_counter_3) << std::endl;
8051  std::cout << "Current algebraic potential normal gradient residual: " << sqrt(residual_counter_4) << std::endl;
8052  std::cout << "Current algebraic potential normal gradient hanging nodes residual: " << sqrt(residual_counter_5) << std::endl;
8053  std::cout << "Current algebraic potential hanging nodes residual: " << sqrt(residual_counter_6) << std::endl;
8054  std::cout << "Current algebraic potential normal gradient bem residual: " << sqrt(residual_counter_7) << std::endl;
8055  std::cout << "Current algebraic free surface coords x residual: " << sqrt(residual_counter_8) << std::endl;
8056  std::cout << "Current algebraic free surface coords y residual: " << sqrt(residual_counter_9) << std::endl;
8057  std::cout << "Current algebraic pressure/free surf phi residual: " << sqrt(residual_counter_10) << std::endl;
8058  std::cout << "Current differential rigid mode vel residual: " << sqrt(residual_counter_11) << std::endl;
8059  std::cout << "Current differential rigid mode displ residual: " << sqrt(residual_counter_12) << std::endl;
8060  static unsigned int res_evals = 0;
8061  res_evals++;
8062  std::cout << "Residual evaluations: " << res_evals << std::endl;
8063 
8064 
8065 
8066  return 0;
8067 
8068 }
8069 
8072 template <int dim>
8074  const Vector<double> &src_yy,
8075  const Vector<double> &src)
8076 {
8077  Vector<double> src_copy(src);
8078  jacobian_preconditioner_matrix.vmult(dst,src_copy);
8079 
8080  return 0;
8081 }
8082 
8083 
8086 template <int dim>
8088  const Vector<double> &src_yy,
8089  const Vector<double> &src)
8090 {
8091 
8092  jacobian_prec(current_time,dst,src_yy,current_sol_dot,src,1e7);
8093 //for (unsigned int i=0; i<dst.size();++i)
8094 // {
8095 // cout<<" *** "<<i<<" "<<src_yy(i)<<" "<<src(i)<<" "<<dst(i)<<" "<<current_sol_dot(i)<<endl;
8096 // }
8097  return 0;
8098 }
8099 
8100 
8103 template <int dim>
8105  Vector<double> &dst,
8106  const Vector<double> &src_yy,
8107  const Vector<double> &src_yp,
8108  const Vector<double> &src,
8109  const double alpha)
8110 {
8111 
8112  cout<<"alpha (using) "<<alpha<<endl;
8113  SparseDirectUMFPACK prec_direct;
8114  prec_direct.initialize(jacobian_preconditioner_matrix);
8115  prec_direct.vmult(dst,src);
8116 
8117  Vector<double> residual(dst.size());
8118  jacobian_preconditioner_matrix.vmult(residual,dst);
8119  residual *= -1.0;
8120  residual.add(src);
8121 
8122 
8123 
8124  //SolverGMRES<Vector<double> > solver (solver_control,
8125  //SolverGMRES<Vector<double> >::AdditionalData(100));
8126  //solver.solve (jacobian_preconditioner_matrix, dst, src, preconditioner_preconditioner_matrix);
8127 
8128 
8129 // cout<<"----Rullo di tamburi--------"<<endl;
8130 // SolverGMRES<Vector<double> > solver (solver_control,
8131 // SolverGMRES<Vector<double> >::AdditionalData(100));
8132 // solver.solve (*this, dst, src, jacobian_preconditioner_matrix);
8133 // cout<<"----Respirate, prego--------"<<endl;
8134 
8135  cout<<"Inverting preconditioner"<<endl;
8136 
8137  return 0;
8138 }
8139 
8141 template <int dim>
8143 {
8144  setup_jacobian_prec(current_time,src_yy,current_sol_dot,0.0);
8145 //cout<<current_sol_dot<<endl;
8146  return 0;
8147 }
8149 template <int dim>
8151  const Vector<double> &src_yy,
8152  const Vector<double> &src_yp,
8153  const double alpha)
8154 {
8155  cout<<"alpha (building) "<<alpha<<endl;
8156  jacobian_preconditioner_matrix = 0;
8157  preconditioner_preconditioner_matrix = 0;
8158 //int preconditioner_band = 100;
8159  for (unsigned int i=0; i<this->n_dofs(); ++i)
8160  for (SparsityPattern::iterator col=jacobian_sparsity_pattern.begin(i); col!=jacobian_sparsity_pattern.end(i); ++col)
8161  {
8162  unsigned int j = col->column();
8163  //cout<<" "<<i<<" "<<j<<" "<<jacobian_matrix(i,j)+alpha*jacobian_dot_matrix(i,j)<<endl;
8164 
8165  jacobian_preconditioner_matrix.set(i,j,jacobian_matrix(i,j)+alpha*jacobian_dot_matrix(i,j));
8166  }
8167 
8168  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8169  {
8170  if ( (!constraints.is_constrained(i)) &&
8171  ((comp_dom.flags[i] & water) || (comp_dom.flags[i] & pressure)) &&
8172  (!(comp_dom.flags[i] & transom_on_water)) )
8173  {
8174  jacobian_preconditioner_matrix.set(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
8175  i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
8176  1.0);
8177  //cout<<" "<<i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()<<endl;
8178  }
8179  else if ( (!constraints.is_constrained(i)) &&
8180  (!(comp_dom.flags[i] & water)) )
8181  {
8182  jacobian_preconditioner_matrix.set(i+comp_dom.vector_dh.n_dofs(),
8183  i+comp_dom.vector_dh.n_dofs(),
8184  1.0);
8185  //cout<<" "<<i+comp_dom.vector_dh.n_dofs()<<endl;
8186  }
8187  else if (comp_dom.flags[i] & transom_on_water)
8188  {
8189  jacobian_preconditioner_matrix.set(i+comp_dom.vector_dh.n_dofs(),
8190  i+comp_dom.vector_dh.n_dofs(),
8191  1.0);
8192  //cout<<" "<<i+comp_dom.vector_dh.n_dofs()<<endl;
8193  }
8194  }
8195 
8196 
8197 
8198  cout<<"Building preconditioner"<<endl;
8199 
8200  /*
8201  //if (fabs(t-0.08)<0.00001)
8202  {
8203  for (unsigned int i=0; i<this->n_dofs(); ++i)
8204  for (SparsityPattern::iterator c=jacobian_sparsity_pattern.begin(i); c!=jacobian_sparsity_pattern.end(i); ++c)
8205  {
8206  unsigned int j = c->column();
8207  cout<<" "<<i<<" "<<j<<" "<<jacobian_preconditioner_matrix(i,j)<<" "<<jacobian_matrix(i,j)<<endl;
8208  }
8209  }
8210  //*/
8211  return 0;
8212 }
8213 
8214 
8221 template <int dim>
8223 {
8224  if (diff_comp.size() != this->n_dofs())
8225  {
8226 
8227  diff_comp.reinit(this->n_dofs());
8228  alg_comp.reinit(this->n_dofs());
8229  sys_comp.reinit(this->n_dofs());
8230 
8231  // 0: X algebraic (horizontal coors, vertical constrained coors,
8232  // vertical coors not on free surface)
8233  // 1: X differential (vertical non constrained free surface coors)
8234  // 2: phi algebraic (on neumann boundaries, non constrained nodes)
8235  // 3: phi differential (non constrained nodes on dirichlet pressure boundaries / free surface)
8236  // 4: dphi/dn on boat or inflow coming from L2 projection (algebraic)
8237  // 5: dphi/dn algebraic (constrained nodes)
8238  // 6: phi algebraic (on constrained nodes)
8239  // 7: dphi/dn algebraic on water/pressure coming from BEM solution (non constrained nodes)
8240  // 8: X algebraic coming from x position smoothing
8241  // 9: X algebraic coming from y position smoothing
8242  // 10: phi algebraic (imposed equal to water counterpart on pressure side of pressure/water interface)
8243  // 11: rigid body velocities and displacements (differential)
8244 
8245  //let's start with the nodes positions dofs
8246  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8247  {
8248  if (comp_dom.vector_flags[3*i] & water)
8249  // if node is on free surface, nodes have first two components set to algebraic,
8250  // third set to differential (and sys_comp = 1)
8251  {
8252  // we distinguish the cases of internal (x and y given by smoothing)
8253  // and edge (x and y given by geometric treatment) nodes
8254  if ( !(comp_dom.vector_flags[3*i] & edge) )
8255  {
8256  // first component is algebraic and marked with 8 in sys_comp
8257  sys_comp(3*i) = 8;
8258  diff_comp(3*i) = 0;
8259  alg_comp(3*i) = 1;
8260  // second component is algebraic and marked with 9 in sys_comp
8261  sys_comp(3*i+1) = 9;
8262  diff_comp(3*i+1) = 0;
8263  alg_comp(3*i+1) = 1;
8264  // only third component is differential and marked 1 in sys_comp
8265  sys_comp(3*i+2) = 1;
8266  diff_comp(3*i+2) = 1;
8267  alg_comp(3*i+2) = 0;
8268  }
8269  // all other are edges dofs and have first and second algebraic components, third is differential
8270  else
8271  {
8272  // only exception is when node is a transom_on_water and near_inflow nodes. in such case it's all algebraic
8273  if (comp_dom.vector_flags[3*i] & transom_on_water ||
8274  comp_dom.vector_flags[3*i] & near_inflow)
8275  {
8276  for (unsigned int j=0; j<dim; ++j)
8277  {
8278  sys_comp(3*i+j) = 0;
8279  diff_comp(3*i+j) = 0;
8280  alg_comp(3*i+j) = 1;
8281  }
8282  }
8283  else
8284  {
8285  // first component is algebraic and marked with 0 in sys_comp
8286  sys_comp(3*i) = 0;
8287  diff_comp(3*i) = 0;
8288  alg_comp(3*i) = 1;
8289  // second component is algebraic and marked with 0 in sys_comp
8290  sys_comp(3*i+1) = 0;
8291  diff_comp(3*i+1) = 0;
8292  alg_comp(3*i+1) = 1;
8293  // only third component is differential and marked 1 in sys_comp
8294  sys_comp(3*i+2) = 1;
8295  diff_comp(3*i+2) = 1;
8296  alg_comp(3*i+2) = 0;
8297  }
8298  }
8299  }
8300  else
8301  // if node is not on free surface, it's algebraic for sure
8302  {
8303  for (unsigned int j=0; j<dim-1; ++j)
8304  {
8305  sys_comp(3*i+j) = 0;
8306  diff_comp(3*i+j) = 0;
8307  alg_comp(3*i+j) = 1;
8308  }
8309  }
8310  }
8311 
8312 
8313  // let's take care of the potential dofs
8314  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8315  {
8316  if (comp_dom.flags[i] & water)
8317  // if node is on free surface, component is differential
8318  {
8319  // unless node is a transom_on_water node. then it's algebraic
8320  if (comp_dom.flags[i] & transom_on_water)
8321  {
8322  sys_comp(i+comp_dom.vector_dh.n_dofs()) = 2;
8323  diff_comp(i+comp_dom.vector_dh.n_dofs()) = 0;
8324  alg_comp(i+comp_dom.vector_dh.n_dofs()) = 1;
8325  }
8326  else
8327  {
8328  diff_comp(i+comp_dom.vector_dh.n_dofs()) = 1;
8329  alg_comp(i+comp_dom.vector_dh.n_dofs()) = 0;
8330  sys_comp(i+comp_dom.vector_dh.n_dofs()) = 3;
8331  }
8332  }
8333  else
8334  // if node is not on free surface, it's algebraic for sure, unless it's a pressure node
8335  // in that case potential is differential
8336  {
8337  if ( comp_dom.flags[i] & pressure )
8338  {
8339  diff_comp(i+comp_dom.vector_dh.n_dofs()) = 1;
8340  alg_comp(i+comp_dom.vector_dh.n_dofs()) = 0;
8341  sys_comp(i+comp_dom.vector_dh.n_dofs()) = 3;
8342  // pressure node on the free surface must be treated differently
8343  if (comp_dom.flags[i] & near_water)
8344  {
8345  diff_comp(i+comp_dom.vector_dh.n_dofs()) = 0;
8346  alg_comp(i+comp_dom.vector_dh.n_dofs()) = 1;
8347  sys_comp(i+comp_dom.vector_dh.n_dofs()) = 10;
8348  }
8349  }
8350  else
8351  {
8352  diff_comp(i+comp_dom.vector_dh.n_dofs()) = 0;
8353  alg_comp(i+comp_dom.vector_dh.n_dofs()) = 1;
8354  sys_comp(i+comp_dom.vector_dh.n_dofs()) = 2;
8355  }
8356  }
8357  }
8358 
8359  // let's take care of the potential normal derivative dofs
8360  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8361  {
8362  // in this case all dofs are algebraic components
8363  if (!(comp_dom.flags[i] & water) && !(comp_dom.flags[i] & pressure))
8364  {
8365  // neumann boundary condition on boat surface is treated separately
8366  if (constraints.is_constrained(i) )
8367  {
8368  // if node is constrained, it is component 5
8369  diff_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 0;
8370  alg_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 1;
8371  sys_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 5;
8372  }
8373  else
8374  {
8375  // otherwise, it is component 4
8376  diff_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 0;
8377  alg_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 1;
8378  sys_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 4;
8379  }
8380  }
8381  else
8382  {
8383  if (constraints.is_constrained(i) )
8384  {
8385  // if node is constrained, it is component 5 again
8386  diff_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 0;
8387  alg_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 1;
8388  sys_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 5;
8389  }
8390  else
8391  {
8392  // otherwise, it is component 7
8393  diff_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 0;
8394  alg_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 1;
8395  sys_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()) = 7;
8396  }
8397  }
8398  }
8399 
8400 
8401  // all hanging (constrained) nodes are algebraic
8402  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); i++)
8403  {
8404  if (vector_constraints.is_constrained(i))
8405  {
8406  diff_comp(i) = 0;
8407  sys_comp(i) = 0;
8408  alg_comp(i) = 1;
8409  }
8410  }
8411 
8412  // all hanging (constrained) nodes are algebraic
8413  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
8414  {
8415  if (constraints.is_constrained(i))
8416  {
8417  diff_comp(i+comp_dom.vector_dh.n_dofs()) = 0;
8418  sys_comp(i+comp_dom.vector_dh.n_dofs()) = 6;
8419  alg_comp(i+comp_dom.vector_dh.n_dofs()) = 1;
8420  }
8421  }
8422 
8423  // finally, we set the final 13 components, needed to displace the boat hull
8424  for (unsigned int i=0; i<13; ++i)
8425  {
8426  diff_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()) = 1;
8427  sys_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()) = 11;
8428  alg_comp(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()) = 0;
8429  }
8430 
8431 
8432  std::vector<unsigned int> row_lengths(dofs_number);
8433 
8434  for (unsigned int i=0; i<dofs_number; ++i)
8435  row_lengths[i] = 5*comp_dom.dh.max_couplings_between_dofs();
8436 
8437  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()] = dofs_number;
8438  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+1] = dofs_number;
8439  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+2] = dofs_number;
8440  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3] = 2;
8441  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+4] = 2;
8442  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+5] = 2;
8443  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6] = dofs_number;
8444  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+7] = dofs_number;
8445  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+8] = dofs_number;
8446  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+9] = 7;
8447  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+10] = 7;
8448  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+11] = 7;
8449  row_lengths[comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+12] = 7;
8450 
8451 
8452 
8453  //ConstraintMatrix constr;
8454  //constr.clear();
8455  //constr.close();
8456 
8457  // we initialize here the jacobian
8458  // sparsity patterns
8459 
8460  jacobian_sparsity_pattern.reinit(dofs_number,
8461  dofs_number,
8462  row_lengths);
8463 
8464  cell_it
8465  cell = comp_dom.dh.begin_active(),
8466  endc = comp_dom.dh.end();
8467 
8468  const unsigned int dofs_per_cell = comp_dom.fe.dofs_per_cell;
8469  std::vector<unsigned int> local_dof_indices(dofs_per_cell);
8470 
8471  for (; cell!=endc; ++cell)
8472  {
8473  cell->get_dof_indices(local_dof_indices);
8474  for (unsigned int i=0; i<dofs_per_cell; ++i)
8475  {
8476  unsigned int ii = local_dof_indices[i];
8477  if (comp_dom.flags[ii] & transom_on_water)
8478  {
8479  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[ii];
8480  jacobian_sparsity_pattern.add(3*ii,3*ii);
8481  jacobian_sparsity_pattern.add(3*ii+1,3*ii+1);
8482  jacobian_sparsity_pattern.add(3*ii+2,3*ii+2);
8483  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos!=duplicates.end(); ++pos)
8484  {
8485  unsigned int jj=*pos;
8486  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8487  }
8488  }
8489 
8490  for (unsigned int j=0; j<dofs_per_cell; ++j)
8491  {
8492  unsigned int jj = local_dof_indices[j];
8493  jacobian_sparsity_pattern.add(3*ii,3*jj);
8494  jacobian_sparsity_pattern.add(3*ii,3*jj+1);
8495  jacobian_sparsity_pattern.add(3*ii,3*jj+2);
8496  jacobian_sparsity_pattern.add(3*ii,jj+comp_dom.vector_dh.n_dofs());
8497  jacobian_sparsity_pattern.add(3*ii,jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8498 
8499  jacobian_sparsity_pattern.add(3*ii+1,3*jj);
8500  jacobian_sparsity_pattern.add(3*ii+1,3*jj+1);
8501  jacobian_sparsity_pattern.add(3*ii+1,3*jj+2);
8502  jacobian_sparsity_pattern.add(3*ii+1,jj+comp_dom.vector_dh.n_dofs());
8503  jacobian_sparsity_pattern.add(3*ii+1,jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8504 
8505  jacobian_sparsity_pattern.add(3*ii+2,3*jj);
8506  jacobian_sparsity_pattern.add(3*ii+2,3*jj+1);
8507  jacobian_sparsity_pattern.add(3*ii+2,3*jj+2);
8508  jacobian_sparsity_pattern.add(3*ii+2,jj+comp_dom.vector_dh.n_dofs());
8509  jacobian_sparsity_pattern.add(3*ii+2,jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8510 
8511  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs(),3*jj);
8512  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs(),3*jj+1);
8513  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs(),3*jj+2);
8514  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs(),jj+comp_dom.vector_dh.n_dofs());
8515  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs(),jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8516 
8517  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),3*jj);
8518  jacobian_sparsity_pattern.add(ii+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),3*jj+1);
8519  jacobian_sparsity_pattern.add(ii+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),3*jj+2);
8520  jacobian_sparsity_pattern.add(ii+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),jj+comp_dom.vector_dh.n_dofs());
8521  jacobian_sparsity_pattern.add(ii+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs(),jj+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8522  //cout<<ii+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs()<<","<<3*jj<<endl;
8523  //cout<<ii+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs()<<","<<3*jj+1<<endl;
8524  //cout<<ii+comp_dom.dh.n_dofs()+comp_dom.vector_dh.n_dofs()<<","<<3*jj+2<<endl;
8525  }
8526  // this is for the dependence of positions, phi and dphi_dn on the rigid modes
8527  for (unsigned int d=0; d<13; ++d)
8528  {
8529  for (unsigned int k=0; k<3; ++k)
8530  {
8531  jacobian_sparsity_pattern.add(3*ii+k,d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8532  }
8533  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs(),
8534  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8535  jacobian_sparsity_pattern.add(ii+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
8536  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8537  }
8538  }
8539  }
8540 
8541  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
8542  {
8543  if (vector_constraints.is_constrained(i))
8544  {
8545  jacobian_sparsity_pattern.add(i,i);
8546  std::vector< std::pair< unsigned int, double > > entries = *vector_constraints.get_constraint_entries(i);
8547  for (unsigned int k=0; k<entries.size(); ++k)
8548  {
8549  jacobian_sparsity_pattern.add(i,entries[k].first);
8550  }
8551  }
8552  }
8553 
8554  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8555  {
8556  if (constraints.is_constrained(i))
8557  {
8558  jacobian_sparsity_pattern.add(i+comp_dom.vector_dh.n_dofs(),i+comp_dom.vector_dh.n_dofs());
8559  jacobian_sparsity_pattern.add(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8560  std::vector< std::pair< unsigned int, double > > entries = *constraints.get_constraint_entries(i);
8561  for (unsigned int k=0; k<entries.size(); ++k)
8562  {
8563  jacobian_sparsity_pattern.add(i+comp_dom.vector_dh.n_dofs(),entries[k].first+comp_dom.vector_dh.n_dofs());
8564  jacobian_sparsity_pattern.add(i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs(),
8565  entries[k].first+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8566  }
8567  }
8568  }
8569 
8570  //this takes care of the left water line nodes projection (without smoothing)
8571  if (!comp_dom.no_boat)
8572  {
8573  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8574  {
8575  if ( (comp_dom.flags[i] & water) &&
8576  (comp_dom.flags[i] & near_boat) &&
8577  (comp_dom.flags[i] & left_side) &&
8578  (comp_dom.moving_point_ids[0] != i) &&
8579  (comp_dom.moving_point_ids[1] != i) &&
8580  (comp_dom.moving_point_ids[2] != i) ) // to avoid the bow and stern node
8581  {
8582  //cout<<"**** "<<i<<endl;
8583 
8584  jacobian_sparsity_pattern.add(3*i,3*i);
8585  jacobian_sparsity_pattern.add(3*i,3*i+1);
8586  jacobian_sparsity_pattern.add(3*i,3*i+2);
8587  jacobian_sparsity_pattern.add(3*i+1,3*i+1);
8588  jacobian_sparsity_pattern.add(3*i+1,3*i+2);
8589  jacobian_sparsity_pattern.add(3*i+1,3*i);
8590  //cout<<i<<" "<<temp_src(3*i+1)<<" ("<<comp_dom.iges_normals[i]<<")"<<endl;
8591  }
8592  }
8593  //this takes care of the bow and stern nodes
8594  for (unsigned int k=0; k<3; ++k)
8595  {
8596  unsigned int i = comp_dom.moving_point_ids[k];
8597 
8598  jacobian_sparsity_pattern.add(3*i,3*i);
8599  jacobian_sparsity_pattern.add(3*i,3*i+2);
8600  jacobian_sparsity_pattern.add(3*i+1,3*i+1);
8601  jacobian_sparsity_pattern.add(3*i+1,3*i+2);
8602  //cout<<i<<" (point) "<<comp_dom.support_points[i]<<endl;
8603  //cout<<i<<" (edges_tangents) "<<comp_dom.edges_tangents(3*i)<<","<<comp_dom.edges_tangents(3*i+1)<<","<<comp_dom.edges_tangents(3*i+2)<<endl;
8604  }
8605  }
8606 
8607  // this cycle hooks the boat and far field double nodes
8608  // to their water twins that have been moved
8609  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8610  {
8611  if ( (comp_dom.flags[i] & water) &&
8612  (comp_dom.flags[i] & edge) )
8613  {
8614  //cout<<"c "<<i<<endl;
8615  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
8616  duplicates.erase(i);
8617  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
8618  {
8619  for (unsigned int k=0; k<3; ++k)
8620  {
8621  jacobian_sparsity_pattern.add(3*(*pos)+k,3*(*pos)+k);
8622  if (comp_dom.flags[i] & transom_on_water)
8623  {
8624  for (unsigned int d=0; d<3; ++d)
8625  jacobian_sparsity_pattern.add(3*(*pos)+k,3*i+d);
8626  for (unsigned int d=0; d<3; ++d)
8627  jacobian_sparsity_pattern.add(3*(*pos)+k,comp_dom.vector_dh.n_dofs()+
8628  comp_dom.dh.n_dofs()+
8629  comp_dom.dh.n_dofs()+3+d);
8630  for (unsigned int d=0; d<4; ++d)
8631  jacobian_sparsity_pattern.add(3*(*pos)+k,comp_dom.vector_dh.n_dofs()+
8632  comp_dom.dh.n_dofs()+
8633  comp_dom.dh.n_dofs()+9+d);
8634  }
8635  else
8636  {
8637  jacobian_sparsity_pattern.add(3*(*pos)+k,3*i+k);
8638  }
8639  }
8640  }
8641  }
8642  }
8643 
8644  // this cycle is to impose the value of potential on the pressure
8645  // side of pressure/free surface interface
8646  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8647  {
8648  if ( (comp_dom.flags[i] & pressure) &&
8649  (comp_dom.flags[i] & near_water) )
8650  {
8651  //cout<<"c "<<i<<endl;
8652  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
8653  duplicates.erase(i);
8654  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
8655  {
8656  if (comp_dom.flags[*pos] & water)
8657  {
8658  jacobian_sparsity_pattern.add(comp_dom.vector_dh.n_dofs()+i,comp_dom.vector_dh.n_dofs()+ *pos);
8659  jacobian_sparsity_pattern.add(comp_dom.vector_dh.n_dofs()+i,comp_dom.vector_dh.n_dofs()+i);
8660  }
8661  }
8662  }
8663  }
8664 
8665  // here's the rigid body part of the dofs jacobian sparsity pattern
8666  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8667  {
8668  if ( comp_dom.flags[i] & boat )
8669  {
8670  for (unsigned int k=0; k<3; ++k)
8671  {
8672  jacobian_sparsity_pattern.add(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8673  3*i);
8674  jacobian_sparsity_pattern.add(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8675  3*i+1);
8676  jacobian_sparsity_pattern.add(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8677  3*i+2);
8678  jacobian_sparsity_pattern.add(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8679  i+comp_dom.vector_dh.n_dofs());
8680  jacobian_sparsity_pattern.add(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8681  i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8682  jacobian_sparsity_pattern.add(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8683  3*i);
8684  jacobian_sparsity_pattern.add(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8685  3*i+1);
8686  jacobian_sparsity_pattern.add(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8687  3*i+2);
8688  jacobian_sparsity_pattern.add(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8689  i+comp_dom.vector_dh.n_dofs());
8690  jacobian_sparsity_pattern.add(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8691  i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8692 
8693  }
8694  }
8695  }
8696 
8697  for (unsigned int k=0; k<3; ++k)
8698  for (unsigned int d=0; d<13; ++d)
8699  {
8700  jacobian_sparsity_pattern.add(k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8701  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8702  jacobian_sparsity_pattern.add(k+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8703  d+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8704 
8705  }
8706 
8707  for (unsigned int k=0; k<3; ++k)
8708  {
8709  jacobian_sparsity_pattern.add(k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8710  k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8711  jacobian_sparsity_pattern.add(k+3+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8712  k+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8713  }
8714 
8715  for (unsigned int k=0; k<4; ++k)
8716  {
8717  for (unsigned int d=0; d<7; ++d)
8718  {
8719  jacobian_sparsity_pattern.add(k+9+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs(),
8720  d+6+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs());
8721  }
8722  }
8723 
8724  jacobian_sparsity_pattern.compress();
8725  jacobian_matrix.reinit(jacobian_sparsity_pattern);
8726  jacobian_dot_matrix.reinit(jacobian_sparsity_pattern);
8727  jacobian_preconditioner_matrix.reinit(jacobian_sparsity_pattern);
8728  preconditioner_preconditioner_matrix.reinit(jacobian_sparsity_pattern);
8729 
8730 
8731 //*/
8732 
8733  }
8734 
8735  return diff_comp;
8736 }
8737 
8738 
8739 
8740 
8741 
8742 
8743 template <int dim>
8745  Vector<double> &bem_bc,
8746  Vector<double> &dphi_dn) const
8747 {
8748 
8749  // we first compute the vectors surface_nodes and other_nodes
8750  // with flags for the Dirichlet (free surface) and Neumann (other)
8751  // nodes for the bem_problem class
8752  cell_it
8753  cell = comp_dom.dh.begin_active(),
8754  endc = comp_dom.dh.end();
8755 
8756  comp_dom.surface_nodes.reinit(comp_dom.dh.n_dofs());
8757  comp_dom.other_nodes.reinit(comp_dom.dh.n_dofs());
8758  comp_dom.other_nodes.add(1);
8759  std::vector<unsigned int> dofs(comp_dom.fe.dofs_per_cell);
8760 
8761  for (; cell != endc; ++cell)
8762  {
8763  if (cell->material_id() == comp_dom.free_sur_ID1 ||
8764  cell->material_id() == comp_dom.free_sur_ID2 ||
8765  cell->material_id() == comp_dom.free_sur_ID3)
8766  {
8767  // This is a free surface node.
8768  cell->get_dof_indices(dofs);
8769  for (unsigned int i=0; i<comp_dom.fe.dofs_per_cell; ++i)
8770  {
8771  comp_dom.surface_nodes(dofs[i]) = 1;
8772  comp_dom.other_nodes(dofs[i]) = 0;
8773  }
8774  }
8775  else
8776  {
8777  for (unsigned int i=0; i<comp_dom.fe.dofs_per_cell; ++i)
8778  {
8779  cell->get_dof_indices(dofs);
8780  }
8781  }
8782  }
8783 
8784 
8785  cell = comp_dom.dh.begin_active();
8786 
8787 
8788  std::vector<Point<dim> > support_points(comp_dom.dh.n_dofs());
8789  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.dh, support_points);
8790 
8791  const unsigned int dofs_per_cell = comp_dom.fe.dofs_per_cell;
8792  std::vector<unsigned int> local_dof_indices (dofs_per_cell);
8793  for (cell = comp_dom.dh.begin_active(); cell != endc; ++cell)
8794  {
8795  cell->get_dof_indices(local_dof_indices);
8796  for (unsigned int j=0; j<comp_dom.fe.dofs_per_cell; ++j)
8797  {
8798  if (cell->material_id() != comp_dom.free_sur_ID1 &&
8799  cell->material_id() != comp_dom.free_sur_ID2 &&
8800  cell->material_id() != comp_dom.free_sur_ID3 )
8801  {
8802  if (cell->material_id() == comp_dom.wall_sur_ID1 ||
8803  cell->material_id() == comp_dom.wall_sur_ID2 ||
8804  cell->material_id() == comp_dom.wall_sur_ID3)
8805  {
8806  Vector<double> wind_value(dim);
8807  wind.vector_value(support_points[local_dof_indices[j]],wind_value);
8808  Point<dim> Vinf;
8809  for (unsigned int i = 0; i < dim; i++)
8810  Vinf(i) = wind_value(i);
8812  // needs to be changed
8813  //Point<3> original(support_points[local_dof_indices[j]](0),
8814  // fabs(support_points[local_dof_indices[j]](1)),
8815  // support_points[local_dof_indices[j]](2));
8816  //Point<3> projection;
8817  //Point<3> normal;
8818  //double mean_curvature;
8819  //comp_dom.boat_model.boat_water_line_right->axis_projection_and_diff_forms(projection, normal, mean_curvature, original);
8820  //double b = support_points[local_dof_indices[j]](1) < 0.0 ? -1.0 : 1.0;
8821  //projection(1)*=b;
8822  //normal(1)*=b;
8823 
8824  //BoatSurface<3> boat_surface;
8825  //Point<3> normal2 = boat_surface.HullNormal(support_points[local_dof_indices[j]]);
8826  //std::cout<<std::endl;
8827  //std::cout<<local_dof_indices[j]<<" Point "<<support_points[local_dof_indices[j]]<<std::endl;
8828  //std::cout<<"NormalNew "<<comp_dom.iges_normals[local_dof_indices[j]]<<std::endl;
8829  //std::cout<<"NormalExact "<<normal2<<std::endl;
8830  //std::cout<<"Error "<<normal2.distance(comp_dom.iges_normals[local_dof_indices[j]])<<std::endl;
8832  //bem_bc(local_dof_indices[j]) = -comp_dom.iges_normals[local_dof_indices[j]]*Vinf;
8833  bem_bc(local_dof_indices[j]) = -comp_dom.node_normals[local_dof_indices[j]]*Vinf;
8834  dphi_dn(local_dof_indices[j]) = bem_bc(local_dof_indices[j]);
8835  //std::cout<<bem_bc(local_dof_indices[j])<<" "<<dphi_dn(local_dof_indices[j])<<" "<<Vinf<<std::endl;
8836  }
8837  else if (cell->material_id() == comp_dom.inflow_sur_ID1 ||
8838  cell->material_id() == comp_dom.inflow_sur_ID2 ||
8839  cell->material_id() == comp_dom.inflow_sur_ID3)
8840  {
8841  bem_bc(local_dof_indices[j]) = inflow_norm_potential_grad.value(support_points[local_dof_indices[j]]);
8842  dphi_dn(local_dof_indices[j]) = inflow_norm_potential_grad.value(support_points[local_dof_indices[j]]);
8843  cout<<inflow_norm_potential_grad.value(support_points[local_dof_indices[j]])<<endl;
8844  }
8845  else
8846  {
8847  bem_bc(local_dof_indices[j]) = 0;
8848  dphi_dn(local_dof_indices[j]) = 0;
8849  }
8850  }
8851  else
8852  {
8853 
8854  }
8855 
8856  }
8857 
8858 
8859  }
8860 
8861  // trying a fix for transom stern nodes
8862  Vector<double> wind_value(dim);
8863  wind.vector_value(Point<3>(0.0,0.0,0.0),wind_value);
8864  Point<dim> Vinf;
8865  for (unsigned int i = 0; i < dim; i++)
8866  Vinf(i) = wind_value(i);
8867  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
8868  {
8869  if ( comp_dom.flags[i] & transom_on_water )
8870  {
8871  comp_dom.surface_nodes(i) = 0;
8872  comp_dom.other_nodes(i) = 1;
8873  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[i];
8874  duplicates.erase(i);
8875  bem_bc(i) = 0;
8876  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
8877  bem_bc(i) += bem_dphi_dn(*pos)/duplicates.size();
8878  dphi_dn(i) = bem_bc(i);
8879  }
8880  }
8881 
8882 
8883 }
8884 
8885 
8886 // @sect4{BEMProblem::compute_gradient}
8887 
8888 // The next function simply solves
8889 // computes the gradient of the potential
8890 // (velocity field in fluid dynamics).
8891 template <int dim>
8893  const Vector<double> &phi,
8894  const Vector<double> &dphi_dn,
8895  const Vector<double> &nodes_velocities)
8896 {
8897  ConstraintMatrix constr;
8898  ConstraintMatrix vector_constr;
8899 
8900  constr.clear();
8901  vector_constr.clear();
8902 
8903 
8904  constr.close();
8905  vector_constr.close();
8906 
8907  std::vector<unsigned int> vector_dofs(comp_dom.vector_fe.dofs_per_cell);
8908  std::vector<Point<dim> > vector_support_points(comp_dom.vector_dh.n_dofs());
8909  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.vector_dh, vector_support_points);
8910 
8911  DXDt_and_DphiDt_vector.reinit(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
8912 
8913  Vector<double> elevations(comp_dom.dh.n_dofs());
8914  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
8915  {
8916  elevations(i) = vector_support_points[dim*i](dim-1);
8917  }
8918 
8919  //for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
8920  // {
8921  // cout<<i<<" "<<dphi_dn(i)<<endl;
8922  // }
8923 
8924  DphiDt_sys_matrix.reinit (DphiDt_sparsity_pattern);
8925  DphiDt_sys_matrix_2.reinit (DphiDt_sparsity_pattern);
8926  vector_sys_matrix.reinit (vector_sparsity_pattern);
8927 
8928  DphiDt_sys_solution.reinit (comp_dom.dh.n_dofs());
8929  DphiDt_sys_solution_2.reinit (comp_dom.dh.n_dofs());
8930  DphiDt_sys_solution_3.reinit (comp_dom.dh.n_dofs());
8931  break_wave_press.reinit (comp_dom.dh.n_dofs());
8932  vector_sys_solution.reinit (comp_dom.vector_dh.n_dofs());
8933  vector_sys_solution_2.reinit (comp_dom.vector_dh.n_dofs());
8934 
8935  DphiDt_sys_rhs.reinit (comp_dom.dh.n_dofs());
8936  DphiDt_sys_rhs_2.reinit (comp_dom.dh.n_dofs());
8937  DphiDt_sys_rhs_3.reinit (comp_dom.dh.n_dofs());
8938  DphiDt_sys_rhs_4.reinit (comp_dom.dh.n_dofs());
8939  vector_sys_rhs.reinit (comp_dom.vector_dh.n_dofs());
8940  vector_sys_rhs_2.reinit (comp_dom.vector_dh.n_dofs());
8941 
8942  FEValues<dim-1,dim> vector_fe_v(*comp_dom.mapping, comp_dom.vector_fe, *comp_dom.quadrature,
8943  update_values | update_gradients |
8944  update_cell_normal_vectors |
8945  update_quadrature_points |
8946  update_JxW_values);
8947 
8948  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
8949  update_values | update_gradients |
8950  update_cell_normal_vectors |
8951  update_quadrature_points |
8952  update_JxW_values);
8953 
8954  const unsigned int DphiDt_n_q_points = fe_v.n_quadrature_points;
8955  const unsigned int DphiDt_dofs_per_cell = comp_dom.fe.dofs_per_cell;
8956  std::vector<unsigned int> DphiDt_local_dof_indices (DphiDt_dofs_per_cell);
8957 
8958  FullMatrix<double> local_DphiDt_matrix (DphiDt_dofs_per_cell, DphiDt_dofs_per_cell);
8959  Vector<double> local_DphiDt_rhs (DphiDt_dofs_per_cell);
8960  Vector<double> local_DphiDt_rhs_2 (DphiDt_dofs_per_cell);
8961 
8962  const unsigned int vector_n_q_points = vector_fe_v.n_quadrature_points;
8963  const unsigned int vector_dofs_per_cell = comp_dom.vector_fe.dofs_per_cell;
8964  std::vector<unsigned int> vector_local_dof_indices (vector_dofs_per_cell);
8965 
8966  FullMatrix<double> local_vector_matrix (vector_dofs_per_cell, vector_dofs_per_cell);
8967  Vector<double> local_vector_rhs (vector_dofs_per_cell);
8968  Vector<double> local_vector_rhs_2 (vector_dofs_per_cell);
8969  Vector<double> local_vector_gradients (vector_dofs_per_cell);
8970  Vector<double> local_vector_normals (vector_dofs_per_cell);
8971 
8972 
8973  std::vector< Tensor<1,dim> > vector_phi_surf_grads(DphiDt_n_q_points);
8974  std::vector< Tensor<1,dim> > vector_eta_surf_grads(DphiDt_n_q_points);
8975  std::vector<double> vector_phi_norm_grads(vector_n_q_points);
8976  std::vector<Vector<double> > quad_nodes_velocities(vector_n_q_points,
8977  Vector<double>(dim));
8978 
8979  std::vector< Tensor<1,dim> > DphiDt_phi_surf_grads(vector_n_q_points);
8980  std::vector< Tensor<1,dim> > DphiDt_eta_surf_grads(vector_n_q_points);
8981  std::vector<double> DphiDt_phi_norm_grads(DphiDt_n_q_points);
8982 
8983 
8984 
8985  cell_it
8986  vector_cell = comp_dom.vector_dh.begin_active(),
8987  vector_endc = comp_dom.vector_dh.end();
8988 
8989  cell_it
8990  cell = comp_dom.dh.begin_active(),
8991  endc = comp_dom.dh.end();
8992 
8993 
8994 
8995  std::vector<Point<dim> > support_points(comp_dom.dh.n_dofs());
8996  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.dh, support_points);
8997 
8998 
8999  for (; cell!=endc,vector_cell!=vector_endc; ++cell,++vector_cell)
9000  {
9001  Assert(cell->index() == vector_cell->index(), ExcInternalError());
9002  //cout<<"Original "<<cell<<endl;
9003  vector_fe_v.reinit (vector_cell);
9004  fe_v.reinit(cell);
9005  local_DphiDt_matrix = 0;
9006  local_DphiDt_rhs = 0;
9007  local_DphiDt_rhs_2 = 0;
9008  local_vector_matrix = 0;
9009  local_vector_rhs = 0;
9010  local_vector_rhs_2 = 0;
9011  //cell->get_dof_indices (DphiDt_local_dof_indices);
9012  //for (unsigned int i=0; i<DphiDt_dofs_per_cell; ++i)
9013  //{
9014  //phis[i] = phi(local_dof_indices[i]);
9015  //phis[i].diff(i+3*dofs_per_cell,5*dofs_per_cell);
9016  //dphi_dns[i] = dphi_dn(local_dof_indices[i]);
9017  //dphi_dns[i].diff(i+4*dofs_per_cell,5*dofs_per_cell);
9018  //std::cout<<i<<"--> "<<DphiDt_local_dof_indices[i]<<"--------->"<<phi(DphiDt_local_dof_indices[i])<<" "<<dphi_dn(DphiDt_local_dof_indices[i])<<endl;
9019  //}
9020 
9021 
9022  fe_v.get_function_gradients((const Vector<double> &)phi, DphiDt_phi_surf_grads);
9023  fe_v.get_function_values(dphi_dn, DphiDt_phi_norm_grads);
9024  fe_v.get_function_gradients((const Vector<double> &)phi, vector_phi_surf_grads);
9025  fe_v.get_function_gradients(elevations, vector_eta_surf_grads);
9026  fe_v.get_function_values(dphi_dn, vector_phi_norm_grads);
9027  vector_fe_v.get_function_values(nodes_velocities, quad_nodes_velocities);
9028 
9029  const std::vector<Point<dim> > &DphiDt_node_normals = fe_v.get_normal_vectors();
9030  const std::vector<Point<dim> > &DphiDt_node_positions = fe_v.get_quadrature_points();
9031  const std::vector<Point<dim> > &vector_node_normals = vector_fe_v.get_normal_vectors();
9032  const std::vector<Point<dim> > &vector_node_positions = vector_fe_v.get_quadrature_points();
9033 
9034  double g = 9.81;
9035 
9036  std::vector<Vector<double> > DphiDt_wind_values(DphiDt_n_q_points);
9037  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
9038  {
9039  DphiDt_wind_values[q].reinit(dim,true);
9040  wind.vector_value(DphiDt_node_positions[q],DphiDt_wind_values[q]);
9041  }
9042  std::vector<Vector<double> > vector_wind_values(DphiDt_n_q_points);
9043  for (unsigned int q=0; q<vector_n_q_points; ++q)
9044  {
9045  vector_wind_values[q].reinit(dim,true);
9046  wind.vector_value(vector_node_positions[q], vector_wind_values[q]);
9047  }
9048 
9049  unsigned int comp_i, comp_j;
9050  Point<dim> ez(0,0,1);
9051  for (unsigned int q=0; q<vector_n_q_points; ++q)
9052  {
9053  Point<dim> gradient = vector_node_normals[q]*vector_phi_norm_grads[q] + vector_phi_surf_grads[q];
9054 
9055  //std::cout<<gradient<<std::endl;
9056  //double nu_0 = 1.0;
9057  double nu_0 = 0;
9058  double damping = nu_0 *
9059  pow((fmax(abs(vector_node_positions[q](0)),20)-20)/(31.169752-20),2) *
9060  vector_phi_norm_grads[q];
9061 // double damping = nu_0 *
9062 // pow((fmax(abs(vector_node_positions[q](0)),25)-25)/(25),2) *
9063 // vector_node_positions[q](2);
9064 
9065 
9066  Point<dim> Vinf;
9067  for (unsigned int i = 0; i < dim; i++)
9068  Vinf(i) = vector_wind_values[q](i);
9069  Point<dim> eta_grad = Point<dim>(0,0,0);
9070  //eta_grad(0) = -vector_node_normals[q](0)/vector_node_normals[q](2);
9071  //eta_grad(1) = -vector_node_normals[q](1)/vector_node_normals[q](2);
9072  eta_grad = eta_grad + vector_eta_surf_grads[q];
9073  eta_grad(dim-1) = 0;
9074 
9075  double fluid_vel_norm = (gradient+Vinf).norm();
9076  if (fluid_vel_norm < 1e-3)
9077  fluid_vel_norm = -8.0e+05*pow(fluid_vel_norm,3.0) + 1.7e+03*pow(fluid_vel_norm,2.0) + 0.0001;
9078  Point<dim> velocity_unit_vect = (gradient+Vinf)/fluid_vel_norm;
9079 
9080  const double delta = cell->diameter()/sqrt(2);
9081  for (unsigned int i=0; i<vector_dofs_per_cell; ++i)
9082  {
9083  double supg_shape_fun = 1.0*(delta)*vector_fe_v.shape_grad(i, q)*velocity_unit_vect;
9084  comp_i = comp_dom.vector_fe.system_to_component_index(i).first;
9085  for (unsigned int j=0; j<vector_dofs_per_cell; ++j)
9086  {
9087  comp_j = comp_dom.vector_fe.system_to_component_index(j).first;
9088  if (comp_i == comp_j)
9089  local_vector_matrix(i,j) += ( (vector_fe_v.shape_value(i, q)+supg_shape_fun)*
9090  vector_fe_v.shape_value(j, q) ) *
9091  vector_fe_v.JxW(q);
9092  }
9093 
9094  if ( (cell->material_id() == comp_dom.free_sur_ID1 ||
9095  cell->material_id() == comp_dom.free_sur_ID2 ||
9096  cell->material_id() == comp_dom.free_sur_ID3 ) )
9097  {
9098  Point<dim> u(quad_nodes_velocities[q](0),quad_nodes_velocities[q](1),quad_nodes_velocities[q](2));
9099  double dEta_dt = gradient[dim-1] + (u-gradient-Vinf)*eta_grad-damping;
9100  //cout<<q<<" "<<i<<" "<<gradient[dim-1]<<" "<<eta_grad<<" "<<u-gradient-Vinf<<endl;
9101  //cout<<q<<" "<<i<<" "<<dEta_dt<<endl;
9102  Point<dim> uu = gradient; //(gradient[dim-1],(u-gradient-Vinf)*eta_grad,Vinf(0));
9103 
9104  // nodes displacement velocity: x is 0 for now, z is devised to follow the wave, y to make
9105  // u parallel to the boat surface
9106  u(2) = dEta_dt;
9107  local_vector_rhs(i) += (vector_fe_v.shape_value(i, q)+supg_shape_fun) *
9108  u(comp_i) * vector_fe_v.JxW(q);
9109  local_vector_rhs_2(i) += (vector_fe_v.shape_value(i, q)+supg_shape_fun) *
9110  uu(comp_i) * vector_fe_v.JxW(q);
9111  }
9112  else
9113  {
9114  local_vector_rhs(i) += (vector_fe_v.shape_value(i, q)+supg_shape_fun) *
9115  0 * vector_fe_v.JxW(q);
9116  local_vector_rhs_2(i) += (vector_fe_v.shape_value(i, q)+supg_shape_fun) *
9117  0 * vector_fe_v.JxW(q);
9118  }
9119  }
9120  }
9121 
9122  vector_cell->get_dof_indices (vector_local_dof_indices);
9123  vector_constr.distribute_local_to_global
9124  (local_vector_matrix,
9125  local_vector_rhs,
9126  vector_local_dof_indices,
9127  vector_sys_matrix,
9128  vector_sys_rhs);
9129 
9130  vector_constr.distribute_local_to_global
9131  (local_vector_rhs_2,
9132  vector_local_dof_indices,
9133  vector_sys_rhs_2);
9134 
9135  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
9136  {
9137  Point<dim> gradient = DphiDt_node_normals[q]*DphiDt_phi_norm_grads[q] + DphiDt_phi_surf_grads[q];
9138  Point<dim> Vinf;
9139  for (unsigned int i = 0; i < dim; i++)
9140  Vinf(i) = DphiDt_wind_values[q](i);
9141 
9142  Point<dim> eta_grad = Point<dim>(0,0,0);
9143  eta_grad = eta_grad + vector_eta_surf_grads[q];
9144  eta_grad(dim-1) = 0;
9145 
9146  Point<dim> phi_surf_grad_corrected = Point<dim>(0,0,0);
9147  phi_surf_grad_corrected(0) = DphiDt_phi_surf_grads[q][0] -
9148  DphiDt_phi_surf_grads[q][2]*DphiDt_node_normals[q][0]/DphiDt_node_normals[q][2];
9149  phi_surf_grad_corrected(1) = DphiDt_phi_surf_grads[q][1] -
9150  DphiDt_phi_surf_grads[q][2]*DphiDt_node_normals[q][1]/DphiDt_node_normals[q][2];
9151  //phi_surf_grad_corrected(dim-1) = 0;
9152  //phi_surf_grad_corrected(0) = gradient(0);
9153  //phi_surf_grad_corrected(1) = gradient(1);
9154  //phi_surf_grad_corrected(2) = gradient(2);
9155 
9156  double fluid_vel_norm = (gradient+Vinf).norm();
9157  if (fluid_vel_norm < 1e-3)
9158  fluid_vel_norm = -8.0e+05*pow(fluid_vel_norm,3.0) + 1.7e+03*pow(fluid_vel_norm,2.0) + 0.0001;
9159  Point<dim> velocity_unit_vect = (gradient+Vinf)/fluid_vel_norm;
9160 
9161  Point<dim> eta_grad_unit_vect = Point<3>(0,0,0);
9162  if (sqrt((eta_grad).square()) > 1e-3)
9163  eta_grad_unit_vect = (eta_grad)/sqrt((eta_grad).square());
9164  double Fr = sqrt((gradient+Vinf).square())/sqrt(g*comp_dom.Lx_boat);
9165  double eta = DphiDt_node_positions[q](dim-1);
9166  double delta_p = 0;
9167  if ( (eta_grad*(gradient+Vinf) > 0) &&
9168  (sqrt(eta*eta+eta_grad.square()*pow(Fr,4.0)) > 0.1725*Fr*Fr) &&
9169  (cell->material_id() == comp_dom.free_sur_ID1 ||
9170  cell->material_id() == comp_dom.free_sur_ID2 ||
9171  cell->material_id() == comp_dom.free_sur_ID3 ) )
9172  {
9173  delta_p = 0.0*eta_grad.square()/Fr/Fr*(velocity_unit_vect*eta_grad_unit_vect)*
9174  (eta+0.117*Fr*Fr);
9175  //std::cout<<"eta "<<DphiDt_node_positions[q]<<" |grad_eta|^2 "<<eta_grad.square()<<" Fr "<<Fr<<std::endl;
9176  //sstd::cout<<sqrt(eta*eta+eta_grad.square()*pow(Fr,4.0))<<" vs "<<0.1725*Fr*Fr<<std::endl;
9177  }
9178 
9179  //double nu_0 = 1.0;
9180  double nu_0 = 0;
9181  double damping = nu_0 *
9182  pow((fmax(abs(vector_node_positions[q](0)),20)-20)/(31.169752-20),2) *
9183  DphiDt_phi_norm_grads[q];
9184 
9185 // double damping = nu_0 *
9186 // pow((fmax(abs(DphiDt_node_positions[q](0)),25)-25)/(25),2) *
9187 // DphiDt_phi_norm_grads[q];
9188 
9189  const double delta = cell->diameter()/sqrt(2);
9190  for (unsigned int i=0; i<DphiDt_dofs_per_cell; ++i)
9191  {
9192  double supg_shape_fun = 1.0*(delta)*fe_v.shape_grad(i, q)*velocity_unit_vect;
9193  for (unsigned int j=0; j<DphiDt_dofs_per_cell; ++j)
9194  local_DphiDt_matrix(i,j) += ((fe_v.shape_value (i, q)+supg_shape_fun) *
9195  fe_v.shape_value (j, q)) *
9196  fe_v.JxW(q);
9197  if (cell->material_id() == comp_dom.free_sur_ID1 ||
9198  cell->material_id() == comp_dom.free_sur_ID2 ||
9199  cell->material_id() == comp_dom.free_sur_ID3 )
9200  {
9201  Point<dim> u(quad_nodes_velocities[q](0),quad_nodes_velocities[q](1),quad_nodes_velocities[q](2));
9202  double dEta_dt = (gradient[dim-1]+(u - gradient - Vinf)*eta_grad-damping);
9203 
9204  // nodes displacement velocity: x is 0 for now, z is devised to follow the wave, y to make
9205  // u parallel to the boat surface
9206  u(2) = dEta_dt;
9207  local_DphiDt_rhs(i) += (fe_v.shape_value (i, q)+supg_shape_fun) *
9208  ((gradient * gradient)/2 - g*DphiDt_node_positions[q](dim-1) +
9209  phi_surf_grad_corrected*(u - gradient - Vinf) -
9210  damping - delta_p) *
9211  fe_v.JxW(q);
9212  local_DphiDt_rhs_2(i) += (fe_v.shape_value (i, q)+supg_shape_fun) *
9213  (delta_p) *
9214  fe_v.JxW(q);
9215  //cout<<q<<" "<<i<<" "<<fe_v.shape_grad(i, q)<<" "<<velocity_unit_vect<<" "<<1.0*(delta)<<endl;
9216  //cout<<q<<" "<<i<<" "<<(fe_v.shape_value (i, q)+supg_shape_fun)<<" "<<((gradient * gradient)/2 - g*DphiDt_node_positions[q](dim-1) +
9217  // phi_surf_grad_corrected*(u - gradient - Vinf) -
9218  // damping - delta_p)<<" "<<fe_v.JxW(q)<<endl;
9219  }
9220  else
9221  local_DphiDt_rhs(i) += 0;
9222 
9223  }
9224  }
9225 
9226  cell->get_dof_indices (DphiDt_local_dof_indices);
9228  (local_DphiDt_matrix,
9229  local_DphiDt_rhs,
9230  DphiDt_local_dof_indices,
9231  DphiDt_sys_matrix,
9232  DphiDt_sys_rhs);
9233 
9235  (local_DphiDt_rhs_2,
9236  DphiDt_local_dof_indices,
9237  DphiDt_sys_rhs_2);
9238  }
9239 
9240 
9241  rhs_evaluations_counter++;
9242 
9243 
9244  /* //checking the volume conservation
9245  double volume = 0;
9246 
9247  cell = comp_dom.dh.begin_active();
9248  for (; cell!=endc; ++cell)
9249  {
9250  fe_v.reinit(cell);
9251  if (cell->material_id() == comp_dom.free_sur_ID1 ||
9252  cell->material_id() == comp_dom.free_sur_ID2 ||
9253  cell->material_id() == comp_dom.free_sur_ID3 )
9254  {
9255  const std::vector<Point<dim> > &q_points = fe_v.get_quadrature_points();
9256  const std::vector<Point<dim> > &normals = fe_v.get_normal_vectors();
9257 
9258  for (unsigned int q=0; q<DphiDt_n_q_points; ++q){
9259  //std::cout<<q_points[q](0)<<" "<<q_points[q](1)<<std::endl;
9260  volume += q_points[q](dim-1) * normals[q](dim-1) * fe_v.JxW(q);}
9261  }
9262  }
9263 
9264  std::cout<<"Volume: "<<volume<<std::endl;//*/
9265 
9266 
9267 }
9268 
9269 
9270 template <int dim>
9272  const Vector<double> &phi,
9273  const Vector<double> &dphi_dn)
9274 {
9275 
9276  std::vector<unsigned int> vector_dofs(comp_dom.vector_fe.dofs_per_cell);
9277  std::vector<Point<dim> > vector_support_points(comp_dom.vector_dh.n_dofs());
9278  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping, comp_dom.vector_dh, vector_support_points);
9279 
9280  vector_sys_matrix.reinit (vector_sparsity_pattern);
9281  Vector<double> complete_gradient_sys_rhs(comp_dom.vector_dh.n_dofs());
9282 
9283 
9284  FEValues<dim-1,dim> vector_fe_v(*comp_dom.mapping, comp_dom.vector_fe, *comp_dom.quadrature,
9285  update_values | update_gradients |
9286  update_cell_normal_vectors |
9287  update_quadrature_points |
9288  update_JxW_values);
9289 
9290  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
9291  update_values | update_gradients |
9292  update_cell_normal_vectors |
9293  update_quadrature_points |
9294  update_JxW_values);
9295 
9296 
9297  const unsigned int vector_n_q_points = vector_fe_v.n_quadrature_points;
9298  const unsigned int vector_dofs_per_cell = comp_dom.vector_fe.dofs_per_cell;
9299  std::vector<unsigned int> vector_local_dof_indices (vector_dofs_per_cell);
9300 
9301  FullMatrix<double> local_vector_matrix (vector_dofs_per_cell, vector_dofs_per_cell);
9302  Vector<double> local_complete_gradient_rhs (vector_dofs_per_cell);
9303 
9304  std::vector< Tensor<1,dim> > vector_phi_surf_grads(vector_n_q_points);
9305  std::vector<double> vector_phi_norm_grads(vector_n_q_points);
9306 
9307 
9308  cell_it
9309  vector_cell = comp_dom.vector_dh.begin_active(),
9310  vector_endc = comp_dom.vector_dh.end();
9311  cell_it
9312  cell = comp_dom.dh.begin_active(),
9313  endc = comp_dom.dh.end();
9314 
9315  for (; cell!=endc,vector_cell!=vector_endc; ++cell,++vector_cell)
9316  {
9317  Assert(cell->index() == vector_cell->index(), ExcInternalError());
9318 
9319  vector_fe_v.reinit (vector_cell);
9320  fe_v.reinit(cell);
9321 
9322  local_vector_matrix = 0;
9323  local_complete_gradient_rhs = 0;
9324 
9325  fe_v.get_function_gradients((const Vector<double> &)phi, vector_phi_surf_grads);
9326  fe_v.get_function_values(dphi_dn, vector_phi_norm_grads);
9327 
9328 
9329  const std::vector<Point<dim> > &vector_node_normals = vector_fe_v.get_normal_vectors();
9330  const std::vector<Point<dim> > &vector_node_positions = vector_fe_v.get_quadrature_points();
9331 
9332  double g = 9.81;
9333 
9334  std::vector<Vector<double> > vector_wind_values(vector_n_q_points);
9335  for (unsigned int q=0; q<vector_n_q_points; ++q)
9336  {
9337  vector_wind_values[q].reinit(dim,true);
9338  wind.vector_value(vector_node_positions[q], vector_wind_values[q]);
9339  }
9340 
9341  unsigned int comp_i, comp_j;
9342  for (unsigned int q=0; q<vector_n_q_points; ++q)
9343  {
9344  Point<dim> gradient = vector_node_normals[q]*vector_phi_norm_grads[q] + vector_phi_surf_grads[q];
9345 
9346  for (unsigned int i=0; i<vector_dofs_per_cell; ++i)
9347  {
9348  comp_i = comp_dom.vector_fe.system_to_component_index(i).first;
9349  for (unsigned int j=0; j<vector_dofs_per_cell; ++j)
9350  {
9351  comp_j = comp_dom.vector_fe.system_to_component_index(j).first;
9352  if (comp_i == comp_j)
9353  {
9354  local_vector_matrix(i,j) += ( (vector_fe_v.shape_value(i, q))*
9355  vector_fe_v.shape_value(j, q) ) *
9356  vector_fe_v.JxW(q);
9357 
9358  }
9359  }
9360  local_complete_gradient_rhs(i) += (vector_fe_v.shape_value(i, q)) *
9361  gradient(comp_i) * vector_fe_v.JxW(q);
9362  }
9363  }
9364 
9365  vector_cell->get_dof_indices (vector_local_dof_indices);
9366  vector_constraints.distribute_local_to_global
9367  (local_vector_matrix,
9368  local_complete_gradient_rhs,
9369  vector_local_dof_indices,
9370  vector_sys_matrix,
9371  complete_gradient_sys_rhs);
9372 
9373  }
9374 
9375  SparseDirectUMFPACK vector_direct;
9376  vector_direct.initialize(vector_sys_matrix);
9377  vector_direct.vmult(complete_potential_gradients,complete_gradient_sys_rhs);
9378  vector_constraints.distribute(complete_potential_gradients);
9379 
9380  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
9381  {
9382  std::set <unsigned int> doubles = comp_dom.vector_double_nodes_set[i];
9383  if ( doubles.size() > 1 )
9384  {
9385  double average = 0.0;
9386  for (std::set<unsigned int>::iterator pos=doubles.begin(); pos != doubles.end(); ++pos)
9387  {
9388  average += complete_potential_gradients(*pos);
9389  }
9390  average /= doubles.size();
9391  for (std::set<unsigned int>::iterator pos=doubles.begin(); pos != doubles.end(); ++pos)
9392  {
9393  complete_potential_gradients(*pos) = average;
9394  }
9395  }
9396  }
9397 
9398  vector_constraints.distribute(complete_potential_gradients);
9399 }
9400 
9401 
9402 
9403 
9404 
9405 
9406 template <int dim>
9408  Vector<double> &comp_1, Vector<double> &comp_2, Vector<double> &comp_3, Vector<double> &comp_4,
9409  const double t,
9410  const Vector<double> &solution,
9411  const Vector<double> &solution_dot)
9412 {
9413 
9414  std::cout<<"Computing pressure... "<<std::endl;
9415 
9416  double g = 9.81;
9417  double rho = 1025.1;
9418 
9419  comp_dom.update_support_points();
9420  press.reinit(comp_dom.dh.n_dofs());
9421 
9422 
9423  comp_1.reinit(comp_dom.dh.n_dofs());
9424  comp_2.reinit(comp_dom.dh.n_dofs());
9425  comp_3.reinit(comp_dom.dh.n_dofs());
9426  comp_4.reinit(comp_dom.dh.n_dofs());
9427  Vector<double> rhs_comp_1(comp_dom.dh.n_dofs());
9428  Vector<double> rhs_comp_2(comp_dom.dh.n_dofs());
9429  Vector<double> rhs_comp_3(comp_dom.dh.n_dofs());
9430  Vector<double> rhs_comp_4(comp_dom.dh.n_dofs());
9431  rhs_comp_1 = 0;
9432  rhs_comp_2 = 0;
9433  rhs_comp_3 = 0;
9434  rhs_comp_4 = 0;
9435 
9436  DphiDt_sys_rhs.reinit (comp_dom.dh.n_dofs());
9437  DphiDt_sys_matrix.reinit(DphiDt_sparsity_pattern);
9438 
9439  VectorView<double> phi(comp_dom.dh.n_dofs(),solution.begin()+comp_dom.vector_dh.n_dofs());
9440  VectorView<double> dphi_dn(comp_dom.dh.n_dofs(),solution.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
9441  VectorView<double> DphiDt(comp_dom.dh.n_dofs(),solution_dot.begin()+comp_dom.vector_dh.n_dofs());
9442  VectorView<double> node_vels(comp_dom.vector_dh.n_dofs(),solution_dot.begin());
9443  AssertDimension(DphiDt.size(), node_vels.size()/dim);
9444 
9445  Point<3> hull_baricenter_displ;
9446  Point<3> hull_baricenter_vel;
9447  Point<3> hull_ang_vel;
9448  for (unsigned int d=0; d<3; ++d)
9449  {
9450  hull_baricenter_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
9451  hull_baricenter_displ(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
9452  hull_ang_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
9453  }
9454 
9455  Point<3> baricenter_pos(hull_baricenter_displ(0)+comp_dom.boat_model.reference_hull_baricenter(0),
9456  hull_baricenter_displ(1)+comp_dom.boat_model.reference_hull_baricenter(1),
9457  hull_baricenter_displ(2)+comp_dom.boat_model.reference_hull_baricenter(2));
9458 
9459  Vector<double> v_x(comp_dom.dh.n_dofs());
9460  Vector<double> v_y(comp_dom.dh.n_dofs());
9461  Vector<double> v_z(comp_dom.dh.n_dofs());
9462 
9463  for (unsigned int i = 0; i < comp_dom.dh.n_dofs(); i++)
9464  {
9465  v_x(i) = node_vels(i*dim)+hull_ang_vel(1)*(comp_dom.support_points[i](2)-baricenter_pos(2))-
9466  hull_ang_vel(2)*(comp_dom.support_points[i](1)-baricenter_pos(1))+hull_baricenter_vel(0);
9467  v_y(i) = node_vels(i*dim+1)+hull_ang_vel(2)*(comp_dom.support_points[i](0)-baricenter_pos(0))-
9468  hull_ang_vel(0)*(comp_dom.support_points[i](2)-baricenter_pos(2))+hull_baricenter_vel(1);
9469  v_z(i) = node_vels(i*dim+2)+hull_ang_vel(0)*(comp_dom.support_points[i](1)-baricenter_pos(1))-
9470  hull_ang_vel(1)*(comp_dom.support_points[i](0)-baricenter_pos(0))+hull_baricenter_vel(2);
9471  }
9472 
9473  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
9474  update_values | update_gradients |
9475  update_cell_normal_vectors |
9476  update_quadrature_points |
9477  update_JxW_values);
9478 
9479  const unsigned int DphiDt_n_q_points = fe_v.n_quadrature_points;
9480  const unsigned int DphiDt_dofs_per_cell = comp_dom.fe.dofs_per_cell;
9481  std::vector<unsigned int> DphiDt_local_dof_indices (DphiDt_dofs_per_cell);
9482 
9483  FullMatrix<double> local_DphiDt_matrix (DphiDt_dofs_per_cell, DphiDt_dofs_per_cell);
9484  Vector<double> local_DphiDt_rhs (DphiDt_dofs_per_cell);
9485 
9486  Vector<double> local_DphiDt_rhs_comp_1 (DphiDt_dofs_per_cell);
9487  Vector<double> local_DphiDt_rhs_comp_2 (DphiDt_dofs_per_cell);
9488  Vector<double> local_DphiDt_rhs_comp_3 (DphiDt_dofs_per_cell);
9489  Vector<double> local_DphiDt_rhs_comp_4 (DphiDt_dofs_per_cell);
9490 
9491  std::vector< Tensor<1,dim> > DphiDt_phi_surf_grads(DphiDt_n_q_points);
9492  std::vector<double> DphiDt_phi_norm_grads(DphiDt_n_q_points);
9493 
9494  std::vector<double> DphiDt_v_x_values(DphiDt_n_q_points);
9495  std::vector<double> DphiDt_v_y_values(DphiDt_n_q_points);
9496  std::vector<double> DphiDt_v_z_values(DphiDt_n_q_points);
9497  std::vector<double> DphiDt_DphiDt_values(DphiDt_n_q_points);
9498 
9499  cell_it
9500  cell = comp_dom.dh.begin_active(),
9501  endc = comp_dom.dh.end();
9502  Point<dim> press_force_test_1;
9503  Point<dim> press_force_test_2;
9504  Point<dim> press_moment;
9505 
9506  for (; cell!=endc; ++cell)
9507  {
9508  fe_v.reinit(cell);
9509  local_DphiDt_rhs = 0;
9510  local_DphiDt_matrix = 0;
9511 
9512  local_DphiDt_rhs_comp_1 = 0;
9513  local_DphiDt_rhs_comp_2 = 0;
9514  local_DphiDt_rhs_comp_3 = 0;
9515  local_DphiDt_rhs_comp_4 = 0;
9516 
9517  fe_v.get_function_gradients((const Vector<double> &)phi, DphiDt_phi_surf_grads);
9518  fe_v.get_function_values((const Vector<double> &)dphi_dn, DphiDt_phi_norm_grads);
9519  fe_v.get_function_values(v_x, DphiDt_v_x_values);
9520  fe_v.get_function_values(v_y, DphiDt_v_y_values);
9521  fe_v.get_function_values(v_z, DphiDt_v_z_values);
9522  fe_v.get_function_values((const Vector<double> &)DphiDt, DphiDt_DphiDt_values);
9523  const std::vector<Point<dim> > &DphiDt_node_normals = fe_v.get_normal_vectors();
9524  const std::vector<Point<dim> > &DphiDt_node_positions = fe_v.get_quadrature_points();
9525 
9526  std::vector<Vector<double> > DphiDt_wind_values(DphiDt_n_q_points);
9527  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
9528  {
9529  DphiDt_wind_values[q].reinit(dim,true);
9530  wind.vector_value(DphiDt_node_positions[q],DphiDt_wind_values[q]);
9531  }
9532 
9533 
9534  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
9535  {
9536  Point<dim> gradient = DphiDt_node_normals[q]*DphiDt_phi_norm_grads[q] + DphiDt_phi_surf_grads[q];
9537  Point<dim> Vinf;
9538  for (unsigned int i = 0; i < dim; i++)
9539  Vinf(i) = DphiDt_wind_values[q](i);
9540 
9541  Point<dim> phi_surf_grad = Point<dim>(0,0,0);
9542  phi_surf_grad = phi_surf_grad + DphiDt_phi_surf_grads[q];
9543  phi_surf_grad(dim-1) = 0;
9544 
9545  Point<dim> node_vel_vect;
9546  node_vel_vect(0) = DphiDt_v_x_values[q];
9547  node_vel_vect(1) = DphiDt_v_y_values[q];
9548  node_vel_vect(2) = DphiDt_v_z_values[q];
9549 
9550  Point<dim> velocity_unit_vect;
9551  if (sqrt((gradient+Vinf).square()) > 1e-3)
9552  velocity_unit_vect = (gradient+Vinf)/sqrt((gradient+Vinf).square());
9553 
9554  double press = rho*((Vinf)*(Vinf))/2 -
9555  rho*((gradient+Vinf)*(gradient+Vinf))/2 -
9556  rho*g*DphiDt_node_positions[q](dim-1) -
9557  rho*(DphiDt_DphiDt_values[q]-node_vel_vect*gradient);
9558  double press2 = -rho*((Vinf)*(gradient))
9559  -rho*((gradient)*(gradient))/2
9560  -rho*g*DphiDt_node_positions[q](dim-1)
9561  -rho*(DphiDt_DphiDt_values[q]-node_vel_vect*gradient);
9562  /*std::cout<<"cell "<<cell<<" node "<<q<<std::endl;
9563  std::cout<<"press "<<press<<std::endl;
9564  std::cout<<"term1 "<<rho*((Vinf)*(Vinf))/2<<std::endl;
9565  std::cout<<"term2 "<<-rho*((gradient+Vinf)*(gradient+Vinf))/2<<std::endl;
9566  std::cout<<"term3 "<<-rho*g*DphiDt_node_positions[q](dim-1)<<std::endl;
9567  std::cout<<"term4 "<<-rho*(DphiDt_DphiDt_values[q]-node_vel_vect*phi_surf_grad)/2<<std::endl;
9568  std::cout<<std::endl;//*/
9569 
9570  for (unsigned int i=0; i<DphiDt_dofs_per_cell; ++i)
9571  {
9572  for (unsigned int j=0; j<DphiDt_dofs_per_cell; ++j)
9573  local_DphiDt_matrix(i,j) += ((fe_v.shape_value (i, q)) *
9574  fe_v.shape_value (j, q)) *
9575  fe_v.JxW(q);
9576  local_DphiDt_rhs(i) += (fe_v.shape_value (i, q)) *
9577  (press) *
9578  fe_v.JxW(q);
9579  local_DphiDt_rhs_comp_1(i) += (fe_v.shape_value (i, q)) *
9580  (rho*((Vinf)*(Vinf))/2) *
9581  fe_v.JxW(q);
9582  local_DphiDt_rhs_comp_2(i) += (fe_v.shape_value (i, q)) *
9583  (-rho*((gradient+Vinf)*(gradient+Vinf))/2) *
9584  fe_v.JxW(q);
9585  local_DphiDt_rhs_comp_3(i) += (fe_v.shape_value (i, q)) *
9586  (-rho*g*DphiDt_node_positions[q](dim-1)) *
9587  fe_v.JxW(q);
9588  local_DphiDt_rhs_comp_4(i) += (fe_v.shape_value (i, q)) *
9589  (-rho*(DphiDt_DphiDt_values[q]-node_vel_vect*phi_surf_grad)) *
9590  fe_v.JxW(q);
9591 
9592  }
9593  if ((cell->material_id() == comp_dom.wall_sur_ID1 ||
9594  cell->material_id() == comp_dom.wall_sur_ID2 ||
9595  cell->material_id() == comp_dom.wall_sur_ID3 ))
9596  {
9597  press_force_test_1 += press*DphiDt_node_normals[q]*fe_v.JxW(q);
9598  press_force_test_2 += press2*DphiDt_node_normals[q]*fe_v.JxW(q);
9599  press_moment += press*Point<3>((DphiDt_node_positions[q](1)-baricenter_pos(1))*DphiDt_node_normals[q](2)-
9600  (DphiDt_node_positions[q](2)-baricenter_pos(2))*DphiDt_node_normals[q](1),
9601  (DphiDt_node_positions[q](2)-baricenter_pos(2))*DphiDt_node_normals[q](0)-
9602  (DphiDt_node_positions[q](0)-baricenter_pos(0))*DphiDt_node_normals[q](2),
9603  (DphiDt_node_positions[q](0)-baricenter_pos(0))*DphiDt_node_normals[q](1)-
9604  (DphiDt_node_positions[q](1)-baricenter_pos(1))*DphiDt_node_normals[q](0))*fe_v.JxW(q);
9605  }
9606  }
9607 
9608  cell->get_dof_indices (DphiDt_local_dof_indices);
9609  constraints.distribute_local_to_global
9610  (local_DphiDt_matrix,
9611  local_DphiDt_rhs,
9612  DphiDt_local_dof_indices,
9613  DphiDt_sys_matrix,
9614  DphiDt_sys_rhs);
9615 
9616  constraints.distribute_local_to_global
9617  (local_DphiDt_rhs_comp_1,
9618  DphiDt_local_dof_indices,
9619  rhs_comp_1);
9620  constraints.distribute_local_to_global
9621  (local_DphiDt_rhs_comp_2,
9622  DphiDt_local_dof_indices,
9623  rhs_comp_2);
9624  constraints.distribute_local_to_global
9625  (local_DphiDt_rhs_comp_3,
9626  DphiDt_local_dof_indices,
9627  rhs_comp_3);
9628  constraints.distribute_local_to_global
9629  (local_DphiDt_rhs_comp_4,
9630  DphiDt_local_dof_indices,
9631  rhs_comp_4);
9632 
9633 
9634 
9635  }
9636 
9637  //DphiDt_sys_matrix.print(std::cout);
9638  SparseDirectUMFPACK pressure_direct;
9639  pressure_direct.initialize(DphiDt_sys_matrix);
9640  pressure_direct.vmult(press, DphiDt_sys_rhs);
9641  constraints.distribute(press);
9642 
9643  pressure_direct.vmult(comp_1, rhs_comp_1);
9644  constraints.distribute(comp_1);
9645  pressure_direct.vmult(comp_2, rhs_comp_2);
9646  constraints.distribute(comp_2);
9647  pressure_direct.vmult(comp_3, rhs_comp_3);
9648  constraints.distribute(comp_3);
9649  pressure_direct.vmult(comp_4, rhs_comp_4);
9650  constraints.distribute(comp_4);
9651 
9652 
9653  Vector<double> complete_potential_gradients(comp_dom.vector_dh.n_dofs());
9654  compute_potential_gradients(complete_potential_gradients,phi,dphi_dn);
9655 
9656 
9657  wind.set_time(t);
9658  Vector<double> instantVelValue(dim);
9659  Point<dim> zzero(0,0,0);
9660  wind.vector_value(zzero,instantVelValue);
9661  Point<3> V_inf(instantVelValue(0),
9662  instantVelValue(1),
9663  instantVelValue(2));
9664 
9665  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
9666  {
9667  Point<3> gradient(complete_potential_gradients(3*i),
9668  complete_potential_gradients(3*i+1),
9669  complete_potential_gradients(3*i+2));
9670  Point<3> v(node_vels(3*i),node_vels(3*i+1),node_vels(3*i+2));
9671  press(i) = 0.5*rho*V_inf*V_inf -
9672  0.5*rho*(V_inf+gradient)*(V_inf+gradient) -
9673  rho*g*comp_dom.support_points[i](2) -
9674  rho*(DphiDt(i)-v*gradient);
9675  }
9676 
9677  // preparing iges normal vectors vector for pressure computation
9678  Vector<double> iges_normals_x_values(comp_dom.dh.n_dofs());
9679  Vector<double> iges_normals_y_values(comp_dom.dh.n_dofs());
9680  Vector<double> iges_normals_z_values(comp_dom.dh.n_dofs());
9681  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
9682  {
9683  iges_normals_x_values(i) = comp_dom.iges_normals[i](0);
9684  iges_normals_y_values(i) = comp_dom.iges_normals[i](1);
9685  iges_normals_z_values(i) = comp_dom.iges_normals[i](2);
9686  }
9687 
9688 
9689  // pressure force computation
9690  Point<dim> press_force;
9691  double wet_surface = 0;
9692 
9693  cell = comp_dom.dh.begin_active(),
9694  endc = comp_dom.dh.end();
9695 
9696  std::vector<double> pressure_quad_values(DphiDt_n_q_points);
9697  std::vector<double> n_x_quad_values(DphiDt_n_q_points);
9698  std::vector<double> n_y_quad_values(DphiDt_n_q_points);
9699  std::vector<double> n_z_quad_values(DphiDt_n_q_points);
9700 
9701  for (; cell!=endc; ++cell)
9702  {
9703  if ((cell->material_id() == comp_dom.wall_sur_ID1 ||
9704  cell->material_id() == comp_dom.wall_sur_ID2 ||
9705  cell->material_id() == comp_dom.wall_sur_ID3 ))
9706  {
9707  fe_v.reinit(cell);
9708  fe_v.get_function_values(press, pressure_quad_values);
9709  fe_v.get_function_values(iges_normals_x_values, n_x_quad_values);
9710  fe_v.get_function_values(iges_normals_y_values, n_y_quad_values);
9711  fe_v.get_function_values(iges_normals_z_values, n_z_quad_values);
9712 
9713  const std::vector<Point<dim> > &DphiDt_node_normals = fe_v.get_normal_vectors();
9714  for (unsigned int q=0; q<DphiDt_n_q_points; ++q)
9715  {
9716  Point<3> normal(n_x_quad_values[q],n_y_quad_values[q],n_z_quad_values[q]);
9717  //Point<dim> local_press_force = pressure_quad_values[q]*normal;
9718  Point<dim> local_press_force = pressure_quad_values[q]*DphiDt_node_normals[q];
9719  press_force += (local_press_force) * fe_v.JxW(q);
9720  wet_surface += 1.0 * fe_v.JxW(q);
9721  }
9722  }
9723  }
9724 
9725  // breaking wave additional pressure computation
9726  Point<3> break_press_force(0.0,0.0,0.0);
9727  for (tria_it elem=comp_dom.tria.begin_active(); elem!= comp_dom.tria.end(); ++elem)
9728  {
9729  if ((elem->material_id() == comp_dom.free_sur_ID1 ||
9730  elem->material_id() == comp_dom.free_sur_ID2 ||
9731  elem->material_id() == comp_dom.free_sur_ID3 ))
9732  {
9733  if (elem->at_boundary())
9734  {
9735  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
9736  {
9737  if ( elem->face(f)->boundary_id() == 27 ||
9738  elem->face(f)->boundary_id() == 29 ) // left side
9739  {
9740  std::vector<Point<3> > vertices(4);
9741  std::vector<CellData<2> > cells(1);
9742  Vector<double> pressure_vect(4);
9743 
9744  unsigned int index_0 = comp_dom.find_point_id(elem->face(f)->vertex(0),comp_dom.ref_points);
9745  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[index_0];
9746  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
9747  {
9748  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
9749  if (comp_dom.flags[*pos] & water)
9750  {
9751  index_0 = *pos;
9752  break;
9753  }
9754  }
9755  vertices[0] = comp_dom.support_points[index_0];
9756  pressure_vect(0) = fmax(break_wave_press(index_0),1e-4)*rho;
9757 
9758  unsigned int index_1 = comp_dom.find_point_id(elem->face(f)->vertex(1),comp_dom.ref_points);
9759  duplicates = comp_dom.double_nodes_set[index_1];
9760  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
9761  {
9762  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
9763  if (comp_dom.flags[*pos] & water)
9764  {
9765  index_1 = *pos;
9766  break;
9767  }
9768  }
9769  vertices[1] = comp_dom.support_points[index_1];
9770  pressure_vect(1) = fmax(break_wave_press(index_1),1e-4)*rho;
9771  //cout<<"********* "<<pressure_vect(0)<<" "<<pressure_vect(1)<<endl;
9772  Point<3> temp_point(vertices[0](0),vertices[0](1),vertices[0](2)+pressure_vect(0)/g/rho);
9773  // if point we're dealing with is an internal one, we're projecting it on boat in y direction
9774  if ( (comp_dom.moving_point_ids[3] != index_0) &&
9775  (comp_dom.moving_point_ids[4] != index_0) &&
9776  (comp_dom.moving_point_ids[5] != index_0) &&
9777  (comp_dom.moving_point_ids[6] != index_0) )
9778  {
9779  //cout<<index_0<<" "<<comp_dom.moving_point_ids[3]<<" "<<comp_dom.moving_point_ids[4]<<" ";
9780  //cout<<comp_dom.moving_point_ids[5]<<" "<<comp_dom.moving_point_ids[6]<<endl;
9781  comp_dom.boat_model.boat_water_line_left->axis_projection(vertices[2],temp_point); // y axis projection
9782  }
9783  //otherwise it needs to be properly projected on the curve (to be implemented yet)
9784  else
9785  vertices[2] = vertices[0];
9786  temp_point = Point<3>(vertices[1](0),vertices[1](1),vertices[1](2)+pressure_vect(1)/g/rho);
9787 
9788  if ( (comp_dom.moving_point_ids[3] != index_1) &&
9789  (comp_dom.moving_point_ids[4] != index_1) &&
9790  (comp_dom.moving_point_ids[5] != index_1) &&
9791  (comp_dom.moving_point_ids[6] != index_1) )
9792  {
9793  //cout<<index_0<<" "<<comp_dom.moving_point_ids[3]<<" "<<comp_dom.moving_point_ids[4]<<" ";
9794  //cout<<comp_dom.moving_point_ids[5]<<" "<<comp_dom.moving_point_ids[6]<<endl;
9795  comp_dom.boat_model.boat_water_line_left->axis_projection(vertices[3],temp_point); // y axis projection
9796  }
9797  //otherwise it needs to be properly projected on the curve (to be implemented yet)
9798  else
9799  vertices[3] = vertices[1];
9800  //cout<<"########## "<<vertices[0]<<" "<<vertices[1]<<endl;
9801  //cout<<"########## "<<vertices[2]<<" "<<vertices[3]<<endl;
9802  pressure_vect(2) = 0.0;
9803  pressure_vect(3) = 0.0;
9804  if (vertices[1](0) < vertices[0](0))
9805  {
9806  cells[0].vertices[0]=0;
9807  cells[0].vertices[1]=1;
9808  cells[0].vertices[2]=3;
9809  cells[0].vertices[3]=2;
9810  //cout<<"l* "<<elem<<endl;
9811  }
9812  else
9813  {
9814  cells[0].vertices[0]=1;
9815  cells[0].vertices[1]=0;
9816  cells[0].vertices[2]=2;
9817  cells[0].vertices[3]=3;
9818  //cout<<"l** "<<elem<<endl;
9819  }
9820  SubCellData subcelldata;
9821  Triangulation<dim-1, dim> break_tria;
9822  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
9824  break_tria.create_triangulation_compatibility(vertices, cells, subcelldata );
9825  FE_Q<dim-1,dim> break_fe(1);
9826  DoFHandler<dim-1,dim> break_dh(break_tria);
9827  break_dh.distribute_dofs(break_fe);
9828 
9829  FEValues<dim-1,dim> break_fe_v(break_fe, *comp_dom.quadrature,
9830  update_values | update_gradients |
9831  update_cell_normal_vectors |
9832  update_quadrature_points |
9833  update_JxW_values);
9834 
9835  const unsigned int break_n_q_points = break_fe_v.n_quadrature_points;
9836  std::vector<double> break_pressure_quad_values(break_n_q_points);
9837  cell_it cell = break_dh.begin_active();
9838  break_fe_v.reinit(cell);
9839  break_fe_v.get_function_values(pressure_vect, break_pressure_quad_values);
9840  const std::vector<Point<dim> > &break_node_normals = break_fe_v.get_normal_vectors();
9841  const std::vector<Point<dim> > &break_quad_nodes = break_fe_v.get_quadrature_points();
9842 
9843  for (unsigned int q=0; q<break_n_q_points; ++q)
9844  {
9845  Point<dim> local_press_force = break_pressure_quad_values[q]*break_node_normals[q];
9846  break_press_force += (local_press_force) * break_fe_v.JxW(q);
9847  //cout<<q<<" F = ("<<local_press_force<<") n = ("<<break_node_normals[q]<<")"<<" "<<break_fe_v.JxW(q);
9848  //cout<<" p = ("<<break_quad_nodes[q]<<")"<<endl;
9849  }
9850 
9851 
9852  }
9853  if ( elem->face(f)->boundary_id() == 26 ||
9854  elem->face(f)->boundary_id() == 28 ) // right side
9855  {
9856  std::vector<Point<3> > vertices(4);
9857  std::vector<CellData<2> > cells(1);
9858  Vector<double> pressure_vect(4);
9859 
9860  unsigned int index_0 = comp_dom.find_point_id(elem->face(f)->vertex(0),comp_dom.ref_points);
9861  std::set<unsigned int> duplicates = comp_dom.double_nodes_set[index_0];
9862  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
9863  {
9864  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
9865  if (comp_dom.flags[*pos] & water)
9866  {
9867  index_0 = *pos;
9868  break;
9869  }
9870  }
9871  vertices[0] = comp_dom.support_points[index_0];
9872  pressure_vect(0) = fmax(break_wave_press(index_0),1e-4)*rho;
9873 
9874  unsigned int index_1 = comp_dom.find_point_id(elem->face(f)->vertex(1),comp_dom.ref_points);
9875  duplicates = comp_dom.double_nodes_set[index_1];
9876  for (std::set<unsigned int>::iterator pos = duplicates.begin(); pos !=duplicates.end(); pos++)
9877  {
9878  //cout<<i<<" mpid"<<*pos<<" is in?"<<boundary_dofs[i][3*(*pos)]<<endl;
9879  if (comp_dom.flags[*pos] & water)
9880  {
9881  index_1 = *pos;
9882  break;
9883  }
9884  }
9885  vertices[1] = comp_dom.support_points[index_1];
9886  pressure_vect(1) = fmax(break_wave_press(index_1),1e-4)*rho;
9887  Point<3> temp_point(vertices[0](0),vertices[0](1),vertices[0](2)+pressure_vect(0)/g/rho);
9888  // if point we're dealing with is an internal one, we're projectiong it on boat in y direction
9889  if ( (comp_dom.moving_point_ids[3] != index_0) &&
9890  (comp_dom.moving_point_ids[4] != index_0) &&
9891  (comp_dom.moving_point_ids[5] != index_0) &&
9892  (comp_dom.moving_point_ids[6] != index_0) )
9893  {
9894  //cout<<index_0<<" "<<comp_dom.moving_point_ids[3]<<" "<<comp_dom.moving_point_ids[4]<<" ";
9895  //cout<<comp_dom.moving_point_ids[5]<<" "<<comp_dom.moving_point_ids[6]<<endl;
9896  comp_dom.boat_model.boat_water_line_right->axis_projection(vertices[2],temp_point); // y axis projection
9897  }
9898  //otherwise it needs to be properly projected on the curve
9899  else
9900  vertices[2] = vertices[0];
9901  temp_point = Point<3>(vertices[1](0),vertices[1](1),vertices[1](2)+pressure_vect(1)/g/rho);
9902  if ( (comp_dom.moving_point_ids[3] != index_1) &&
9903  (comp_dom.moving_point_ids[4] != index_1) &&
9904  (comp_dom.moving_point_ids[5] != index_1) &&
9905  (comp_dom.moving_point_ids[6] != index_1) )
9906  {
9907  //cout<<index_1<<" "<<comp_dom.moving_point_ids[3]<<" "<<comp_dom.moving_point_ids[4]<<" ";
9908  //cout<<comp_dom.moving_point_ids[5]<<" "<<comp_dom.moving_point_ids[6]<<endl;
9909  comp_dom.boat_model.boat_water_line_right->axis_projection(vertices[3],temp_point); // y axis projection
9910  }
9911  //otherwise it needs to be properly projected on the curve
9912  else
9913  vertices[3] = vertices[1];
9914 
9915  pressure_vect(2) = 0.0;
9916  pressure_vect(3) = 0.0;
9917  if (vertices[1](0) > vertices[0](0))
9918  {
9919  cells[0].vertices[0]=0;
9920  cells[0].vertices[1]=1;
9921  cells[0].vertices[2]=3;
9922  cells[0].vertices[3]=2;
9923  //cout<<"* "<<elem<<endl;
9924  }
9925  else
9926  {
9927  cells[0].vertices[0]=1;
9928  cells[0].vertices[1]=0;
9929  cells[0].vertices[2]=2;
9930  cells[0].vertices[3]=3;
9931  //cout<<"** "<<elem<<endl;
9932  }
9933  SubCellData subcelldata;
9934  Triangulation<dim-1, dim> break_tria;
9935  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
9937  break_tria.create_triangulation_compatibility(vertices, cells, subcelldata );
9938  FE_Q<dim-1,dim> break_fe(1);
9939  DoFHandler<dim-1,dim> break_dh(break_tria);
9940  break_dh.distribute_dofs(break_fe);
9941  FEValues<dim-1,dim> break_fe_v(break_fe, *comp_dom.quadrature,
9942  update_values | update_gradients |
9943  update_cell_normal_vectors |
9944  update_quadrature_points |
9945  update_JxW_values);
9946 
9947  const unsigned int break_n_q_points = break_fe_v.n_quadrature_points;
9948  std::vector<double> break_pressure_quad_values(break_n_q_points);
9949  cell_it cell = break_dh.begin_active();
9950  break_fe_v.reinit(cell);
9951  break_fe_v.get_function_values(pressure_vect, break_pressure_quad_values);
9952  const std::vector<Point<dim> > &break_node_normals = break_fe_v.get_normal_vectors();
9953  const std::vector<Point<dim> > &break_quad_nodes = break_fe_v.get_quadrature_points();
9954 
9955  for (unsigned int q=0; q<break_n_q_points; ++q)
9956  {
9957  Point<dim> local_press_force = break_pressure_quad_values[q]*break_node_normals[q];
9958  break_press_force += (local_press_force) * break_fe_v.JxW(q);
9959  if (local_press_force.distance(Point<3>(0.0,0.0,0.0)) > 1e-3)
9960  {
9961  //cout<<q<<" F = ("<<local_press_force<<") n = ("<<break_node_normals[q]<<")"<<" "<<break_fe_v.JxW(q);
9962  //cout<<" p = ("<<break_quad_nodes[q]<<")"<<endl;
9963  }
9964  }
9965 
9966 
9967  }
9968  }
9969  }
9970  }
9971  }
9972 
9973  // transom pressure force computation
9974  wind.set_time(t);
9975  Vector<double> instantWindValue(dim);
9976  Point<dim> zero(0,0,0);
9977  wind.vector_value(zero,instantWindValue);
9978  double Vinf = instantWindValue(0);
9979  Point<dim> transom_press_force;
9980  double transom_wet_surface = 0;
9981 
9982  if (!comp_dom.no_boat && comp_dom.boat_model.is_transom)
9983  {
9984  //double transom_draft = ref_transom_wet_surface/(fabs(comp_dom.boat_model.PointLeftTransom(1))+
9985  // fabs(comp_dom.boat_model.PointRightTransom(1)));
9986  double transom_draft = fabs(comp_dom.boat_model.CurrentPointCenterTransom(2));
9987  double transom_aspect_ratio = (fabs(comp_dom.boat_model.CurrentPointLeftTransom(1))+
9988  fabs(comp_dom.boat_model.CurrentPointRightTransom(1)))/transom_draft;
9989  double FrT = sqrt(Vinf*Vinf)/sqrt(9.81*transom_draft);
9990  double ReT = sqrt(9.81*pow(transom_draft,3.0))/1.307e-6;
9991  double eta_dry=fmin(0.05*pow(FrT,2.834)*pow(transom_aspect_ratio,0.1352)*pow(ReT,0.01338),1.0);
9992  //cout<<"eta_dry "<<eta_dry<<" mean transom draft "<<mean_transom_draft<<endl;
9993  cout<<"eta_dry "<<eta_dry<<endl;
9994  std::vector<Point<3> > vertices;
9995  std::vector<CellData<2> > cells;
9996  std::vector<double> transom_pressure_vect;
9997  for (tria_it elem=comp_dom.tria.begin_active(); elem!= comp_dom.tria.end(); ++elem)
9998  {
9999  if ((elem->material_id() == comp_dom.wall_sur_ID1 ||
10000  elem->material_id() == comp_dom.wall_sur_ID2 ||
10001  elem->material_id() == comp_dom.wall_sur_ID3 ))
10002  {
10003  if (elem->at_boundary())
10004  {
10005  for (unsigned int f=0; f<GeometryInfo<2>::faces_per_cell; ++f)
10006  if ( elem->face(f)->boundary_id() == 32 ||
10007  elem->face(f)->boundary_id() == 37 )
10008  {
10009  unsigned int index_0 = comp_dom.find_point_id(elem->face(f)->vertex(0),comp_dom.ref_points);
10010  double pressure_0 = (1-eta_dry)*comp_dom.ref_points[3*index_0](2)*rho*g;
10011  unsigned int index_1 = comp_dom.find_point_id(elem->face(f)->vertex(1),comp_dom.ref_points);
10012  double pressure_1 = (1-eta_dry)*comp_dom.ref_points[3*index_1](2)*rho*g;
10013  if (comp_dom.ref_points[3*index_1](1) < comp_dom.ref_points[3*index_0](1))
10014  {
10015  vertices.push_back(comp_dom.ref_points[3*index_0]);
10016  //cout<<comp_dom.ref_points[3*index_0]<<" / "<<elem->face(f)->vertex(0)<<endl;
10017  transom_pressure_vect.push_back(pressure_0);
10018  vertices.push_back(comp_dom.ref_points[3*index_1]);
10019  //cout<<comp_dom.ref_points[3*index_1]<<" / "<<elem->face(f)->vertex(1)<<endl;
10020  transom_pressure_vect.push_back(pressure_1);
10021  vertices.push_back(comp_dom.ref_points[3*index_1]+
10022  -1.0*Point<3>(0.0,0.0,(1-eta_dry)*comp_dom.ref_points[3*index_1](2)));
10023  //cout<<comp_dom.ref_points[3*index_1]-
10024  // Point<3>(0.0,0.0,(1-eta_dry)*comp_dom.ref_points[3*index_1](2))<<endl;
10025  transom_pressure_vect.push_back(0.0);
10026  vertices.push_back(comp_dom.ref_points[3*index_0]+
10027  -1.0*Point<3>(0.0,0.0,(1-eta_dry)*comp_dom.ref_points[3*index_0](2)));
10028  //cout<<comp_dom.ref_points[3*index_0]-
10029  // Point<3>(0.0,0.0,(1-eta_dry)*comp_dom.ref_points[3*index_0](2))<<endl;
10030  transom_pressure_vect.push_back(0.0);
10031  cells.resize(cells.size()+1);
10032  cells[cells.size()-1].vertices[0]=4*(cells.size()-1)+0;
10033  cells[cells.size()-1].vertices[1]=4*(cells.size()-1)+1;
10034  cells[cells.size()-1].vertices[2]=4*(cells.size()-1)+2;
10035  cells[cells.size()-1].vertices[3]=4*(cells.size()-1)+3;
10036  }
10037  else
10038  {
10039  vertices.push_back(comp_dom.ref_points[3*index_1]);
10040  transom_pressure_vect.push_back(pressure_1);
10041  vertices.push_back(comp_dom.ref_points[3*index_0]);
10042  transom_pressure_vect.push_back(pressure_0);
10043  vertices.push_back(comp_dom.ref_points[3*index_0]+
10044  -1.0*Point<3>(0.0,0.0,(1-eta_dry)*comp_dom.ref_points[3*index_0](2)));
10045  transom_pressure_vect.push_back(0.0);
10046  vertices.push_back(comp_dom.ref_points[3*index_1]+
10047  -1.0*Point<3>(0.0,0.0,(1-eta_dry)*comp_dom.ref_points[3*index_1](2)));
10048  transom_pressure_vect.push_back(0.0);
10049  cells.resize(cells.size()+1);
10050  cells[cells.size()-1].vertices[0]=4*(cells.size()-1)+0;
10051  cells[cells.size()-1].vertices[1]=4*(cells.size()-1)+1;
10052  cells[cells.size()-1].vertices[2]=4*(cells.size()-1)+2;
10053  cells[cells.size()-1].vertices[3]=4*(cells.size()-1)+3;
10054  }
10055  }
10056  }
10057  }
10058  }
10059  Vector<double> transom_pressure(transom_pressure_vect.size());
10060  for (unsigned int i=0; i<transom_pressure_vect.size(); ++i)
10061  {
10062  transom_pressure(i) = transom_pressure_vect[i];
10063  //cout<<i<<" " <<transom_pressure(i)<<" "<<vertices[i]<<endl;
10064  }
10065 
10066  SubCellData subcelldata;
10067  Triangulation<dim-1, dim> transom_tria;
10068  GridTools::delete_unused_vertices (vertices, cells, subcelldata);
10070  transom_tria.create_triangulation_compatibility(vertices, cells, subcelldata );
10071  FE_Q<dim-1,dim> transom_fe(1);
10072  DoFHandler<dim-1,dim> transom_dh(transom_tria);
10073  transom_dh.distribute_dofs(transom_fe);
10074 
10075  FEValues<dim-1,dim> transom_fe_v(transom_fe, *comp_dom.quadrature,
10076  update_values | update_gradients |
10077  update_cell_normal_vectors |
10078  update_quadrature_points |
10079  update_JxW_values);
10080 
10081  const unsigned int transom_n_q_points = transom_fe_v.n_quadrature_points;
10082  //const unsigned int DphiDt_dofs_per_cell = comp_dom.fe.dofs_per_cell;
10083 
10084  if (eta_dry < 1.0)
10085  {
10086  std::vector<double> transom_pressure_quad_values(transom_n_q_points);
10087  for (cell_it cell = transom_dh.begin_active(); cell!=transom_dh.end(); ++cell)
10088  {
10089  transom_fe_v.reinit(cell);
10090  transom_fe_v.get_function_values(transom_pressure, transom_pressure_quad_values);
10091  const std::vector<Point<dim> > &transom_node_normals = transom_fe_v.get_normal_vectors();
10092  const std::vector<Point<dim> > &transom_quad_nodes = transom_fe_v.get_quadrature_points();
10093  for (unsigned int q=0; q<transom_n_q_points; ++q)
10094  {
10095  Point<dim> local_press_force = transom_pressure_quad_values[q]*transom_node_normals[q];
10096  transom_press_force += (local_press_force) * transom_fe_v.JxW(q);
10097  transom_wet_surface += 1 * transom_fe_v.JxW(q);
10098  //cout<<q<<" F = ("<<local_press_force<<") n = ("<<transom_node_normals[q]<<")"<<" "<<transom_fe_v.JxW(q);
10099  //cout<<" p = ("<<transom_quad_nodes[q]<<")"<<endl;
10100  }
10101  }
10102  }
10103  else
10104  {
10105  transom_press_force = Point<3>(0.0,0.0,0.0);
10106  transom_wet_surface = 0;
10107  }
10108  //std::string filename = ( output_file_name + "_" +
10109  // Utilities::int_to_string(0) +
10110  // ".vtu" );
10111 
10112  DataOut<dim-1, DoFHandler<dim-1, dim> > dataout;
10113  dataout.attach_dof_handler(transom_dh);
10114  dataout.add_data_vector(transom_pressure, "transom_pressure");
10115  dataout.build_patches(StaticMappingQ1<2,3>::mapping,transom_fe.degree,
10116  DataOut<dim-1, DoFHandler<dim-1, dim> >::curved_inner_cells);
10117  std::ofstream file("transom.vtu");
10118  dataout.write_vtu(file);
10119  }
10120 
10121 
10122  // viscous force computed with flat plate or ITTC 1957 model
10123 
10124  //water kinematic viscosity: 1.307e-6 m^2/s at 10°C; 1.004e-6 m^2/s at 20°C
10125  double Re_l = fmax(1e-5,Vinf*comp_dom.Lx_boat/1.307e-6);
10126  //double Cd = 1.3282/sqrt(Re_l); // for flat plate
10127  double Cd = 0.075/(pow(log10(Re_l)-2., 2));
10128  double viscous_drag = 0.5*rho*Vinf*Vinf*comp_dom.boat_model.boatWetSurface*Cd;
10129  Point<3> visc_force(viscous_drag,0.0,0.0);
10130 
10131  std::string press_filename = ( output_file_name + "_force.txt" );
10132 
10133  ofstream myfile;
10134  if ( fabs(t-initial_time) < 1e-5 )
10135  myfile.open (press_filename.c_str());
10136  else
10137  myfile.open (press_filename.c_str(),ios::app);
10138  myfile << t <<" "<<press_force<<" "<<transom_press_force<<" "<<visc_force<<" "<<break_press_force<<" "<<press_moment<<" "<<wet_surface+transom_wet_surface<<" "<<press_force_test_1<<" "<<press_force_test_2<<" \n";
10139  myfile.close();
10140 
10141  std::cout<<"Total Force: "<<press_force-transom_press_force+visc_force+break_press_force<<std::endl;
10142  std::cout<<"Pressure Force: "<<press_force<<std::endl;
10143  std::cout<<"Breaking Wave Pressure Force: "<<break_press_force<<std::endl;
10144  std::cout<<"Transom Pressure Force: "<<transom_press_force<<std::endl;
10145  std::cout<<"Viscous Force: "<<visc_force<<std::endl;
10146  std::cout<<"Pressure Moment: "<<press_moment<<std::endl;
10147  std::cout<<"Wet Surface: "<<wet_surface<<" Transom Wet Surface: "<<transom_wet_surface<<" ("<<ref_transom_wet_surface<<")"<<std::endl;
10148 
10149  double max_err = 0.0;
10150  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
10151  {
10152  if (comp_dom.flags[i] & pressure)
10153  {
10154  double k=0.62994;
10155  double omega=2.4835;
10156  double h=5.5;
10157  double a=0.05;
10158  double time_factor = 1.0;
10159  double time_factor_deriv = 0.0;
10160  double ramp_length = 20.0;
10161  if (t<ramp_length)
10162  {
10163  time_factor = 0.5*sin(3.141592654*(t)/ramp_length-3.141592654/2)+0.5;
10164  time_factor_deriv = 0.5*3.141592654/ramp_length*cos(3.141592654*(t)/ramp_length-3.141592654/2);
10165  }
10166  double dphi_dt = omega*omega*a/k*cosh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*cos(k*comp_dom.support_points[i](0)+omega*t)*time_factor +
10167  omega*a/k*cosh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*sin(k*comp_dom.support_points[i](0)+omega*t)*time_factor_deriv;
10168  Point<3> grad_phi(omega*a*cosh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*cos(k*comp_dom.support_points[i](0)+omega*t)*time_factor,
10169  0.0*time_factor,
10170  omega*a*sinh(k*(comp_dom.support_points[i](2)+h))/sinh(k*h)*sin(k*comp_dom.support_points[i](0)+omega*t)*time_factor);
10171 
10172 
10173 
10174  double ex_pressure = ( -dphi_dt - 0.5*(grad_phi*grad_phi) -
10175  grad_phi(0)*instantWindValue(0)-grad_phi(1)*instantWindValue(1)-grad_phi(2)*instantWindValue(2) -
10176  comp_dom.support_points[i](2)*g ) * rho;
10177  cout<<i<<": P=("<<comp_dom.support_points[i]<<") p_ex="<<ex_pressure<<" vs p="<<press(i)<<" err="<<fabs(ex_pressure-press(i))<<endl;
10178  max_err = fmax(fabs(ex_pressure-press(i)),max_err);
10179  }
10180  }
10181  cout<<"Max Err: "<<max_err<<endl;
10182  /*
10183  // test of drag computation from control box momentum balance
10184  Vector<double> x_coors(comp_dom.dh.n_dofs());
10185  Vector<double> y_coors(comp_dom.dh.n_dofs());
10186  Vector<double> z_coors(comp_dom.dh.n_dofs());
10187  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
10188  {
10189  x_coors(i) = comp_dom.support_points[i](0);
10190  y_coors(i) = comp_dom.support_points[i](1);
10191  z_coors(i) = comp_dom.support_points[i](2);
10192  }
10193 
10194  dealii::Functions::FEFieldFunction<3,DoFHandler<2,3>, Vector <double> > fe_function(comp_dom.dh, x_coors, *comp_dom.mapping);
10195 
10196  //void Functions::FEFieldFunction< dim, DH, VECTOR >::value_list ( const std::vector< Point< dim > > & points,
10197  //std::vector< double > & values,
10198  //const unsigned int component = 0
10199  //) const
10200  */
10201 
10202 
10203 
10204 
10205 
10206 
10207  std::cout<<"...done computing pressure. "<<std::endl;
10208 
10209 }
10210 
10211 
10212 template <int dim>
10213 void FreeSurface<dim>::output_results(const std::string filename,
10214  const double t,
10215  const Vector<double> &solution,
10216  const Vector<double> &solution_dot)
10217 {
10218 
10219 
10220  VectorView<double> phi(comp_dom.dh.n_dofs(),solution.begin()+comp_dom.vector_dh.n_dofs());
10221  VectorView<double> phi_dot(comp_dom.dh.n_dofs(),solution_dot.begin()+comp_dom.vector_dh.n_dofs());
10222  VectorView<double> dphi_dn(comp_dom.dh.n_dofs(),solution.begin()+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs());
10223  VectorView<double> nodes_vel(comp_dom.vector_dh.n_dofs(),solution_dot.begin());
10224 
10225  wind.set_time(t);
10226  Vector<double> instantWindValue(dim);
10227  Point<dim> zero(0,0,0);
10228  wind.vector_value(zero,instantWindValue);
10229  Point<dim> Vinf;
10230  for (unsigned int i = 0; i < dim; i++)
10231  Vinf(i) = instantWindValue(i);
10232 
10233  Point<3> hull_lin_vel;
10234  Point<3> hull_ang_vel;
10235  Point<3> hull_lin_displ;
10236  for (unsigned int d=0; d<3; ++d)
10237  {
10238  hull_lin_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+d);
10239  hull_ang_vel(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+6+d);
10240  hull_lin_displ(d) = solution(comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()+3+d);
10241  }
10242 
10243  Point<3> baricenter_pos(hull_lin_displ(0)+comp_dom.boat_model.reference_hull_baricenter(0),
10244  hull_lin_displ(1)+comp_dom.boat_model.reference_hull_baricenter(1),
10245  hull_lin_displ(2)+comp_dom.boat_model.reference_hull_baricenter(2));
10246 
10247 
10248 
10249  Vector<double> fluid_vel_x(comp_dom.dh.n_dofs());
10250  Vector<double> fluid_vel_y(comp_dom.dh.n_dofs());
10251  Vector<double> fluid_vel_z(comp_dom.dh.n_dofs());
10252  Vector<double> nodes_vel_x(comp_dom.dh.n_dofs());
10253  Vector<double> nodes_vel_y(comp_dom.dh.n_dofs());
10254  Vector<double> nodes_vel_z(comp_dom.dh.n_dofs());
10255  //Vector<double> map_init_x(comp_dom.dh.n_dofs());
10256  //Vector<double> map_init_y(comp_dom.dh.n_dofs());
10257  //Vector<double> map_init_z(comp_dom.dh.n_dofs());
10258 
10259  Vector<double> complete_potential_gradients(comp_dom.vector_dh.n_dofs());
10260  compute_potential_gradients(complete_potential_gradients,phi,dphi_dn);
10261 
10262  for (unsigned int i = 0; i < comp_dom.dh.n_dofs(); i++)
10263  {
10264  fluid_vel_x(i) = complete_potential_gradients(i*dim)+Vinf(0);
10265  fluid_vel_y(i) = complete_potential_gradients(i*dim+1)+Vinf(1);
10266  fluid_vel_z(i) = complete_potential_gradients(i*dim+2)+Vinf(2);
10267  if ( ((comp_dom.flags[i] & boat) &&
10268  !(comp_dom.flags[i] & near_water) ) ||
10269  (comp_dom.flags[i] & transom_on_water) )
10270  {
10271 
10272  Point<3> rig_vel(hull_ang_vel(1)*(comp_dom.support_points[i](2)-hull_lin_displ(2))-
10273  hull_ang_vel(2)*(comp_dom.support_points[i](1)-hull_lin_displ(1))+hull_lin_vel(0),
10274  hull_ang_vel(2)*(comp_dom.support_points[i](0)-hull_lin_displ(0))-
10275  hull_ang_vel(0)*(comp_dom.support_points[i](2)-hull_lin_displ(2))+hull_lin_vel(1),
10276  hull_ang_vel(0)*(comp_dom.support_points[i](1)-hull_lin_displ(1))-
10277  hull_ang_vel(1)*(comp_dom.support_points[i](0)-hull_lin_displ(0))+hull_lin_vel(2));
10278 
10279  nodes_vel_x(i) = nodes_vel(i*dim)+rig_vel(0);
10280  nodes_vel_y(i) = nodes_vel(i*dim+1)+rig_vel(1);
10281  nodes_vel_z(i) = nodes_vel(i*dim+2)+rig_vel(2);
10282  }
10283  else
10284  {
10285  nodes_vel_x(i) = nodes_vel(i*dim);
10286  nodes_vel_y(i) = nodes_vel(i*dim+1);
10287  nodes_vel_z(i) = nodes_vel(i*dim+2);
10288  }
10289  //map_init_x(i) = comp_dom.initial_map_points(i*dim);
10290  //map_init_y(i) = comp_dom.initial_map_points(i*dim+1);
10291  //map_init_z(i) = comp_dom.initial_map_points(i*dim+2);
10292  }
10293 
10294 
10295  Vector<double> elevations(comp_dom.dh.n_dofs());
10296  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); i++)
10297  {
10298  elevations(i) = solution(dim*i+dim-1);
10299  }
10300 
10301  Vector<double> pressure(comp_dom.dh.n_dofs());
10302  Vector<double> comp_1(comp_dom.dh.n_dofs());
10303  Vector<double> comp_2(comp_dom.dh.n_dofs());
10304  Vector<double> comp_3(comp_dom.dh.n_dofs());
10305  Vector<double> comp_4(comp_dom.dh.n_dofs());
10306  compute_pressure(pressure,comp_1,comp_2,comp_3,comp_4,t,solution,solution_dot);
10307 
10308  // preparing iges normal vectors vector for pressure computation
10309  Vector<double> iges_normals_x_values(comp_dom.dh.n_dofs());
10310  Vector<double> iges_normals_y_values(comp_dom.dh.n_dofs());
10311  Vector<double> iges_normals_z_values(comp_dom.dh.n_dofs());
10312  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
10313  {
10314  iges_normals_x_values(i) = comp_dom.iges_normals[i](0);
10315  iges_normals_y_values(i) = comp_dom.iges_normals[i](1);
10316  iges_normals_z_values(i) = comp_dom.iges_normals[i](2);
10317  }
10318 
10319  {
10320  DataOut<dim-1, DoFHandler<dim-1, dim> > dataout;
10321 
10322  dataout.attach_dof_handler(comp_dom.dh);
10323 
10324 
10325  dataout.add_data_vector((const Vector<double> &)phi, "phi");
10326  dataout.add_data_vector((const Vector<double> &)phi_dot, "phi_dot");
10327  dataout.add_data_vector(elevations, "elevations");
10328  dataout.add_data_vector(pressure, "pressure");
10329  dataout.add_data_vector((const Vector<double> &)dphi_dn, "dphi_dn");
10330  dataout.add_data_vector(fluid_vel_x, "fluid_vel_x");
10331  dataout.add_data_vector(fluid_vel_y, "fluid_vel_y");
10332  dataout.add_data_vector(fluid_vel_z, "fluid_vel_z");
10333  dataout.add_data_vector(nodes_vel_x, "nodes_vel_x");
10334  dataout.add_data_vector(nodes_vel_y, "nodes_vel_y");
10335  dataout.add_data_vector(nodes_vel_z, "nodes_vel_z");
10336  //cout<<"####### "<<break_wave_press.size()<<endl;
10337  //cout<<"#-----# "<<nodes_vel_z.size()<<endl;
10338  dataout.add_data_vector(break_wave_press, "break_wave_press");
10339  dataout.add_data_vector(comp_1, "comp_1");
10340  dataout.add_data_vector(comp_2, "comp_2");
10341  dataout.add_data_vector(comp_3, "comp_3");
10342  dataout.add_data_vector(comp_4, "comp_4");
10343  dataout.add_data_vector(iges_normals_x_values, "iges_normals_x");
10344  dataout.add_data_vector(iges_normals_y_values, "iges_normals_y");
10345  dataout.add_data_vector(iges_normals_z_values, "iges_normals_z");
10346  //dataout.add_data_vector(map_init_x, "map_init_x");
10347  //dataout.add_data_vector(map_init_y, "map_init_y");
10348  //dataout.add_data_vector(map_init_z, "map_init_z");
10349  //dataout.add_data_vector(DphiDt_sys_solution_2, "damping");
10350 
10351  dataout.build_patches(*comp_dom.mapping,
10352  comp_dom.vector_fe.degree,
10353  DataOut<dim-1, DoFHandler<dim-1, dim> >::curved_inner_cells);
10354 
10355  std::ofstream file(filename.c_str());
10356 
10357  dataout.write_vtu(file);
10358  }
10359 
10360  std::string hull_motions_filename = ( output_file_name + "_hull_motions.txt" );
10361 
10362  ofstream myfile;
10363  if ( fabs(t-initial_time) < 1e-5 )
10364  myfile.open (hull_motions_filename.c_str());
10365  else
10366  myfile.open (hull_motions_filename.c_str(),ios::app);
10367  myfile << t <<" "<<baricenter_pos<<" "<<comp_dom.boat_model.yaw_angle<<" "<<-comp_dom.boat_model.pitch_angle+comp_dom.boat_model.initial_trim<<" "<<-comp_dom.boat_model.roll_angle<<" "<<hull_lin_vel<<" "<<hull_ang_vel<<" \n";
10368  myfile.close();
10369 
10370 
10371  /*
10372  Standard_Integer NbPointConstraint=1;
10373  // Initialize a BuildPlateSurface
10374  GeomPlate_BuildPlateSurface BPSurf(4,15,4);
10375  // Point constraints
10376  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
10377  {
10378  if (comp_dom.flags[i] & water)
10379  {
10380  Handle(GeomPlate_PointConstraint) PCont= new GeomPlate_PointConstraint(Pnt(comp_dom.support_points[i]),0);
10381  BPSurf.Add(PCont);
10382  }
10383  }
10384  // Compute the Plate surface
10385  BPSurf.Perform();
10386 
10387 
10388 
10389  // Approximation of the Plate surface
10390  Standard_Integer MaxSeg=100;
10391  Standard_Integer MaxDegree=8;
10392  Standard_Integer CritOrder=0;
10393  Standard_Real dmax,Tol;
10394  Handle(GeomPlate_Surface) PSurf = BPSurf.Surface();
10395  //dmax = Max(0.0001,10*BPSurf.G0Error());
10396  dmax = 0.00001;
10397  Tol=0.00001;
10398  GeomPlate_MakeApprox
10399  Mapp(PSurf,Tol,MaxSeg,MaxDegree,dmax,CritOrder);
10400  Handle (Geom_Surface) Surf (Mapp.Surface());
10401  // create a face corresponding to the approximated Plate Surface
10402  Standard_Real Umin, Umax, Vmin, Vmax;
10403  PSurf->Bounds( Umin, Umax, Vmin, Vmax);
10404  BRepBuilderAPI_MakeFace MF(Surf,Umin, Umax, Vmin, Vmax,1e-4);
10405 
10406  TopoDS_Shape cut_edge;
10407  intersect_plane(MF,cut_edge,1.0,0.0,0.0,-2.32422);
10408  // These lines can be used to dump the surface on an .igs file
10409 
10410  IGESControl_Controller::Init();
10411  IGESControl_Writer ICW ("MM", 0);
10412  Standard_Boolean ok = ICW.AddShape (MF);
10413  ICW.AddShape (cut_edge);
10414  //Standard_Boolean ok = ICW.AddShape (Pnt(comp_dom.support_points[0]));
10415  ICW.ComputeModel();
10416  Standard_Boolean OK = ICW.Write ("free_surf.igs");
10417  */
10418 
10419 //compute_internal_velocities(phi,dphi_dn);
10420 
10421 
10422 }
10423 
10424 
10425 template <int dim>
10427  const Vector<double> &dphi_dn)
10428 {
10429 
10430  unsigned int n_points;
10431 
10432  // Create streamobject
10433  ifstream infile;
10434  infile.open("points.txt");
10435 
10436  // Exit if file opening failed
10437  if (!infile.is_open())
10438  {
10439  cerr<<"Opening failed"<<endl;
10440  exit(1);
10441  }
10442 
10443  // Get number of points
10444  infile >> n_points;
10445 
10446  std::vector< Point<3> > points(n_points,Point<3>(0.0,0.0,0.0));
10447  std::vector< Point<3> > velocities(n_points,Point<3>(0.0,0.0,0.0));
10448 
10449  unsigned int count = 0;
10450  while (!infile.eof())
10451  {
10452  infile >> points[count](0) >> points[count](1) >> points[count](2);
10453  ++count;
10454  }
10455  infile.close();
10456 
10457 
10458 
10459 
10460  comp_dom.update_support_points();
10461 
10462 
10463  FEValues<dim-1,dim> fe_v(*comp_dom.mapping, comp_dom.fe, *comp_dom.quadrature,
10464  update_values | update_gradients |
10465  update_cell_normal_vectors |
10466  update_quadrature_points |
10467  update_JxW_values);
10468 
10469 
10470  const unsigned int n_q_points = fe_v.n_quadrature_points;
10471  const unsigned int dofs_per_cell = comp_dom.fe.dofs_per_cell;
10472  std::vector<unsigned int> local_dof_indices (dofs_per_cell);
10473 
10474  std::vector<double> q_phi(n_q_points);
10475  std::vector<double> q_dphi_dn(n_q_points);
10476 
10477 
10478 
10479  cell_it
10480  cell = comp_dom.dh.begin_active(),
10481  endc = comp_dom.dh.end();
10482 
10483  for (; cell!=endc; ++cell)
10484  {
10485  fe_v.reinit(cell);
10486 
10487  fe_v.get_function_values(dphi_dn, q_dphi_dn);
10488  fe_v.get_function_values(phi, q_phi);
10489  const std::vector<Point<dim> > &quad_nodes = fe_v.get_quadrature_points();
10490  const std::vector<Point<dim> > &quad_nodes_normals = fe_v.get_normal_vectors();
10491 
10492  for (unsigned int i=0; i<n_points; ++i)
10493  {
10494  fad_double x,y,z;
10495  x = points[i](0);
10496  y = points[i](1);
10497  z = points[i](2);
10498 
10499  x.diff(0,3);
10500  y.diff(1,3);
10501  z.diff(2,3);
10502 
10503  for (unsigned int q=0; q<n_q_points; ++q)
10504  {
10505 
10506  Point <dim, fad_double > r(quad_nodes[q](0)-x,quad_nodes[q](1)-y,quad_nodes[q](2)-z);
10507 
10508  fad_double G = fad_double(1.0/(4.0*numbers::PI))/r.norm();
10509 
10510  fad_double dG_dn = -(r(0)*fad_double(quad_nodes_normals[q](0))+
10511  r(1)*fad_double(quad_nodes_normals[q](1))+
10512  r(2)*fad_double(quad_nodes_normals[q](2)))/(fad_double(4.0*numbers::PI)*pow(r.norm(),3.0));
10513 
10514 
10515  //cout<<"G: "<<G.val()<<" "<<G_x_plus<<" "<<G_z_plus<<endl;
10516 
10517  Point<dim> grad_G(G.fastAccessDx(0),G.fastAccessDx(1),G.fastAccessDx(2));
10518  Point<dim> grad_dG_dn(dG_dn.fastAccessDx(0),dG_dn.fastAccessDx(1),dG_dn.fastAccessDx(2));
10519 
10520  velocities[i] += (q_dphi_dn[q]*grad_G - q_phi[q]*grad_dG_dn)*fe_v.JxW(q);
10521 
10522  }
10523 
10524  }
10525 
10526  }
10527 
10528 
10529  for (unsigned int i=0; i<n_points; ++i)
10530  cout<<i<<" P("<<points[i]<<") grad_phi("<<velocities[i]<<") "<<endl;
10531 
10532  ofstream myfile;
10533  myfile.open ("velocities.txt");
10534  for (unsigned int i=0; i<n_points; ++i)
10535  myfile<<velocities[i]<<endl;
10536  myfile.close();
10537 }
10538 
10539 template <int dim>
10541  ConstraintMatrix &cc)
10542 {
10543  std::vector<Point<dim> > supp_points(comp_dom.vector_dh.n_dofs());
10544  DoFTools::map_dofs_to_support_points<dim-1, dim>( *comp_dom.mapping,
10545  comp_dom.vector_dh,
10546  supp_points);
10547 
10548  // we start clearing the constraint matrices
10549  c.clear();
10550  cc.clear();
10551 
10552 
10553  // here we prepare the constraint matrices so as to account for the presence hanging
10554  // nodes
10555 
10557  DoFTools::make_hanging_node_constraints (comp_dom.vector_dh,cc);
10558  /*
10559  for(unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
10560  {
10561  std::cout << i << std::endl;
10562  if (c.is_constrained(i))
10563  {
10564  std::cout << "Constraining " << i << std::endl;
10565  cc.add_line(i);
10566  c.add_line(i);
10567  cc.set_inhomogeneity(i, 0);
10568  }
10569  }
10570  //*/
10571 
10572  cc.close();
10573  c.close();
10574 }
10575 
10576 
10577 template <int dim>
10579  const Vector<double> &yp,
10580  const std::string fname) const
10581 {
10582  std::cout << "Dumping solution: " << fname << std::endl;
10583  std::ofstream ofile((fname+"_y.dat").c_str());
10584  y.block_write(ofile);
10585  ofile.close();
10586  ofile.open((fname+"_yp.dat").c_str());
10587  yp.block_write(ofile);
10588  comp_dom.dump_tria(fname+"_tria.dat");
10589  ofile.close();
10590 }
10591 
10592 
10593 
10594 template <int dim>
10596  Vector<double> &yp,
10597  const std::string fname)
10598 {
10599  std::cout << "Restoring solution: " << fname << std::endl;
10600 
10601  std::ifstream ifile((fname+"_y.dat").c_str());
10602  y.block_read(ifile);
10603  ifile.close();
10604  ifile.open((fname+"_yp.dat").c_str());
10605  yp.block_read(ifile);
10606  ifile.close();
10607  comp_dom.restore_tria(fname+"_tria.dat");
10608  comp_dom.update_mapping(y);
10609 
10610 
10611 }
10612 
10613 
10614 template <int dim>
10616 {
10617  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
10618  {
10619  if (sys_comp(i) == 0)
10620  {
10621  std::set<unsigned int> doubles = comp_dom.vector_double_nodes_set[i];
10622  for (std::set<unsigned int>::iterator it = doubles.begin() ; it != doubles.end(); it++ )
10623  {
10624  //if(sys_comp(*it) == 1)
10625  comp_dom.map_points(i) = comp_dom.map_points(*it);
10626  //else
10627  // map_points(*it) = map_points(i);
10628  }
10629  }
10630  }
10631 
10632  comp_dom.full_mesh_treatment();
10633  vector_constraints.distribute(comp_dom.map_points);
10634 }
10635 
10636 template <int dim>
10638 {
10639  for (unsigned int i=0; i<comp_dom.vector_dh.n_dofs(); ++i)
10640  {
10641  if (sys_comp(i) == 0)
10642  {
10643  std::set<unsigned int> doubles = comp_dom.vector_double_nodes_set[i];
10644  for (std::set<unsigned int>::iterator it = doubles.begin() ; it != doubles.end(); it++ )
10645  {
10646  //if(sys_comp(*it) == 1)
10647  comp_dom.map_points(i) = comp_dom.map_points(*it);
10648  //else
10649  // map_points(*it) = map_points(i);
10650  }
10651  }
10652  }
10653  comp_dom.partial_mesh_treatment(blend_factor);
10654  vector_constraints.distribute(comp_dom.map_points);
10655 }
10656 
10657 
10658 
10659 
10660 template <int dim>
10662 {
10663 
10664 }
10665 
10666 
10667 
10668 
10669 template class FreeSurface<3>;
10670 
void block_read(std::istream &in)
const Tensor< 1, spacedim > & shape_grad(const unsigned int function_no, const unsigned int quadrature_point) const
void refine_and_coarsen_fixed_number(Triangulation< dim, spacedim > &triangulation, const VectorType &criteria, const double top_fraction_of_cells, const double bottom_fraction_of_cells, const unsigned int max_n_cells=std::numeric_limits< unsigned int >::max())
void prepare_bem_vectors(double time, Vector< double > &bem_bc, Vector< double > &dphi_dn) const
real_type l2_norm() const
active_cell_iterator begin_active(const unsigned int level=0) const
virtual void output_step(Vector< double > &solution, const unsigned int step_number)
This function is called at the end of each iteration step for the newton solver.
#define AssertDimension(dim1, dim2)
void prepare_restart(const double t, Vector< double > &y, Vector< double > &yp, bool restart_flag=true)
Method to make sure residual is null at each (re)start of the computation.
void map_dofs_to_support_points(const Mapping< dim, spacedim > &mapping, const DoFHandler< dim, spacedim > &dof_handler, std::vector< Point< spacedim > > &support_points)
virtual int residual(const double t, Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src_yp)
For dae problems, we need a residual function.
static void declare_parameters(ParameterHandler &param)
Tensor< 1, dim, Type > & T(Point< dim, Type > &p)
Definition: free_surface.h:89
void remove_transom_hanging_nodes(Vector< double > &solution, Vector< double > &solution_dot, const double t, const unsigned int step_number, const double h)
void set(const std::string &entry_name, const std::string &new_value)
void output_results(const std::string, const double t, const Vector< double > &solution, const Vector< double > &pressure)
ActiveSelector::active_cell_iterator active_cell_iterator
virtual int setup_jacobian_prec(const Vector< double > &src_yy)
Setup Jacobian preconditioner for Newton.
numbers::NumberTraits< double >::real_type distance(const Point< dim, double > &p) const
numbers::NumberTraits< Number >::real_type norm() const
#define AssertThrow(cond, exc)
iterator end()
virtual void reinit(const SparsityPattern &sparsity)
std::string get(const std::string &entry_string) const
void vmult(Vector< double > &dst, const Vector< double > &src) const
static void declare_parameters(ParameterHandler &prm, const unsigned int n_components=1)
virtual unsigned int n_dofs() const
Returns the number of degrees of freedom.
virtual unsigned int n_dofs() const
Returns the number of degrees of freedom.
void enter_subsection(const std::string &subsection)
static const double PI
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 distribute_local_to_global(const InVector &local_vector, const std::vector< size_type > &local_dof_indices, OutVector &global_vector) const
virtual unsigned int n_dofs() const
Returns the number of degrees of freedom.
Vector< double > & get_diameters()
static::ExceptionBase & ExcMessage(std::string arg1)
DoFHandler< dim-1, dim >::active_cell_iterator cell_it
Definition: free_surface.h:243
void enforce_partial_geometry_constraints(const double blend_factor)
static void reorder_cells(std::vector< CellData< dim > > &original_cells, const bool use_new_style_ordering=false)
#define Assert(cond, exc)
void compute_potential_gradients(Vector< double > &complete_potential_gradients, const Vector< double > &phi, const Vector< double > &dphi_dn)
Sacado::Fad::DFad< double > fad_double
Definition: free_surface.cc:52
void compute_keel_smoothing(Vector< double > &smoothing)
std::size_t size() const
Triangulation< dim-1, dim >::active_cell_iterator tria_it
Definition: free_surface.h:244
void declare_parameters(ParameterHandler &prm)
Definition: free_surface.cc:59
virtual bool solution_check(Vector< double > &solution, Vector< double > &solution_dot, const double t, const unsigned int step_number, const double h)
This function will check the behaviour of the solution.
std::map< types::boundary_id, const Function< dim, Number > * > type
virtual Vector< double > & differential_components()
And an identification of the differential components.
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 >())
void block_write(std::ostream &out) const
virtual int jacobian_prec(const double t, Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src_yp, const Vector< double > &src, const double alpha)
Jacobian inverse preconditioner vector product for dae.
void enforce_full_geometry_constraints()
iterator begin()
std::string int_to_string(const unsigned int value, const unsigned int digits=numbers::invalid_unsigned_int)
std::map< unsigned int, unsigned int > indices_map
void print(const char *format=0) const DEAL_II_DEPRECATED
void compute_internal_velocities(const Vector< double > &phi, const Vector< double > &dphi_dn)
void dump_solution(const Vector< double > &y, const Vector< double > &yp, const std::string fname) const
const unsigned int dofs_per_cell
void leave_subsection()
bool get_bool(const std::string &entry_name) const
void compute_pressure(Vector< double > &press, Vector< double > &comp_1, Vector< double > &comp_2, Vector< double > &comp_3, Vector< double > &comp_4, const double t, const Vector< double > &solution, const Vector< double > &solution_dot)
const unsigned int n_quadrature_points
numbers::NumberTraits< double >::real_type square() const
virtual int jacobian_prec_prod(Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src)
Jacobian preconditioner vector product for newton solver.
const double & shape_value(const unsigned int function_no, const unsigned int point_no) const
double norm(const FEValuesBase< dim > &fe, const VectorSlice< const std::vector< std::vector< Tensor< 1, dim > > > > &Du)
dealii::Point< 3 > Pnt(const gp_Pnt &p)
Convert OpenCascade point into.
Definition: occ_utilities.h:76
virtual int jacobian(const double t, Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src_yp, const Vector< double > &src, const double alpha)
Jacobian vector product for dae.
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)
void initialize(const SparsityPattern &sparsity_pattern)
unsigned int solve(Vector< double > &solution, const unsigned int max_steps)
Solve.
void make_edges_conformal(Vector< double > &solution, Vector< double > &solution_dot, const double t, const unsigned int step_number, const double h)
Method to enforce mesh conformity at edges at each restart.
int residual_and_jacobian(const double t, Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src_yp, const Vector< double > &src, const double alpha, const bool is_jacobian)
This function computes either DAE residual or corrensponding Jacobian matrix vector product with vect...
void add(const doublea, const FullMatrix< number2 > &A)
double get_double(const std::string &entry_name) const
virtual void distribute_dofs(const FiniteElement< dim, spacedim > &fe)
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
void compute_constraints(ConstraintMatrix &constraints, ConstraintMatrix &vector_constraints)
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::pair< double, unsigned int > mypair
Handle(Geom_Curve) NumericalTowingTank
void compute_DXDt_and_DphiDt(double time, const Vector< double > &phi, const Vector< double > &dphi_dn, const Vector< double > &nodes_velocities)
SparseMatrix< number > & copy_from(const SparseMatrix< somenumber > &source)
void restore_solution(Vector< double > &y, Vector< double > &yp, const std::string fname)
bool comparator(const mypair &l, const mypair &r)
void reinit(const TriaIterator< DoFCellAccessor< DoFHandlerType< dim, spacedim >, level_dof_access > > &cell)
static void estimate(const Mapping< dim, spacedim > &mapping, const DoFHandlerType &dof, const Quadrature< dim-1 > &quadrature, const typename FunctionMap< spacedim >::type &neumann_bc, const InputVector &solution, Vector< float > &error, const ComponentMask &component_mask=ComponentMask(), const Function< spacedim > *coefficients=0, const unsigned int n_threads=numbers::invalid_unsigned_int, const types::subdomain_id subdomain_id=numbers::invalid_subdomain_id, const types::material_id material_id=numbers::invalid_material_id, const Strategy strategy=cell_diameter_over_24)
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)
void initial_conditions(Vector< double > &dst)
void parse_parameters(ParameterHandler &prm)
long int get_integer(const std::string &entry_string) const
void vmult(Vector< double > &dst, const Vector< double > &src) const
static::ExceptionBase & ExcInternalError()
std::map< unsigned int, unsigned int > indices_map