WaveBEM: Unsteady Nonlinear Potential Flow Solver for Ship-Wave Interaction.
restart_nonlinear_problem_diff.h
Go to the documentation of this file.
1 // The program starts with including a bunch
2 // of include files that we will use in the
3 // various parts of the program. Most of them
4 // have been discussed in previous tutorials
5 // already:
6 #ifndef restart_nonlinear_problem_diff_h
7 #define restart_nonlinear_problem_diff_h
8 
9 
10 #include <free_surface.h>
11 #include <numerical_towing_tank.h>
12 #include <newton_argument.h>
13 
14 
16  public NewtonArgument
17 {
18 public:
21  const double &time,
25  free_surface(free_surface),
26  comp_dom(comp_dom),
27  time(time),
28  free_surf_y(free_surf_y),
29  free_surf_y_dot(free_surf_y_dot),
30  free_surf_jacobian_dot(free_surf_jacobian_dot)
31  {
32  // we first need to count the nodes of the water line. for each of them, we will have a vertical (z)
33  // component, and a horizontal (y) component
34 
35  water_line_indices.clear();
36  bow_stern_indices.clear();
37  water_indices.clear();
38  phi_indices.clear();
39  rigid_modes_indices.clear();
40 
41  if (!comp_dom.no_boat)
42  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
43  {
44  if ( (comp_dom.flags[i] & water) &&
45  (comp_dom.flags[i] & near_boat) &&
46  !(comp_dom.flags[i] & transom_on_water) &&
47  (comp_dom.moving_point_ids[3] != i) &&
48  (comp_dom.moving_point_ids[4] != i) &&
49  (comp_dom.moving_point_ids[5] != i) &&
50  (comp_dom.moving_point_ids[6] != i) )
51  {
52  //cout<<"WL "<<i<<" ("<<3*i+1<<" "<<3*i+2<<")"<<endl;
53  water_line_indices.insert(i);
54  }
55  }
56 
57  //this takes care of the bow and stern nodes
58  if (!comp_dom.no_boat)
59  for (unsigned int k=3; k<7; ++k)
60  {
61  unsigned int i = comp_dom.moving_point_ids[k];
62  bow_stern_indices.insert(i);
63  //cout<<"BS "<<i<<" ("<<3*i<<" "<<3*i+1<<" "<<3*i+2<<")"<<endl;
64  }
65 
66  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
67  {
68  if ( (comp_dom.flags[i] & water) &&
69  (comp_dom.flags[i] & near_boat)==0 &&
70  (comp_dom.flags[i] & transom_on_water)==0 &&
71  (comp_dom.flags[i] & near_inflow)==0 &&
72  (comp_dom.vector_constraints.is_constrained(3*i+2))==0 )
73  {
74  //cout<<"W "<<i<<" ("<<3*i+2<<")"<<endl;
75  water_indices.insert(i);
76  }
77  }
78 
79  // let's take care of the potential dofs
80  for (unsigned int i=0; i<comp_dom.dh.n_dofs(); ++i)
81  {
82  if (comp_dom.flags[i] & water)
83  // if node is on free surface, component is differential
84  {
85  // unless node is a transom_on_water node . then it's algebraic
86  if ( (comp_dom.vector_flags[3*i] & transom_on_water) ||
87  (comp_dom.vector_constraints.is_constrained(3*i)) )
88  {
89  }
90  else
91  {
92  phi_indices.insert(i);
93  }
94  }
95  }
96 
97  // we now add the rigid modes dofs
98  for (unsigned int d=0; d<13; ++d)
99  {
100  rigid_modes_indices.insert(d);
101  }
102 
103  free_surf_jac_x_delta.reinit(free_surf_y.size());
104  free_surf_res.reinit(free_surf_y.size());
105 
106 
107 
108  unsigned int count = 0;
109  for (std::set <unsigned int>::iterator pos = water_line_indices.begin(); pos != water_line_indices.end(); ++pos)
110  {
111  unsigned int i=*pos;
112  indices_map[3*i+1] = count;
113  count++;
114  indices_map[3*i+2] = count;
115  count++;
116  }
117  for (std::set <unsigned int>::iterator pos = bow_stern_indices.begin(); pos != bow_stern_indices.end(); ++pos)
118  {
119  unsigned int i=*pos;
120  Point<3> t(comp_dom.edges_tangents[3*i],comp_dom.edges_tangents[3*i+1],comp_dom.edges_tangents[3*i+2]);
121  indices_map[3*i] = count;
122  count++;
123  indices_map[3*i+1] = count;
124  count++;
125  indices_map[3*i+2] = count;
126  count++;
127  }
128  for (std::set <unsigned int>::iterator pos = water_indices.begin(); pos != water_indices.end(); ++pos)
129  {
130  unsigned int i=*pos;
131  indices_map[3*i+2] = count;
132  count++;
133  }
134 
135  for (std::set <unsigned int>::iterator pos = phi_indices.begin(); pos != phi_indices.end(); ++pos)
136  {
137  unsigned int i=*pos;
138  indices_map[i+comp_dom.vector_dh.n_dofs()] = count;
139  count++;
140  }
141 
142  for (std::set <unsigned int>::iterator pos = rigid_modes_indices.begin(); pos != rigid_modes_indices.end(); ++pos)
143  {
144  unsigned int i=*pos;
145  indices_map[i+comp_dom.vector_dh.n_dofs()+comp_dom.dh.n_dofs()+comp_dom.dh.n_dofs()] = count;
146  count++;
147  }
148 
149 
150  //cout<<" MAP "<<endl;
151  //for (std::map <unsigned int,unsigned int>::iterator pos = indices_map.begin(); pos != indices_map.end(); ++pos)
152  // {
153  // cout<<"Restart: "<<pos->second<<" ---> DAE: "<<pos->first<<endl;
154  // }
155  //cout<<" REPORT "<<endl;
156  //cout<<count<<endl;
157  //cout<<2*water_line_indices.size()<<endl;
158  //cout<<3*bow_stern_indices.size()<<endl;
159  //cout<<water_indices.size()<<endl;
160  //cout<<phi_indices.size()<<endl;
161  //cout<<2*water_line_indices.size()+3*bow_stern_indices.size()+water_indices.size()+phi_indices.size()+dphi_dn_indices.size()<<endl;
162  std::vector<unsigned int> line_lengths(2*water_line_indices.size()+
163  3*bow_stern_indices.size()+
164  water_indices.size()+
165  phi_indices.size()+
166  rigid_modes_indices.size());
167  for (unsigned int i=0; i<2*water_line_indices.size()+3*bow_stern_indices.size()+water_indices.size()+phi_indices.size(); ++i)
168  line_lengths[i] = 40;
169  for (unsigned int i=0; i<rigid_modes_indices.size(); ++i)
170  line_lengths[i+2*water_line_indices.size()+3*bow_stern_indices.size()+water_indices.size()+phi_indices.size()] =
172 
175  line_lengths );
176 
177  count = 0;
178  for (std::set <unsigned int>::iterator pos = water_line_indices.begin(); pos != water_line_indices.end(); ++pos)
179  {
180  unsigned int i=*pos;
181  jacobian_sparsity_pattern.add(count,count);
182  jacobian_sparsity_pattern.add(count,count+1);
183  count++;
184  for (SparsityPattern::iterator col=free_surf_jacobian_dot.get_sparsity_pattern().begin(3*i+2);
185  col!=free_surf_jacobian_dot.get_sparsity_pattern().end(3*i+2); ++col)
186  if ( indices_map.count(col->column()) )
187  jacobian_sparsity_pattern.add(count,indices_map.find(col->column())->second);
188  count++;
189  }
190  for (std::set <unsigned int>::iterator pos = bow_stern_indices.begin(); pos != bow_stern_indices.end(); ++pos)
191  {
192  unsigned int i=*pos;
193  Point<3> t(comp_dom.edges_tangents[3*i],comp_dom.edges_tangents[3*i+1],comp_dom.edges_tangents[3*i+2]);
194  jacobian_sparsity_pattern.add(count,count);
195  jacobian_sparsity_pattern.add(count,count+2);
196  count++;
197  jacobian_sparsity_pattern.add(count,count);
198  jacobian_sparsity_pattern.add(count,count+1);
199  count++;
200  for (SparsityPattern::iterator col=free_surf_jacobian_dot.get_sparsity_pattern().begin(3*i+2);
201  col!=free_surf_jacobian_dot.get_sparsity_pattern().end(3*i+2); ++col)
202  if ( indices_map.count(col->column()) )
203  jacobian_sparsity_pattern.add(count,indices_map.find(col->column())->second);
204  count++;
205  }
206  for (std::set <unsigned int>::iterator pos = water_indices.begin(); pos != water_indices.end(); ++pos)
207  {
208  unsigned int i=*pos;
209  for (SparsityPattern::iterator col=free_surf_jacobian_dot.get_sparsity_pattern().begin(3*i+2);
210  col!=free_surf_jacobian_dot.get_sparsity_pattern().end(3*i+2); ++col)
211  if ( indices_map.count(col->column()) )
212  jacobian_sparsity_pattern.add(count,indices_map.find(col->column())->second);
213  count++;
214  }
215 
216  for (std::set <unsigned int>::iterator pos = phi_indices.begin(); pos != phi_indices.end(); ++pos)
217  {
218  unsigned int i=*pos;
219  for (SparsityPattern::iterator col=free_surf_jacobian_dot.get_sparsity_pattern().begin(i+comp_dom.vector_dh.n_dofs());
220  col!=free_surf_jacobian_dot.get_sparsity_pattern().end(i+comp_dom.vector_dh.n_dofs()); ++col)
221  if ( indices_map.count(col->column()) )
222  jacobian_sparsity_pattern.add(count,indices_map.find(col->column())->second);
223  count++;
224  }
225 
226  for (std::set <unsigned int>::iterator pos = rigid_modes_indices.begin(); pos != rigid_modes_indices.end(); ++pos)
227  {
228  unsigned int i=*pos;
229  for (SparsityPattern::iterator col=free_surf_jacobian_dot.get_sparsity_pattern().begin(i+comp_dom.vector_dh.n_dofs());
230  col!=free_surf_jacobian_dot.get_sparsity_pattern().end(i+comp_dom.vector_dh.n_dofs()); ++col)
231  if ( indices_map.count(col->column()) )
232  jacobian_sparsity_pattern.add(count,indices_map.find(col->column())->second);
233  count++;
234  }
237 
238 
239 
240  }
241 
242  virtual unsigned int n_dofs() const;
243 
244  virtual void output_step(Vector<double> &solution,
245  const unsigned int step_number);
246 
250  virtual int residual(Vector<double> &dst,
251  const Vector<double> &src_yy);
252 
254  virtual int jacobian(Vector<double> &dst,
255  const Vector<double> &src_yy,
256  const Vector<double> &src);
257 
259  virtual int setup_jacobian_prec(const Vector<double> &src_yy);
260 
263  virtual int jacobian_prec(Vector<double> &dst,
264  const Vector<double> &src_yy,
265  const Vector<double> &src);
266 
269  virtual int jacobian_prec_prod(Vector<double> &dst,
270  const Vector<double> &src_yy,
271  const Vector<double> &src);
272 
273 private:
274 
277  const double &time;
281 
284  std::set<unsigned int> water_line_indices;
285  std::set<unsigned int> bow_stern_indices;
286  std::set<unsigned int> water_indices;
287  std::set<unsigned int> phi_indices;
288  std::set<unsigned int> rigid_modes_indices;
291 
292 public:
293  std::map<unsigned int,unsigned int> indices_map;
294 
295 };
296 
297 #endif
virtual int setup_jacobian_prec(const Vector< double > &src_yy)
Setup Jacobian preconditioner for Newton.
std::set< unsigned int > rigid_modes_indices
ConstraintMatrix vector_constraints
DoFHandler< dim-1, dim > vector_dh
bool is_constrained(const size_type index) const
iterator begin() const
virtual int jacobian_prec(Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src)
Jacobian inverse preconditioner vector product for newton solver.
virtual int jacobian_prec_prod(Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src)
Jacobian preconditioner vector product for newton solver.
virtual int residual(Vector< double > &dst, const Vector< double > &src_yy)
For newton solver, we need a residual function.
virtual void reinit(const SparsityPattern &sparsity)
std::vector< unsigned int > moving_point_ids
virtual unsigned int n_dofs() const
Returns the number of degrees of freedom.
void add(const size_type i, const size_type j)
std::vector< GeometryFlags > flags
types::global_dof_index n_dofs() const
std::size_t size() const
iterator end() const
std::map< unsigned int, unsigned int > indices_map
std::vector< GeometryFlags > vector_flags
const SparseMatrix< double > & free_surf_jacobian_dot
void reinit(const size_type m, const size_type n, const unsigned int max_per_row)
RestartNonlinearProblemDiff(FreeSurface< 3 > &free_surface, const NumericalTowingTank &comp_dom, const double &time, Vector< double > &free_surf_y, Vector< double > &free_surf_y_dot, const SparseMatrix< double > &free_surf_jacobian_dot)
Base class that needs to be inherited by any function that wants to use the newton solver class...
const SparsityPattern & get_sparsity_pattern() const
virtual int jacobian(Vector< double > &dst, const Vector< double > &src_yy, const Vector< double > &src)
Jacobian vector product for newton solver.
virtual void reinit(const size_type N, const bool omit_zeroing_entries=false)
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.
Vector< double > edges_tangents
DoFHandler< dim-1, dim > dh