refineable_young_laplace.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// Copyright (C) 2006-2023 Matthias Heil and Andrew Hazel
7 //LIC//
8 //LIC// This library is free software; you can redistribute it and/or
9 //LIC// modify it under the terms of the GNU Lesser General Public
10 //LIC// License as published by the Free Software Foundation; either
11 //LIC// version 2.1 of the License, or (at your option) any later version.
12 //LIC//
13 //LIC// This library is distributed in the hope that it will be useful,
14 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 //LIC// Lesser General Public License for more details.
17 //LIC//
18 //LIC// You should have received a copy of the GNU Lesser General Public
19 //LIC// License along with this library; if not, write to the Free Software
20 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 //LIC// 02110-1301 USA.
22 //LIC//
23 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 //LIC//
25 //LIC//====================================================================
26 //Driver for refineable Young Laplace problem
27 
28 //Generic routines
29 #include "generic.h"
30 
31 // The YoungLaplace equations
32 #include "young_laplace.h"
33 
34 // The mesh
35 #include "meshes/rectangular_quadmesh.h"
36 
37 // Namespaces
38 using namespace std;
39 using namespace oomph;
40 
41 // Namespace (shared with non-refineable version)
43 
44 //====== start_of_problem_class=======================================
45 /// 2D RefineableYoungLaplace problem on rectangular domain, discretised with
46 /// 2D QRefineableYoungLaplace elements. The specific type of element is
47 /// specified via the template parameter.
48 //====================================================================
49 template<class ELEMENT>
50 class RefineableYoungLaplaceProblem : public Problem
51 {
52 
53 public:
54 
55  /// Constructor:
57 
58  /// Destructor (empty)
60 
61  /// Update the problem specs before solve: Empty
63 
64  /// Update the problem after solve: Empty
66 
67  /// Actions before adapt: Wipe the mesh of contact angle elements
69  {
70  // Kill the contact angle elements and wipe contact angle mesh
71  if (Contact_angle_mesh_pt!=0) delete_contact_angle_elements();
72 
73  // Rebuild the Problem's global mesh from its various sub-meshes
74  rebuild_global_mesh();
75  }
76 
77 
78  /// Actions after adapt: Rebuild the mesh of contact angle elements
80  {
81  // Create contact angle elements on boundaries 1 and 3 of bulk mesh
84  {
85  create_contact_angle_elements(1);
86  create_contact_angle_elements(3);
87 
88  // Set function pointers for contact-angle elements
89  unsigned nel=Contact_angle_mesh_pt->nelement();
90  for (unsigned e=0;e<nel;e++)
91  {
92  // Upcast from GeneralisedElement to YoungLaplace contact angle
93  // element
94  YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
95  dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*>(
96  Contact_angle_mesh_pt->element_pt(e));
97 
98  // Set the pointer to the prescribed contact angle
99  el_pt->prescribed_cos_gamma_pt() = &GlobalParameters::Cos_gamma;
100  }
101  }
102 
103  // Rebuild the Problem's global mesh from its various sub-meshes
104  rebuild_global_mesh();
105 
106  }
107 
108  /// Increase the problem parameters before each solve
109  void increment_parameters();
110 
111  /// Doc the solution. DocInfo object stores flags/labels for where the
112  /// output gets written to and the trace file
113  void doc_solution(DocInfo& doc_info, ofstream& trace_file);
114 
115 private:
116 
117  /// Create YoungLaplace contact angle elements on the
118  /// b-th boundary of the bulk mesh and add them to contact angle mesh
119  void create_contact_angle_elements(const unsigned& b);
120 
121  /// Delete contact angle elements
123 
124  /// Pointer to the "bulk" mesh
125  RefineableRectangularQuadMesh<ELEMENT>* Bulk_mesh_pt;
126 
127  /// Pointer to the contact angle mesh
128  Mesh* Contact_angle_mesh_pt;
129 
130  /// Pointer to mesh containing the height control element
131  Mesh* Height_control_mesh_pt;
132 
133  /// Pointer to height control element
134  HeightControlElement* Height_control_element_pt;
135 
136  /// Node at which the height (displacement along spine) is controlled/doced
137  Node* Control_node_pt;
138 
139 }; // end of problem class
140 
141 
142 //=====start_of_constructor===============================================
143 /// Constructor for RefineableYoungLaplace problem
144 //========================================================================
145 template<class ELEMENT>
147 {
148 
149  // Setup dependent parameters in namespace
151 
152 
153  // Setup bulk mesh
154  //----------------
155 
156  // # of elements in x-direction
157  unsigned n_x=GlobalParameters::N_x;
158 
159  // # of elements in y-direction
160  unsigned n_y=GlobalParameters::N_y;
161 
162  // Domain length in x-direction
163  double l_x=GlobalParameters::L_x;
164 
165  // Domain length in y-direction
166  double l_y=GlobalParameters::L_y;
167 
168  // Print Size of the mesh
169  cout << "Lx = " << l_x << " and Ly = " << l_y << endl;
170 
171  // Build and assign mesh
172  Bulk_mesh_pt=new RefineableRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
173 
174  // Create/set error estimator
175  Bulk_mesh_pt->spatial_error_estimator_pt()=new Z2ErrorEstimator;
176 
177  // Set targets for spatial adaptivity
178  Bulk_mesh_pt->max_permitted_error()=1.0e-4;
179  Bulk_mesh_pt->min_permitted_error()=1.0e-6;
180 
181  // Add bulk mesh to the global mesh
182  add_sub_mesh(Bulk_mesh_pt);
183 
184 
185  // Prescribed height?
186  //-------------------
187 
188  // Choose the prescribed height element
189  ELEMENT* prescribed_height_element_pt= dynamic_cast<ELEMENT*>(
190  Bulk_mesh_pt->element_pt(GlobalParameters::Control_element));
191 
192  // ...and the associated control node (node 0 in that element)
193  // (we're storing this node even if there's no height-control, for
194  // output purposes...)
195  Control_node_pt= static_cast<Node*>(
196  prescribed_height_element_pt->node_pt(0));
197 
198  cout << "Controlling height at (x,y) : (" << Control_node_pt->x(0)
199  << "," << Control_node_pt->x(1) << ")" << endl;
200 
201  // If needed, create a height control element and store the
202  // pointer to the Kappa Data created by this object
203  Height_control_element_pt=0;
204  Height_control_mesh_pt=0;
206  {
207  Height_control_element_pt=new HeightControlElement(
208  Control_node_pt,&GlobalParameters::Controlled_height);
209 
210  GlobalParameters::Kappa_pt=Height_control_element_pt->kappa_pt();
211  Height_control_element_pt->kappa_pt()->
212  set_value(0,GlobalParameters::Kappa_initial);
213 
214  // Add to mesh
215  Height_control_mesh_pt = new Mesh;
216  Height_control_mesh_pt->add_element_pt(Height_control_element_pt);
217 
218  // Add height control mesh to the global mesh
219  add_sub_mesh(Height_control_mesh_pt);
220  }
221  //...otherwise create a kappa data item from scratch and pin its
222  // single unknown value
223  else
224  {
226  GlobalParameters::Kappa_pt=new Data(1);
229  }
230 
231 
232  // Contact angle elements
233  //-----------------------
234 
235  // Create prescribed-contact-angle elements from all elements that are
236  // adjacent to boundary 1 and 3 and add them to their own mesh
237  Contact_angle_mesh_pt=0;
240  {
241  // set up new mesh
242  Contact_angle_mesh_pt=new Mesh;
243 
244  // creation of contact angle elements
245  create_contact_angle_elements(1);
246  create_contact_angle_elements(3);
247 
248  // Add contact angle mesh to the global mesh
249  add_sub_mesh(Contact_angle_mesh_pt);
250  }
251 
252 
253  // Build global mesh
254  //------------------
255  build_global_mesh();
256 
257 
258  // Boundary conditions
259  //--------------------
260 
261  // Set the boundary conditions for this problem: All nodes are
262  // free by default -- only need to pin the ones that have Dirichlet conditions
263  // here.
264  unsigned n_bound = Bulk_mesh_pt->nboundary();
265  for(unsigned b=0;b<n_bound;b++)
266  {
267  // Pin all boundaries for three cases and only boundaries
268  // 0 and 2 in all others:
270  (b==0)||
271  (b==2))
272  {
273  unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
274  for (unsigned n=0;n<n_node;n++)
275  {
276  Bulk_mesh_pt->boundary_node_pt(b,n)->pin(0);
277  }
278  }
279  }
280 
281  // Complete build of elements
282  //---------------------------
283 
284  // Complete the build of all elements so they are fully functional
285  unsigned n_bulk=Bulk_mesh_pt->nelement();
286  for(unsigned i=0;i<n_bulk;i++)
287  {
288  // Upcast from GeneralsedElement to the present element
289  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(i));
290 
292  {
293  //Set the spine function pointers
294  el_pt->spine_base_fct_pt() = GlobalParameters::spine_base_function;
295  el_pt->spine_fct_pt() = GlobalParameters::spine_function;
296  }
297 
298  // Set the curvature data for the element
299  el_pt->set_kappa(GlobalParameters::Kappa_pt);
300 
301  }
302 
303  // Set function pointers for contact-angle elements
306  {
307  // Set function pointers for contact-angle elements
308  unsigned nel=Contact_angle_mesh_pt->nelement();
309  for (unsigned e=0;e<nel;e++)
310  {
311  // Upcast from GeneralisedElement to YoungLaplace contact angle
312  // element
313  YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
314  dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*>(
315  Contact_angle_mesh_pt->element_pt(e));
316 
317  // Set the pointer to the prescribed contact angle
318  el_pt->prescribed_cos_gamma_pt() = &GlobalParameters::Cos_gamma;
319  }
320  }
321 
322  // Setup equation numbering scheme
323  cout <<"\nNumber of equations: " << assign_eqn_numbers() << endl;
324  cout << "\n********************************************\n" << endl;
325 
326 } // end of constructor
327 
328 
329 //============start_of_create_contact_angle_elements=====================
330 /// Create YoungLaplace contact angle elements on the b-th boundary of the
331 /// bulk mesh and add them to the contact angle mesh
332 //=======================================================================
333 template<class ELEMENT>
335  const unsigned &b)
336 {
337  // How many bulk elements are adjacent to boundary b?
338  unsigned n_element = Bulk_mesh_pt->nboundary_element(b);
339 
340  // Loop over the bulk elements adjacent to boundary b?
341  for(unsigned e=0;e<n_element;e++)
342  {
343  // Get pointer to the bulk element that is adjacent to boundary b
344  ELEMENT* bulk_elem_pt = dynamic_cast<ELEMENT*>(
345  Bulk_mesh_pt->boundary_element_pt(b,e));
346 
347  // What is the index of the face of the bulk element at the boundary
348  int face_index = Bulk_mesh_pt->face_index_at_boundary(b,e);
349 
350  // Build the corresponding contact angle element
351  YoungLaplaceContactAngleElement<ELEMENT>* contact_angle_element_pt = new
352  YoungLaplaceContactAngleElement<ELEMENT>(bulk_elem_pt,face_index);
353 
354  //Add the contact angle element to the contact angle mesh
355  Contact_angle_mesh_pt->add_element_pt(contact_angle_element_pt);
356 
357  } //end of loop over bulk elements adjacent to boundary b
358 
359 } // end of create_contact_angle_elements
360 
361 
362 //============start_of_delete_contact_angle_elements=====================
363 /// Delete YoungLaplace contact angle elements
364 //=======================================================================
365 template<class ELEMENT>
367 {
368 
369  // How many contact angle elements are there?
370  unsigned n_element = Contact_angle_mesh_pt->nelement();
371 
372  // Loop over the surface elements
373  for(unsigned e=0;e<n_element;e++)
374  {
375  // Kill surface element
376  delete Contact_angle_mesh_pt->element_pt(e);
377  }
378 
379  // Wipe the mesh
380  Contact_angle_mesh_pt->flush_element_and_node_storage();
381 
382 
383 } // end of delete_contact_angle_elements
384 
385 
386 
387 //===============start_of_update_parameters============================
388 /// Update (increase/decrease) parameters
389 //=====================================================================
390 template<class ELEMENT>
392 {
393 
394  // Increment kappa or height value
396  {
397  double kappa=GlobalParameters::Kappa_pt->value(0);
399  GlobalParameters::Kappa_pt->set_value(0,kappa);
400 
401  cout << "Solving for Prescribed KAPPA Value = " ;
402  cout << GlobalParameters::Kappa_pt->value(0) << "\n" << endl;
403  }
404  else
405  {
408 
409  cout << "Solving for Prescribed HEIGHT Value = " ;
410  cout << GlobalParameters::Controlled_height << "\n" << endl;
411  }
412 
413 }
414 
415 
416 //===============start_of_doc=============================================
417 /// Doc the solution: doc_info contains labels/output directory etc.
418 //========================================================================
419 template<class ELEMENT>
421  ofstream& trace_file)
422 {
423 
424  // Output kappa vs height
425  //-----------------------
426  trace_file << -1.0*GlobalParameters::Kappa_pt->value(0) << " ";
427  trace_file << GlobalParameters::get_exact_kappa() << " ";
428  trace_file << Control_node_pt->value(0) ;
429  trace_file << endl;
430 
431  // Number of plot points: npts x npts
432  unsigned npts=5;
433 
434  // Output full solution
435  //---------------------
436  ofstream some_file;
437  char filename[100];
438  //YoungLaplaceEquations::Output_meniscus_and_spines=false;
439  sprintf(filename,"%s/soln%i.dat",doc_info.directory().c_str(),
440  doc_info.number());
441  some_file.open(filename);
442  Bulk_mesh_pt->output(some_file,npts);
443  some_file.close();
444 
445  // Output contact angle
446  //---------------------
447 
448  //Doc contact angle stuff
451  {
452 
453  ofstream tangent_file;
454  sprintf(filename,"%s/tangent_to_contact_line%i.dat",
455  doc_info.directory().c_str(),
456  doc_info.number());
457  tangent_file.open(filename);
458 
459  ofstream normal_file;
460  sprintf(filename,"%s/normal_to_contact_line%i.dat",
461  doc_info.directory().c_str(),
462  doc_info.number());
463  normal_file.open(filename);
464 
465 
466  ofstream contact_angle_file;
467  sprintf(filename,"%s/contact_angle%i.dat",
468  doc_info.directory().c_str(),
469  doc_info.number());
470  contact_angle_file.open(filename);
471 
472  // Tangent and normal vectors to contact line
473  Vector<double> tangent(3);
474  Vector<double> normal(3);
475  Vector<double> r_contact(3);
476 
477  // How many contact angle elements are there?
478  unsigned n_element = Contact_angle_mesh_pt->nelement();
479 
480  // Loop over the surface elements
481  for(unsigned e=0;e<n_element;e++)
482  {
483 
484  tangent_file << "ZONE" << std::endl;
485  normal_file << "ZONE" << std::endl;
486  contact_angle_file << "ZONE" << std::endl;
487 
488  // Upcast from GeneralisedElement to YoungLaplace contact angle element
489  YoungLaplaceContactAngleElement<ELEMENT>* el_pt =
490  dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*>(
491  Contact_angle_mesh_pt->element_pt(e));
492 
493  // Loop over a few points in the contact angle element
494  Vector<double> s(1);
495  for (unsigned i=0;i<npts;i++)
496  {
497  s[0]=-1.0+2.0*double(i)/double(npts-1);
498 
499  dynamic_cast<ELEMENT*>(el_pt->bulk_element_pt())->
500  position(el_pt->local_coordinate_in_bulk(s),r_contact);
501 
502  el_pt->contact_line_vectors(s,tangent,normal);
503  tangent_file << r_contact[0] << " "
504  << r_contact[1] << " "
505  << r_contact[2] << " "
506  << tangent[0] << " "
507  << tangent[1] << " "
508  << tangent[2] << " " << std::endl;
509 
510  normal_file << r_contact[0] << " "
511  << r_contact[1] << " "
512  << r_contact[2] << " "
513  << normal[0] << " "
514  << normal[1] << " "
515  << normal[2] << " " << std::endl;
516 
517  contact_angle_file << r_contact[1] << " "
518  << el_pt->actual_cos_contact_angle(s)
519  << std::endl;
520  }
521 
522 
523  } // end of loop over both boundaries
524 
525  tangent_file.close();
526  normal_file.close();
527  contact_angle_file.close();
528 
529  }
530 
531  cout << "\n********************************************" << endl << endl;
532 
533 } // end of doc
534 
535 
536 
537 //========================================================================
538 /// Run code for current setting of parameter values -- specify name
539 /// of output directory
540 //========================================================================
541 void run_it(const string& output_directory)
542 {
543 
544  // Create label for output
545  //------------------------
546  DocInfo doc_info;
547 
548  // Set outputs
549  //------------
550 
551  // Trace file
552  ofstream trace_file;
553 
554  // Set output directory
555  doc_info.set_directory(output_directory);
556 
557  // Open a trace file
558  char filename[100];
559  sprintf(filename,"%s/trace.dat",doc_info.directory().c_str());
560  trace_file.open(filename);
561 
562  // Write kappa, exact kappa if exists and height values
563  trace_file <<
564  "VARIABLES=\"<GREEK>k</GREEK>\",\"<GREEK>k</GREEK>_{ex}\",\"h\""
565  << std::endl;
566  trace_file << "ZONE" << std::endl;
567 
568  //Set up the problem
569  //------------------
570 
571  // Create the problem with 2D nine-node elements from the
572  // RefineableQYoungLaplaceElement family.
574 
575  problem.refine_uniformly();
576 
577  //Output the solution
578  problem.doc_solution(doc_info,trace_file);
579 
580  //Increment counter for solutions
581  doc_info.number()++;
582 
583  // Parameter incrementation
584  //-------------------------
585 
586  // Loop over steps
587  for (unsigned istep=0;istep<GlobalParameters::Nsteps;istep++)
588  {
589 
590  // Bump up parameters
591  problem.increment_parameters();
592 
593  // Solve the problem
594  unsigned max_adapt=1;
595  problem.newton_solve(max_adapt);
596 
597  //Output the solution
598  problem.doc_solution(doc_info,trace_file);
599 
600  //Increment counter for solutions
601  doc_info.number()++;
602  }
603 
604  // Close output file
605  trace_file.close();
606 
607 } //end of run_it()
608 
609 
610 
611 //===== start_of_main=====================================================
612 /// Driver code for 2D RefineableYoungLaplace problem. Input arguments: none
613 /// (for validation) or case (0,1,2,3 for all pinned, barrel with spines,
614 /// barrel without spines, and T junction), and number of steps.
615 //========================================================================
616 int main(int argc, char* argv[])
617 {
618 
619  // Store command line arguments
620  CommandLineArgs::setup(argc,argv);
621 
622  // Cases to run (By default (validation) run all
623  unsigned case_lo=0;
624  unsigned case_hi=3;
625 
626  // No command line args: Running every case with
627  // limited number of steps
628  if (CommandLineArgs::Argc==1)
629  {
630  std::cout
631  << "Running every case with limited number of steps for validation"
632  << std::endl;
633 
634  // Number of steps
636  }
637  else
638  {
639  // Which case to run?
640  case_lo=atoi(argv[1]);
641  case_hi=atoi(argv[1]);
642 
643  // Number of steps
644  GlobalParameters::Nsteps=atoi(argv[2]);
645  }
646 
647  // Loop over chosen case(s)
648  //-------------------------
649  for (unsigned my_case=case_lo;my_case<=case_hi;my_case++)
650  {
651 
652  // Choose
653  switch (my_case)
654  {
655 
656  case 0:
657 
658  cout << endl << endl
659  << "//////////////////////////////////////////////////////////\n"
660  << "All pinned solution \n"
661  << "//////////////////////////////////////////////////////////\n\n";
662 
664 
665  // Run with spines
667  run_it("RESLT_adapt_all_pinned");
668 
669  break;
670 
671  case 1:
672 
673  cout << endl << endl
674  << "//////////////////////////////////////////////////////////\n"
675  << "Barrel-shaped solution with spine \n"
676  << "/////////////////////////////////////////////////////////\n\n";
677 
681  run_it("RESLT_adapt_barrel_shape");
682 
683  break;
684 
685  case 2:
686 
687  cout << endl << endl
688  << "//////////////////////////////////////////////////////////\n"
689  << "Barrel-shaped solution without spines \n"
690  << "/////////////////////////////////////////////////////////\n\n";
691 
695  run_it("RESLT_adapt_barrel_shape_without_spines");
696 
697  break;
698 
699  case 3:
700 
701  cout << endl << endl
702  << "//////////////////////////////////////////////////////////\n"
703  << "T-junction solution \n"
704  << "//////////////////////////////////////////////////////////\n\n";
705 
708  GlobalParameters::Gamma=MathematicalConstants::Pi/6.0;
711 
712  // Run with spines
714  run_it("RESLT_adapt_T_junction");
715 
716  break;
717 
718 
719  default:
720 
721  std::cout << "Wrong case! Options are:\n"
722  << "0: adaptive All pinned\n"
723  << "1: adaptive Barrel with spines\n"
724  << "2: adaptive Barrel without spines\n"
725  << "3: adaptive T_junction\n"
726  << std::endl;
727  assert(false);
728 
729  }
730 
731  }
732 
733 
734 } //end of main
735 
736 
2D RefineableYoungLaplace problem on rectangular domain, discretised with 2D QRefineableYoungLaplace ...
void create_contact_angle_elements(const unsigned &b)
Create YoungLaplace contact angle elements on the b-th boundary of the bulk mesh and add them to cont...
void actions_after_newton_solve()
Update the problem after solve: Empty.
~RefineableYoungLaplaceProblem()
Destructor (empty)
void actions_before_newton_solve()
Update the problem specs before solve: Empty.
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...
RefineableYoungLaplaceProblem()
Constructor:
void actions_after_adapt()
Actions after adapt: Rebuild the mesh of contact angle elements.
void delete_contact_angle_elements()
Delete contact angle elements.
void actions_before_adapt()
Actions before adapt: Wipe the mesh of contact angle elements.
HeightControlElement * Height_control_element_pt
Pointer to height control element.
void increment_parameters()
Increase the problem parameters before each solve.
double L_x
Length and width of the domain.
double Controlled_height
Height control value.
Definition: barrel.cc:51
unsigned Control_element
Number of element in bulk mesh at which height control is applied. Initialise to 0 – will be overwrit...
double get_exact_kappa()
Exact kappa.
Definition: barrel.cc:54
bool Use_height_control
Use height control (true) or not (false)?
double Controlled_height_increment
Increment for height control.
double Kappa_increment
Increment for prescribed curvature.
bool Use_spines
Use spines (true) or not (false)
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:104
unsigned Nsteps
Number of steps.
unsigned N_x
Number of elements in the mesh.
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:72
double L_y
Width of domain.
double Gamma
Contact angle and its cos (dependent parameter – is reassigned)
double Kappa_initial
Initial value for kappa.
double Cos_gamma
Cos of contact angle.
int Case
What case are we considering: Choose one from the enumeration Cases.
void setup_dependent_parameters_and_sanity_check()
Setup dependent parameters and perform sanity check.
int main(int argc, char *argv[])
Driver code for 2D RefineableYoungLaplace problem. Input arguments: none (for validation) or case (0,...
void run_it(const string &output_directory)
Run code for current setting of parameter values – specify name of output directory.