34#include "young_laplace.h"
37#include "meshes/rectangular_quadmesh.h"
51template<
class ELEMENT>
76 rebuild_global_mesh();
92 for (
unsigned e=0;e<nel;e++)
96 YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
97 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
106 rebuild_global_mesh();
147template<
class ELEMENT>
171 cout <<
"Lx = " << l_x <<
" and Ly = " << l_y << endl;
174 Bulk_mesh_pt=
new RefineableRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
177 Bulk_mesh_pt->spatial_error_estimator_pt()=
new Z2ErrorEstimator;
180 Bulk_mesh_pt->max_permitted_error()=1.0e-4;
181 Bulk_mesh_pt->min_permitted_error()=1.0e-6;
184 add_sub_mesh(Bulk_mesh_pt);
191 ELEMENT* prescribed_height_element_pt=
dynamic_cast<ELEMENT*
>(
197 Control_node_pt=
static_cast<Node*
>(
198 prescribed_height_element_pt->node_pt(0));
200 cout <<
"Controlling height at (x,y) : (" << Control_node_pt->x(0)
201 <<
"," << Control_node_pt->x(1) <<
")" << endl;
205 Height_control_element_pt=0;
206 Height_control_mesh_pt=0;
209 Height_control_element_pt=
new HeightControlElement(
213 Height_control_element_pt->kappa_pt()->
217 Height_control_mesh_pt =
new Mesh;
218 Height_control_mesh_pt->add_element_pt(Height_control_element_pt);
221 add_sub_mesh(Height_control_mesh_pt);
239 Contact_angle_mesh_pt=0;
244 Contact_angle_mesh_pt=
new Mesh;
247 create_contact_angle_elements(1);
248 create_contact_angle_elements(3);
251 add_sub_mesh(Contact_angle_mesh_pt);
266 unsigned n_bound = Bulk_mesh_pt->nboundary();
267 for(
unsigned b=0;b<n_bound;b++)
275 unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
276 for (
unsigned n=0;n<n_node;n++)
278 Bulk_mesh_pt->boundary_node_pt(b,n)->pin(0);
287 unsigned n_bulk=Bulk_mesh_pt->nelement();
288 for(
unsigned i=0;i<n_bulk;i++)
291 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(i));
310 unsigned nel=Contact_angle_mesh_pt->nelement();
311 for (
unsigned e=0;e<nel;e++)
315 YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
316 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
317 Contact_angle_mesh_pt->element_pt(e));
325 cout <<
"\nNumber of equations: " << assign_eqn_numbers() << endl;
326 cout <<
"\n********************************************\n" << endl;
335template<
class ELEMENT>
340 unsigned n_element = Bulk_mesh_pt->nboundary_element(b);
343 for(
unsigned e=0;e<n_element;e++)
346 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
347 Bulk_mesh_pt->boundary_element_pt(b,e));
350 int face_index = Bulk_mesh_pt->face_index_at_boundary(b,e);
353 YoungLaplaceContactAngleElement<ELEMENT>* contact_angle_element_pt =
new
354 YoungLaplaceContactAngleElement<ELEMENT>(bulk_elem_pt,face_index);
357 Contact_angle_mesh_pt->add_element_pt(contact_angle_element_pt);
367template<
class ELEMENT>
372 unsigned n_element = Contact_angle_mesh_pt->nelement();
375 for(
unsigned e=0;e<n_element;e++)
378 delete Contact_angle_mesh_pt->element_pt(e);
382 Contact_angle_mesh_pt->flush_element_and_node_storage();
392template<
class ELEMENT>
403 cout <<
"Solving for Prescribed KAPPA Value = " ;
411 cout <<
"Solving for Prescribed HEIGHT Value = " ;
421template<
class ELEMENT>
423 ofstream& trace_file)
430 trace_file << Control_node_pt->value(0) ;
441 snprintf(filename,
sizeof(filename),
"%s/soln%i.dat",doc_info.directory().c_str(),
443 some_file.open(filename);
444 Bulk_mesh_pt->output(some_file,npts);
455 ofstream tangent_file;
456 snprintf(filename,
sizeof(filename),
"%s/tangent_to_contact_line%i.dat",
457 doc_info.directory().c_str(),
459 tangent_file.open(filename);
461 ofstream normal_file;
462 snprintf(filename,
sizeof(filename),
"%s/normal_to_contact_line%i.dat",
463 doc_info.directory().c_str(),
465 normal_file.open(filename);
468 ofstream contact_angle_file;
469 snprintf(filename,
sizeof(filename),
"%s/contact_angle%i.dat",
470 doc_info.directory().c_str(),
472 contact_angle_file.open(filename);
475 Vector<double> tangent(3);
476 Vector<double> normal(3);
477 Vector<double> r_contact(3);
480 unsigned n_element = Contact_angle_mesh_pt->nelement();
483 for(
unsigned e=0;e<n_element;e++)
486 tangent_file <<
"ZONE" << std::endl;
487 normal_file <<
"ZONE" << std::endl;
488 contact_angle_file <<
"ZONE" << std::endl;
491 YoungLaplaceContactAngleElement<ELEMENT>* el_pt =
492 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
493 Contact_angle_mesh_pt->element_pt(e));
497 for (
unsigned i=0;i<npts;i++)
499 s[0]=-1.0+2.0*double(i)/double(npts-1);
501 dynamic_cast<ELEMENT*
>(el_pt->bulk_element_pt())->
502 position(el_pt->local_coordinate_in_bulk(s),r_contact);
504 el_pt->contact_line_vectors(s,tangent,normal);
505 tangent_file << r_contact[0] <<
" "
506 << r_contact[1] <<
" "
507 << r_contact[2] <<
" "
510 << tangent[2] <<
" " << std::endl;
512 normal_file << r_contact[0] <<
" "
513 << r_contact[1] <<
" "
514 << r_contact[2] <<
" "
517 << normal[2] <<
" " << std::endl;
519 contact_angle_file << r_contact[1] <<
" "
520 << el_pt->actual_cos_contact_angle(s)
527 tangent_file.close();
529 contact_angle_file.close();
533 cout <<
"\n********************************************" << endl << endl;
543void run_it(
const string& output_directory)
557 doc_info.set_directory(output_directory);
561 snprintf(filename,
sizeof(filename),
"%s/trace.dat",doc_info.directory().c_str());
562 trace_file.open(filename);
566 "VARIABLES=\"<GREEK>k</GREEK>\",\"<GREEK>k</GREEK>_{ex}\",\"h\""
568 trace_file <<
"ZONE" << std::endl;
577 problem.refine_uniformly();
596 unsigned max_adapt=1;
597 problem.newton_solve(max_adapt);
618int main(
int argc,
char* argv[])
622 CommandLineArgs::setup(argc,argv);
630 if (CommandLineArgs::Argc==1)
633 <<
"Running every case with limited number of steps for validation"
642 case_lo=atoi(argv[1]);
643 case_hi=atoi(argv[1]);
651 for (
unsigned my_case=case_lo;my_case<=case_hi;my_case++)
661 <<
"//////////////////////////////////////////////////////////\n"
662 <<
"All pinned solution \n"
663 <<
"//////////////////////////////////////////////////////////\n\n";
669 run_it(
"RESLT_adapt_all_pinned");
676 <<
"//////////////////////////////////////////////////////////\n"
677 <<
"Barrel-shaped solution with spine \n"
678 <<
"/////////////////////////////////////////////////////////\n\n";
683 run_it(
"RESLT_adapt_barrel_shape");
690 <<
"//////////////////////////////////////////////////////////\n"
691 <<
"Barrel-shaped solution without spines \n"
692 <<
"/////////////////////////////////////////////////////////\n\n";
697 run_it(
"RESLT_adapt_barrel_shape_without_spines");
704 <<
"//////////////////////////////////////////////////////////\n"
705 <<
"T-junction solution \n"
706 <<
"//////////////////////////////////////////////////////////\n\n";
716 run_it(
"RESLT_adapt_T_junction");
723 std::cout <<
"Wrong case! Options are:\n"
724 <<
"0: adaptive All pinned\n"
725 <<
"1: adaptive Barrel with spines\n"
726 <<
"2: adaptive Barrel without spines\n"
727 <<
"3: adaptive T_junction\n"
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)
RefineableRectangularQuadMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
void actions_before_newton_solve()
Update the problem specs before solve: Empty.
Mesh * Contact_angle_mesh_pt
Pointer to the contact angle mesh.
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.
Mesh * Height_control_mesh_pt
Pointer to mesh containing the height control element.
Node * Control_node_pt
Node at which the height (displacement along spine) is controlled/doced.
double L_x
Length and width of the domain.
double Controlled_height
Height control value.
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.
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...
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...
double L_y
Width of domain.
double Gamma
Contact angle and its cos (dependent parameter – is reassigned)
@ T_junction_with_nonzero_contact_angle
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.
void run_it(const string &output_directory)
Run code for current setting of parameter values – specify name of output directory.