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