36 #include "young_laplace.h" 39 #include "meshes/rectangular_quadmesh.h" 43 using namespace oomph;
53 template<
class ELEMENT>
75 if (Contact_angle_mesh_pt!=0) delete_contact_angle_elements();
78 rebuild_global_mesh();
89 create_contact_angle_elements(1);
90 create_contact_angle_elements(3);
93 unsigned nel=Contact_angle_mesh_pt->nelement();
94 for (
unsigned e=0;e<nel;e++)
98 YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
99 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
100 Contact_angle_mesh_pt->element_pt(e));
108 rebuild_global_mesh();
113 void increment_parameters();
117 void doc_solution(DocInfo& doc_info, ofstream& trace_file);
123 void create_contact_angle_elements(
const unsigned& b);
126 void delete_contact_angle_elements();
129 RefineableRectangularQuadMesh<ELEMENT>* Bulk_mesh_pt;
132 Mesh* Contact_angle_mesh_pt;
135 Mesh* Height_control_mesh_pt;
141 Node* Control_node_pt;
149 template<
class ELEMENT>
173 cout <<
"Lx = " << l_x <<
" and Ly = " << l_y << endl;
176 Bulk_mesh_pt=
new RefineableRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
179 Bulk_mesh_pt->spatial_error_estimator_pt()=
new Z2ErrorEstimator;
182 Bulk_mesh_pt->max_permitted_error()=1.0e-4;
183 Bulk_mesh_pt->min_permitted_error()=1.0e-6;
186 add_sub_mesh(Bulk_mesh_pt);
193 ELEMENT* prescribed_height_element_pt=
dynamic_cast<ELEMENT*
>(
199 Control_node_pt=
static_cast<Node*
>(
200 prescribed_height_element_pt->node_pt(0));
202 cout <<
"Controlling height at (x,y) : (" << Control_node_pt->x(0)
203 <<
"," << Control_node_pt->x(1) <<
")" << endl;
207 Height_control_element_pt=0;
208 Height_control_mesh_pt=0;
211 Height_control_element_pt=
new HeightControlElement(
215 Height_control_element_pt->kappa_pt()->
219 Height_control_mesh_pt =
new Mesh;
220 Height_control_mesh_pt->add_element_pt(Height_control_element_pt);
223 add_sub_mesh(Height_control_mesh_pt);
241 Contact_angle_mesh_pt=0;
246 Contact_angle_mesh_pt=
new Mesh;
249 create_contact_angle_elements(1);
250 create_contact_angle_elements(3);
253 add_sub_mesh(Contact_angle_mesh_pt);
268 unsigned n_bound = Bulk_mesh_pt->nboundary();
269 for(
unsigned b=0;b<n_bound;b++)
277 unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
278 for (
unsigned n=0;n<n_node;n++)
280 Bulk_mesh_pt->boundary_node_pt(b,n)->pin(0);
289 unsigned n_bulk=Bulk_mesh_pt->nelement();
290 for(
unsigned i=0;i<n_bulk;i++)
293 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(i));
312 unsigned nel=Contact_angle_mesh_pt->nelement();
313 for (
unsigned e=0;e<nel;e++)
317 YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
318 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
319 Contact_angle_mesh_pt->element_pt(e));
327 cout <<
"\nNumber of equations: " << assign_eqn_numbers() << endl;
328 cout <<
"\n********************************************\n" << endl;
337 template<
class ELEMENT>
342 unsigned n_element = Bulk_mesh_pt->nboundary_element(b);
345 for(
unsigned e=0;e<n_element;e++)
348 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
349 Bulk_mesh_pt->boundary_element_pt(b,e));
352 int face_index = Bulk_mesh_pt->face_index_at_boundary(b,e);
355 YoungLaplaceContactAngleElement<ELEMENT>* contact_angle_element_pt =
new 356 YoungLaplaceContactAngleElement<ELEMENT>(bulk_elem_pt,face_index);
359 Contact_angle_mesh_pt->add_element_pt(contact_angle_element_pt);
369 template<
class ELEMENT>
374 unsigned n_element = Contact_angle_mesh_pt->nelement();
377 for(
unsigned e=0;e<n_element;e++)
380 delete Contact_angle_mesh_pt->element_pt(e);
384 Contact_angle_mesh_pt->flush_element_and_node_storage();
394 template<
class ELEMENT>
405 cout <<
"Solving for Prescribed KAPPA Value = " ;
413 cout <<
"Solving for Prescribed HEIGHT Value = " ;
423 template<
class ELEMENT>
425 ofstream& trace_file)
432 trace_file << Control_node_pt->value(0) ;
443 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
445 some_file.open(filename);
446 Bulk_mesh_pt->output(some_file,npts);
457 ofstream tangent_file;
458 sprintf(filename,
"%s/tangent_to_contact_line%i.dat",
459 doc_info.directory().c_str(),
461 tangent_file.open(filename);
463 ofstream normal_file;
464 sprintf(filename,
"%s/normal_to_contact_line%i.dat",
465 doc_info.directory().c_str(),
467 normal_file.open(filename);
470 ofstream contact_angle_file;
471 sprintf(filename,
"%s/contact_angle%i.dat",
472 doc_info.directory().c_str(),
474 contact_angle_file.open(filename);
477 Vector<double> tangent(3);
478 Vector<double> normal(3);
479 Vector<double> r_contact(3);
482 unsigned n_element = Contact_angle_mesh_pt->nelement();
485 for(
unsigned e=0;e<n_element;e++)
488 tangent_file <<
"ZONE" << std::endl;
489 normal_file <<
"ZONE" << std::endl;
490 contact_angle_file <<
"ZONE" << std::endl;
493 YoungLaplaceContactAngleElement<ELEMENT>* el_pt =
494 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
495 Contact_angle_mesh_pt->element_pt(e));
499 for (
unsigned i=0;i<npts;i++)
501 s[0]=-1.0+2.0*double(i)/double(npts-1);
503 dynamic_cast<ELEMENT*
>(el_pt->bulk_element_pt())->
504 position(el_pt->local_coordinate_in_bulk(s),r_contact);
506 el_pt->contact_line_vectors(s,tangent,normal);
507 tangent_file << r_contact[0] <<
" " 508 << r_contact[1] <<
" " 509 << r_contact[2] <<
" " 512 << tangent[2] <<
" " << std::endl;
514 normal_file << r_contact[0] <<
" " 515 << r_contact[1] <<
" " 516 << r_contact[2] <<
" " 519 << normal[2] <<
" " << std::endl;
521 contact_angle_file << r_contact[1] <<
" " 522 << el_pt->actual_cos_contact_angle(s)
529 tangent_file.close();
531 contact_angle_file.close();
535 cout <<
"\n********************************************" << endl << endl;
545 void run_it(
const string& output_directory)
559 doc_info.set_directory(output_directory);
563 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
564 trace_file.open(filename);
568 "VARIABLES=\"<GREEK>k</GREEK>\",\"<GREEK>k</GREEK>_{ex}\",\"h\"" 570 trace_file <<
"ZONE" << std::endl;
579 problem.refine_uniformly();
598 unsigned max_adapt=1;
599 problem.newton_solve(max_adapt);
620 int main(
int argc,
char* argv[])
624 CommandLineArgs::setup(argc,argv);
632 if (CommandLineArgs::Argc==1)
635 <<
"Running every case with limited number of steps for validation" 644 case_lo=atoi(argv[1]);
645 case_hi=atoi(argv[1]);
653 for (
unsigned my_case=case_lo;my_case<=case_hi;my_case++)
663 <<
"//////////////////////////////////////////////////////////\n" 664 <<
"All pinned solution \n" 665 <<
"//////////////////////////////////////////////////////////\n\n";
671 run_it(
"RESLT_adapt_all_pinned");
678 <<
"//////////////////////////////////////////////////////////\n" 679 <<
"Barrel-shaped solution with spine \n" 680 <<
"/////////////////////////////////////////////////////////\n\n";
685 run_it(
"RESLT_adapt_barrel_shape");
692 <<
"//////////////////////////////////////////////////////////\n" 693 <<
"Barrel-shaped solution without spines \n" 694 <<
"/////////////////////////////////////////////////////////\n\n";
699 run_it(
"RESLT_adapt_barrel_shape_without_spines");
706 <<
"//////////////////////////////////////////////////////////\n" 707 <<
"T-junction solution \n" 708 <<
"//////////////////////////////////////////////////////////\n\n";
718 run_it(
"RESLT_adapt_T_junction");
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"
double L_x
Length and width of the domain.
RefineableYoungLaplaceProblem()
Constructor:
double Controlled_height
Height control value.
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...
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...
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.
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.