barrel.cc
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Version 1.0; svn revision $LastChangedRevision$
7 //LIC//
8 //LIC// $LastChangedDate$
9 //LIC//
10 //LIC// Copyright (C) 2006-2016 Matthias Heil and Andrew Hazel
11 //LIC//
12 //LIC// This library is free software; you can redistribute it and/or
13 //LIC// modify it under the terms of the GNU Lesser General Public
14 //LIC// License as published by the Free Software Foundation; either
15 //LIC// version 2.1 of the License, or (at your option) any later version.
16 //LIC//
17 //LIC// This library is distributed in the hope that it will be useful,
18 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 //LIC// Lesser General Public License for more details.
21 //LIC//
22 //LIC// You should have received a copy of the GNU Lesser General Public
23 //LIC// License along with this library; if not, write to the Free Software
24 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 //LIC// 02110-1301 USA.
26 //LIC//
27 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
28 //LIC//
29 //LIC//====================================================================
30 // Driver code for a 2D YoungLaplace problem
31 
32 // Generic routines
33 #include "generic.h"
34 
35 // The YoungLaplace equations
36 #include "young_laplace.h"
37 
38 // The mesh
39 #include "meshes/simple_rectangular_quadmesh.h"
40 
41 
42 using namespace std;
43 using namespace oomph;
44 
45 //===== start_of_namespace========================================
46 /// Namespace for "global" problem parameters
47 //================================================================
49 {
50 
51  // Displacement control:
52  //----------------------
53 
54  /// Height control value
55  double Controlled_height = 0.0;
56 
57  /// Exact kappa
58  double get_exact_kappa()
59  {
60 
61  // Mean curvature of barrel-shaped meniscus
62  return 2.0*Controlled_height/
63  (Controlled_height*Controlled_height+1.0/4.0);
64 
65  } //end exact kappa
66 
67 
68  // Spine basis
69  //------------
70 
71  /// \short Spine basis: The position vector to the basis of the spine
72  /// as a function of the two coordinates x_1 and x_2, and its
73  /// derivatives w.r.t. to these coordinates.
74  /// dspine_B[i][j] = d spine_B[j] / dx_i
75  /// Spines start in the (x_1,x_2) plane at (x_1,x_2).
76  void spine_base_function(const Vector<double>& x,
77  Vector<double>& spine_B,
78  Vector< Vector<double> >& dspine_B)
79  {
80 
81  // Bspines and derivatives
82  spine_B[0] = x[0];
83  spine_B[1] = x[1];
84  spine_B[2] = 0.0 ;
85  dspine_B[0][0] = 1.0 ;
86  dspine_B[1][0] = 0.0 ;
87  dspine_B[0][1] = 0.0 ;
88  dspine_B[1][1] = 1.0 ;
89  dspine_B[0][2] = 0.0 ;
90  dspine_B[1][2] = 0.0 ;
91 
92  } // End of bspine functions
93 
94 
95 
96  // Spines rotate in the y-direction
97  //---------------------------------
98 
99  /// Min. spine angle against horizontal plane
100  double Alpha_min = MathematicalConstants::Pi/2.0*1.5;
101 
102  /// Max. spine angle against horizontal plane
103  double Alpha_max = MathematicalConstants::Pi/2.0*0.5;
104 
105  /// \short Spine: The spine vector field as a function of the two
106  /// coordinates x_1 and x_2, and its derivatives w.r.t. to these coordinates:
107  /// dspine[i][j] = d spine[j] / dx_i
108  void spine_function(const Vector<double>& x,
109  Vector<double>& spine,
110  Vector< Vector<double> >& dspine)
111  {
112 
113  /// Spines (and derivatives) are independent of x[0] and rotate
114  /// in the x[1]-direction
115  spine[0]=0.0;
116  dspine[0][0]=0.0;
117  dspine[1][0]=0.0;
118 
119  spine[1]=cos(Alpha_min+(Alpha_max-Alpha_min)*x[1]);
120  dspine[0][1]=0.0;
121  dspine[1][1]=-sin(Alpha_min+(Alpha_max-Alpha_min)*x[1])
122  *(Alpha_max-Alpha_min);
123 
124  spine[2]=sin(Alpha_min+(Alpha_max-Alpha_min)*x[1]);
125  dspine[0][2]=0.0;
126  dspine[1][2]=cos(Alpha_min+(Alpha_max-Alpha_min)*x[1])
127  *(Alpha_max-Alpha_min);
128 
129  } // End spine function
130 
131 
132 } // end of namespace
133 
134 
135 
136 
137 //====== start_of_problem_class=======================================
138 /// 2D YoungLaplace problem on rectangular domain, discretised with
139 /// 2D QYoungLaplace elements. The specific type of element is
140 /// specified via the template parameter.
141 //====================================================================
142 template<class ELEMENT>
143 class YoungLaplaceProblem : public Problem
144 {
145 
146 public:
147 
148  /// Constructor:
150 
151  /// Destructor (empty)
153 
154  /// Update the problem before solve
156  {
157  // This only has an effect if displacement control is disabled
158  double new_kappa=Kappa_pt->value(0)-0.5;
159  Kappa_pt->set_value(0,new_kappa);
160  }
161 
162  /// Update the problem after solve: Empty
164 
165  /// \short Doc the solution. DocInfo object stores flags/labels for where the
166  /// output gets written to and the trace file
167  void doc_solution(DocInfo& doc_info, ofstream& trace_file);
168 
169 private:
170 
171  /// Node at which the height (displacement along spine) is controlled/doced
173 
174  /// Pointer to Data object that stores the prescribed curvature
175  Data* Kappa_pt;
176 
177 }; // end of problem class
178 
179 
180 //=====start_of_constructor===============================================
181 /// Constructor for YoungLaplace problem
182 //========================================================================
183 template<class ELEMENT>
185 {
186 
187  // Setup mesh
188  //-----------
189 
190  // # of elements in x-direction
191  unsigned n_x=8;
192 
193  // # of elements in y-direction
194  unsigned n_y=8;
195 
196  // Domain length in x-direction
197  double l_x=1.0;
198 
199  // Domain length in y-direction
200  double l_y=1.0;
201 
202  // Build and assign mesh
203  Problem::mesh_pt()=new SimpleRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
204 
205 
206  // Check that we've got an even number of elements otherwise
207  // out counting doesn't work...
208  if ((n_x%2!=0)||(n_y%2!=0))
209  {
210  cout << "n_x n_y should be even" << endl;
211  abort();
212  }
213 
214  // This is the element that contains the central node:
215  ELEMENT* prescribed_height_element_pt= dynamic_cast<ELEMENT*>(
216  mesh_pt()->element_pt(n_y*n_x/2+n_x/2));
217 
218  // The central node is node 0 in that element
219  Control_node_pt= static_cast<Node*>(prescribed_height_element_pt->node_pt(0));
220 
221  std::cout << "Controlling height at (x,y) : (" << Control_node_pt->x(0)
222  << "," << Control_node_pt->x(1) << ")" << "\n" << endl;
223 
224 
225  // Create a height control element
226  HeightControlElement* height_control_element_pt=new HeightControlElement(
227  Control_node_pt,&GlobalParameters::Controlled_height);
228 
229  // Store pointer to kappa data
230  Kappa_pt=height_control_element_pt->kappa_pt();
231 
232 
233  // Comment out the previous two commands and uncomment the following two
234  // to prescribe the pressure drop (the curvature) directly
235  //Kappa_pt=new Data(1);
236  //Kappa_pt->pin(0);
237 
238 
239  // Boundary conditions
240  //--------------------
241 
242  // Set the boundary conditions for this problem: All nodes are
243  // free by default -- only need to pin the ones that have Dirichlet conditions
244  // here.
245  unsigned n_bound = mesh_pt()->nboundary();
246  for(unsigned b=0;b<n_bound;b++)
247  {
248 
249  // Pin meniscus displacement at all nodes boundaries 0 and 2
250  if ((b==0)||(b==2))
251  {
252  unsigned n_node = mesh_pt()->nboundary_node(b);
253  for (unsigned n=0;n<n_node;n++)
254  {
255  mesh_pt()->boundary_node_pt(b,n)->pin(0);
256  }
257  }
258 
259  } // end bc
260 
261  // Complete build of elements
262  //---------------------------
263 
264  // Complete the build of all elements so they are fully functional
265  unsigned nelement = mesh_pt()->nelement();
266  for(unsigned i=0;i<nelement;i++)
267  {
268  // Upcast from GeneralsedElement to YoungLaplace element
269  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(i));
270 
271  //Set the spine function pointers
272  el_pt->spine_base_fct_pt() = GlobalParameters::spine_base_function;
273  el_pt->spine_fct_pt() = GlobalParameters::spine_function;
274 
275  // Set the curvature data for the element
276  el_pt->set_kappa(Kappa_pt);
277  }
278 
279  // Add the height control element to mesh (comment this out
280  // if you're not using displacement control)
281  mesh_pt()->add_element_pt(height_control_element_pt);
282 
283  // Setup equation numbering scheme
284  cout <<"\nNumber of equations: " << assign_eqn_numbers() << endl;
285 
286 } // end of constructor
287 
288 
289 
290 
291 //===============start_of_doc=============================================
292 /// Doc the solution: doc_info contains labels/output directory etc.
293 //========================================================================
294 template<class ELEMENT>
296  ofstream& trace_file)
297 {
298 
299  // Output kappa vs height of the apex
300  //------------------------------------
301  trace_file << -1.0*Kappa_pt->value(0) << " ";
302  trace_file << GlobalParameters::get_exact_kappa() << " ";
303  trace_file << Control_node_pt->value(0) ;
304  trace_file << endl;
305 
306  // Number of plot points: npts x npts
307  unsigned npts=5;
308 
309  // Output full solution
310  //---------------------
311  ofstream some_file;
312  char filename[100];
313  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
314  doc_info.number());
315  some_file.open(filename);
316  mesh_pt()->output(some_file,npts);
317  some_file.close();
318 
319 } // end of doc
320 
321 
322 //===================start_of_main========================================
323 /// Driver code
324 //========================================================================
325 int main()
326 {
327 
328  // Create label for output
329  DocInfo doc_info;
330 
331  // Set output directory
332  doc_info.set_directory("RESLT");
333 
334  //Open a trace file
335  ofstream trace_file;
336  char filename[100];
337  sprintf(filename,"%s/trace.dat",doc_info.directory().c_str());
338  trace_file.open(filename);
339 
340  // Write kappa, exact kappa and height values
341  trace_file
342  << "VARIABLES=\"<GREEK>k</GREEK>\",\"<GREEK>k</GREEK>_{ex}\",\"h\""
343  << std::endl;
344  trace_file << "ZONE" << std::endl;
345 
346  // Create the problem
347  //-------------------
348 
349  // Create the problem with 2D nine-node elements from the
350  // QYoungLaplaceElement family.
352 
353  //Output the solution
354  problem.doc_solution(doc_info,trace_file);
355 
356  //Increment counter for solutions
357  doc_info.number()++;
358 
359 
360  // Parameter incrementation
361  //-------------------------
362  double increment=0.1;
363 
364  // Loop over steps
365  unsigned nstep=2; // 10;
366  for (unsigned istep=0;istep<nstep;istep++)
367  {
368 
369  // Increment prescribed height value
371 
372  // Solve the problem
373  problem.newton_solve();
374 
375  //Output the solution
376  problem.doc_solution(doc_info,trace_file);
377 
378  //Increment counter for solutions
379  doc_info.number()++;
380 
381  }
382 
383  // Close output file
384  trace_file.close();
385 
386 } // end of main
387 
388 
389 
390 
391 
392 
int main()
Driver code.
Definition: barrel.cc:325
void doc_solution(DocInfo &doc_info, ofstream &trace_file)
Doc the solution. DocInfo object stores flags/labels for where the output gets written to and the tra...
Definition: barrel.cc:295
~YoungLaplaceProblem()
Destructor (empty)
Definition: barrel.cc:152
double Controlled_height
Height control value.
Definition: barrel.cc:55
double Alpha_min
Min. spine angle against horizontal plane.
Definition: barrel.cc:100
YoungLaplaceProblem()
Constructor:
Definition: barrel.cc:184
void spine_function(const Vector< double > &x, Vector< double > &spine, Vector< Vector< double > > &dspine)
Spine: The spine vector field as a function of the two coordinates x_1 and x_2, and its derivatives w...
Definition: barrel.cc:108
Namespace for "global" problem parameters.
Definition: barrel.cc:48
Data * Kappa_pt
Pointer to Data object that stores the prescribed curvature.
void spine_base_function(const Vector< double > &x, Vector< double > &spine_B, Vector< Vector< double > > &dspine_B)
Spine basis: The position vector to the basis of the spine as a function of the two coordinates x_1 a...
Definition: barrel.cc:76
Data * Kappa_pt
Pointer to Data object that stores the prescribed curvature.
Definition: barrel.cc:175
double Alpha_max
Max. spine angle against horizontal plane.
Definition: barrel.cc:103
Node * Control_node_pt
Node at which the height (displacement along spine) is controlled/doced.
Definition: barrel.cc:172
void actions_after_newton_solve()
Update the problem after solve: Empty.
Definition: barrel.cc:163
void actions_before_newton_solve()
Update the problem before solve.
Definition: barrel.cc:155
double get_exact_kappa()
Exact kappa.
Definition: barrel.cc:58