spherical_cap_in_cylinder.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 for refineable 2D Young Laplace problem on a circle sector
31 
32 //Generic routines
33 #include "generic.h"
34 
35 // The YoungLaplace equations
36 #include "young_laplace.h"
37 
38 
39 // The mesh
40 #include "meshes/quarter_circle_sector_mesh.h"
41 
42 
43 using namespace std;
44 using namespace oomph;
45 
46 
47 // Namespace (shared with other driver codes)
49 
50 
51 //====== start_of_problem_class=======================================
52 /// 2D RefineableYoungLaplace problem on a circle sector, discretised with
53 /// 2D QRefineableYoungLaplace elements. The specific type of element is
54 /// specified via the template parameter.
55 //====================================================================
56 template<class ELEMENT>
57 class RefineableYoungLaplaceProblem : public Problem
58 {
59 
60 public:
61 
62  /// Constructor:
64 
65  /// Destructor (empty)
67 
68  /// \short Update the problem specs before solve: Empty
70 
71  /// Update the problem after solve: Empty
73 
74  /// Increment problem parameters
75  void increment_parameters();
76 
77  /// \short Doc the solution. DocInfo object stores flags/labels for where the
78  /// output gets written to and the trace file
79  void doc_solution(DocInfo& doc_info, ofstream& trace_file);
80 
81 private:
82 
83  /// Pointer to GeomObject that specifies the domain bondary
84  GeomObject* Boundary_pt;
85 
86  /// Pointer to the "bulk" mesh
87  RefineableQuarterCircleSectorMesh<ELEMENT>* Bulk_mesh_pt;
88 
89  /// Pointer to mesh containing the height control element
90  Mesh* Height_control_mesh_pt;
91 
92  /// Pointer to height control element
93  HeightControlElement* Height_control_element_pt;
94 
95  /// Node at which the height (displacement along spine) is controlled/doced
96  Node* Control_node_pt;
97 
98 }; // end of problem class
99 
100 
101 //=====start_of_constructor===============================================
102 /// Constructor for RefineableYoungLaplace problem
103 //========================================================================
104 template<class ELEMENT>
106 {
107 
108  // Setup dependent parameters in namespace
110 
111  // Setup bulk mesh
112  //----------------
113 
114  // Build geometric object that forms the curvilinear domain boundary:
115  // a unit circle
116 
117  // Create GeomObject
118  Boundary_pt=new Circle(0.0,0.0,1.0);
119 
120  // Start and end coordinates of curvilinear domain boundary on circle
121  double xi_lo=0.0;
122  double xi_hi=MathematicalConstants::Pi/2.0;
123 
124  // Now create the bulk mesh. Separating line between the two
125  // elements next to the curvilinear boundary is located half-way
126  // along the boundary.
127  double fract_mid=0.5;
128  Bulk_mesh_pt = new RefineableQuarterCircleSectorMesh<ELEMENT>(
129  Boundary_pt,xi_lo,fract_mid,xi_hi);
130 
131  // Create/set error estimator
132  Bulk_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
133 
134  // Set targets for spatial adaptivity
135  Bulk_mesh_pt->max_permitted_error()=1.0e-4;
136  Bulk_mesh_pt->min_permitted_error()=1.0e-6;
137 
138  // Add bulk mesh to the global mesh
139  add_sub_mesh(Bulk_mesh_pt);
140 
141 
142  // Prescribed height?
143  //-------------------
144 
145 
146  // Which element are we using for displacement control?
148 
149  // Choose the prescribed height element
150  ELEMENT* prescribed_height_element_pt= dynamic_cast<ELEMENT*>(
151  Bulk_mesh_pt->element_pt(GlobalParameters::Control_element));
152 
153  // ...and the associated control node (node 0 in that element)
154  // (we're storing this node even if there's no height-control, for
155  // output purposes...)
156  Control_node_pt= static_cast<Node*>(
157  prescribed_height_element_pt->node_pt(0));
158 
159  cout << "Controlling height at (x,y) : (" << Control_node_pt->x(0)
160  << "," << Control_node_pt->x(1) << ")" << endl;
161 
162  // If needed, create a height control element and store the
163  // pointer to the Kappa Data created by this object
164  Height_control_element_pt=0;
165  Height_control_mesh_pt=0;
167  {
168  Height_control_element_pt=new HeightControlElement(
169  Control_node_pt,&GlobalParameters::Controlled_height);
170 
171  GlobalParameters::Kappa_pt=Height_control_element_pt->kappa_pt();
172 
173  // Add to mesh
174  Height_control_mesh_pt = new Mesh;
175  Height_control_mesh_pt->add_element_pt(Height_control_element_pt);
176 
177  // Add height control mesh to the global mesh
178  add_sub_mesh(Height_control_mesh_pt);
179 
180  }
181  //...otherwise create a kappa data item from scratch and pin its
182  // single unknown value
183  else
184  {
185  GlobalParameters::Kappa_pt=new Data(1);
188  }
189 
190  // Build global mesh
191  //------------------
192  build_global_mesh();
193 
194 
195  // Boundary conditions
196  //--------------------
197 
198  // Set the boundary conditions for this problem: All nodes are
199  // free by default -- only need to pin the ones that have Dirichlet conditions
200  // here.
201  unsigned n_node = Bulk_mesh_pt->nboundary_node(1);
202  for (unsigned n=0;n<n_node;n++)
203  {
204  Bulk_mesh_pt->boundary_node_pt(1,n)->pin(0);
205  }
206 
207 
208  // Complete build of elements
209  //---------------------------
210 
211  // Complete the build of all elements so they are fully functional
212  unsigned n_bulk=Bulk_mesh_pt->nelement();
213  for(unsigned i=0;i<n_bulk;i++)
214  {
215  // Upcast from GeneralsedElement to the present element
216  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(i));
217 
219  {
220  //Set the spine function pointers
221  el_pt->spine_base_fct_pt() = GlobalParameters::spine_base_function;
222  el_pt->spine_fct_pt() = GlobalParameters::spine_function;
223  }
224 
225  // Set the curvature data for the element
226  el_pt->set_kappa(GlobalParameters::Kappa_pt);
227 
228  }
229 
230  // Setup equation numbering scheme
231  cout <<"\nNumber of equations: " << assign_eqn_numbers() << endl;
232  cout << "\n********************************************\n" << endl;
233 
234 } // end of constructor
235 
236 
237 
238 //===============start_of_update_parameters==============================
239 /// Update (increase/decrease) parameters
240 //=======================================================================
241 template<class ELEMENT>
243 {
244 
247 
248  cout << "Solving for Prescribed Height Value = " ;
249  cout << GlobalParameters::Controlled_height << "\n" << endl;
250 
251 }
252 
253 
254 
255 //===============start_of_doc=============================================
256 /// Doc the solution: doc_info contains labels/output directory etc.
257 //========================================================================
258 template<class ELEMENT>
260  ofstream& trace_file)
261 {
262 
263  // Output kappa vs height
264  //-----------------------
265  trace_file << -1.0*GlobalParameters::Kappa_pt->value(0) << " ";
266  trace_file << GlobalParameters::get_exact_kappa() << " ";
267  trace_file << Control_node_pt->value(0) ;
268  trace_file << endl;
269 
270 
271  // Number of plot points: npts x npts
272  unsigned npts=5;
273 
274  // Output full solution
275  //---------------------
276  ofstream some_file;
277  char filename[100];
278  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
279  doc_info.number());
280  some_file.open(filename);
281  Bulk_mesh_pt->output(some_file,npts);
282  some_file.close();
283 
284 }
285 
286 
287 
288 //===== start_of_main=====================================================
289 /// Driver code for 2D RefineableYoungLaplace problem. Input arguments: none
290 /// (for validation) or number of steps.
291 //========================================================================
292 int main(int argc, char* argv[])
293 {
294 
295  // Store command line arguments
296  CommandLineArgs::setup(argc,argv);
297 
298  // No command line args: Running with limited number of steps
299  if (CommandLineArgs::Argc==1)
300  {
301  std::cout
302  << "Running with limited number of steps for validation"
303  << std::endl;
304 
305  // Number of steps
307  }
308  else
309  {
310  // Number of steps
311  GlobalParameters::Nsteps=atoi(argv[1]);
312  }
313  // Create label for output
314  //------------------------
315  DocInfo doc_info;
316 
317  // Set outputs
318  //------------
319 
320  // Trace file
321  ofstream trace_file;
322 
323 // Set output directory
324  doc_info.set_directory("RESLT_adapt_pinned_spherical_cap_in_cylinder");
325 
326 //Open a trace file
327  char filename[100];
328  sprintf(filename,"%s/trace.dat",doc_info.directory().c_str());
329  trace_file.open(filename);
330 
331  trace_file
332  << "VARIABLES=\"<GREEK>k</GREEK>\",\"<GREEK>k</GREEK>_{exact}\",\"h\""
333  << std::endl;
334  trace_file << "ZONE" << std::endl;
335 
336 
337  // Set case
339 
340  // Run with spines
342 
343 
344  //Set up the problem
345  //------------------
346 
347  // Create the problem with 2D nine-node elements from the
348  // RefineableQYoungLaplaceElement family.
350 
351  //Output the solution
352  problem.doc_solution(doc_info,trace_file);
353 
354  //Increment counter for solutions
355  doc_info.number()++;
356 
357  // Parameter incrementation
358  //-------------------------
359 
360  // Loop over steps
361  for (unsigned istep=0;istep<GlobalParameters::Nsteps;istep++)
362  {
363  // Solve the problem
364  unsigned max_adapt=1;
365  problem.newton_solve(max_adapt);
366 
367  //Output the solution
368  problem.doc_solution(doc_info,trace_file);
369 
370  //Increment counter for solutions
371  doc_info.number()++;
372 
373  // Increase the parameters
374  problem.increment_parameters();
375  }
376 
377  // Close output file
378  trace_file.close();
379 
380 
381 
382 
383 
384 
385 
386 } //end of main
387 
388 
double Controlled_height
Height control value.
Definition: barrel.cc:55
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...
unsigned Nsteps
Number of steps.
~RefineableYoungLaplaceProblem()
Destructor (empty)
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
void increment_parameters()
Increase the problem parameters before each solve.
void actions_after_solve()
Update the problem after solve: Empty.
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
bool Use_spines
Use spines (true) or not (false)
void setup_dependent_parameters_and_sanity_check()
Setup dependent parameters and perform sanity check.
int main(int argc, char *argv[])
void actions_before_solve()
Update the problem specs before solve: Empty.
int Case
What case are we considering: Choose one from the enumeration Cases.
RefineableQuarterCircleSectorMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
double get_exact_kappa()
Exact kappa.
Definition: barrel.cc:58
bool Use_height_control
Use height control (true) or not (false)?
double Kappa_initial
Initial value for kappa.
GeomObject * Boundary_pt
Pointer to GeomObject that specifies the domain bondary.
double Controlled_height_increment
Increment for height control.