36 #include "young_laplace.h" 39 #include "meshes/rectangular_quadmesh.h" 43 using namespace oomph;
54 double Cos_gamma=cos(MathematicalConstants::Pi/6.0);
74 Vector<double>& spine_B,
75 Vector< Vector<double> >& dspine_B)
82 dspine_B[0][0] = 1.0 ;
83 dspine_B[1][0] = 0.0 ;
84 dspine_B[0][1] = 0.0 ;
85 dspine_B[1][1] = 1.0 ;
86 dspine_B[0][2] = 0.0 ;
87 dspine_B[1][2] = 0.0 ;
97 double Alpha_min = MathematicalConstants::Pi/2.0*1.5;
100 double Alpha_max = MathematicalConstants::Pi/2.0*0.5;
106 Vector<double>& spine,
107 Vector< Vector<double> >& dspine)
116 spine[1]=cos(Alpha_min+(Alpha_max-Alpha_min)*x[1]/L_y);
118 dspine[1][1]=-sin(Alpha_min+(Alpha_max-Alpha_min)*x[1]/L_y)
121 spine[2]=sin(Alpha_min+(Alpha_max-Alpha_min)*x[1]/L_y);
123 dspine[1][2]=cos(Alpha_min+(Alpha_max-Alpha_min)*x[1]/L_y)
141 template<
class ELEMENT>
163 if (Contact_angle_mesh_pt!=0) delete_contact_angle_elements();
166 rebuild_global_mesh();
173 create_contact_angle_elements(1);
174 create_contact_angle_elements(3);
177 unsigned nel=Contact_angle_mesh_pt->nelement();
178 for (
unsigned e=0;e<nel;e++)
182 YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
183 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
184 Contact_angle_mesh_pt->element_pt(e));
191 rebuild_global_mesh();
197 void doc_solution(DocInfo& doc_info, ofstream& trace_file);
203 void create_contact_angle_elements(
const unsigned& b);
206 void delete_contact_angle_elements();
229 template<
class ELEMENT>
249 Bulk_mesh_pt=
new RefineableRectangularQuadMesh<ELEMENT>(n_x,n_y,l_x,l_y);
252 Bulk_mesh_pt->spatial_error_estimator_pt()=
new Z2ErrorEstimator;
255 Bulk_mesh_pt->max_permitted_error()=1.0e-4;
256 Bulk_mesh_pt->min_permitted_error()=1.0e-6;
260 if ((n_x%2!=0)||(n_y%2!=0))
262 cout <<
"n_x n_y should be even" << endl;
267 ELEMENT* prescribed_height_element_pt=
dynamic_cast<ELEMENT*
>(
268 Bulk_mesh_pt->element_pt(n_y*n_x/2+n_x/2));
271 Control_node_pt=
static_cast<Node*
>(prescribed_height_element_pt->node_pt(0));
273 std::cout <<
"Controlling height at (x,y) : (" << Control_node_pt->x(0)
274 <<
"," << Control_node_pt->x(1) <<
")" <<
"\n" << endl;
278 HeightControlElement* height_control_element_pt=
new HeightControlElement(
282 Height_control_mesh_pt =
new Mesh;
283 Height_control_mesh_pt->add_element_pt(height_control_element_pt);
286 Kappa_pt=height_control_element_pt->kappa_pt();
296 Contact_angle_mesh_pt=
new Mesh;
299 create_contact_angle_elements(1);
300 create_contact_angle_elements(3);
305 add_sub_mesh(Bulk_mesh_pt);
306 add_sub_mesh(Height_control_mesh_pt);
307 add_sub_mesh(Contact_angle_mesh_pt);
317 unsigned n_bound = Bulk_mesh_pt->nboundary();
318 for(
unsigned b=0;b<n_bound;b++)
324 unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
325 for (
unsigned n=0;n<n_node;n++)
327 Bulk_mesh_pt->boundary_node_pt(b,n)->pin(0);
336 unsigned n_bulk=Bulk_mesh_pt->nelement();
337 for(
unsigned i=0;i<n_bulk;i++)
340 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(i));
351 unsigned nel=Contact_angle_mesh_pt->nelement();
352 for (
unsigned e=0;e<nel;e++)
356 YoungLaplaceContactAngleElement<ELEMENT> *el_pt =
357 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
358 Contact_angle_mesh_pt->element_pt(e));
366 cout <<
"\nNumber of equations: " << assign_eqn_numbers() << endl;
367 cout <<
"\n********************************************\n" << endl;
376 template<
class ELEMENT>
381 unsigned n_element = Bulk_mesh_pt->nboundary_element(b);
384 for(
unsigned e=0;e<n_element;e++)
387 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
388 Bulk_mesh_pt->boundary_element_pt(b,e));
391 int face_index = Bulk_mesh_pt->face_index_at_boundary(b,e);
394 YoungLaplaceContactAngleElement<ELEMENT>* contact_angle_element_pt =
new 395 YoungLaplaceContactAngleElement<ELEMENT>(bulk_elem_pt,face_index);
398 Contact_angle_mesh_pt->add_element_pt(contact_angle_element_pt);
408 template<
class ELEMENT>
413 unsigned n_element = Contact_angle_mesh_pt->nelement();
416 for(
unsigned e=0;e<n_element;e++)
419 delete Contact_angle_mesh_pt->element_pt(e);
423 Contact_angle_mesh_pt->flush_element_and_node_storage();
433 template<
class ELEMENT>
435 ofstream& trace_file)
440 trace_file << -1.0*
Kappa_pt->value(0) <<
" ";
441 trace_file << Control_node_pt->value(0) ;
452 sprintf(filename,
"%s/soln%i.dat",doc_info.directory().c_str(),
454 some_file.open(filename);
455 Bulk_mesh_pt->output(some_file,npts);
461 ofstream tangent_file;
462 sprintf(filename,
"%s/tangent_to_contact_line%i.dat",
463 doc_info.directory().c_str(),
465 tangent_file.open(filename);
467 ofstream normal_file;
468 sprintf(filename,
"%s/normal_to_contact_line%i.dat",
469 doc_info.directory().c_str(),
471 normal_file.open(filename);
474 ofstream contact_angle_file;
475 sprintf(filename,
"%s/contact_angle%i.dat",
476 doc_info.directory().c_str(),
478 contact_angle_file.open(filename);
481 Vector<double> tangent(3);
482 Vector<double> normal(3);
483 Vector<double> r_contact(3);
486 unsigned n_element = Contact_angle_mesh_pt->nelement();
489 for(
unsigned e=0;e<n_element;e++)
492 tangent_file <<
"ZONE" << std::endl;
493 normal_file <<
"ZONE" << std::endl;
494 contact_angle_file <<
"ZONE" << std::endl;
497 YoungLaplaceContactAngleElement<ELEMENT>* el_pt =
498 dynamic_cast<YoungLaplaceContactAngleElement<ELEMENT>*
>(
499 Contact_angle_mesh_pt->element_pt(e));
503 for (
unsigned i=0;i<npts;i++)
505 s[0]=-1.0+2.0*double(i)/double(npts-1);
507 dynamic_cast<ELEMENT*
>(el_pt->bulk_element_pt())->
508 position(el_pt->local_coordinate_in_bulk(s),r_contact);
510 el_pt->contact_line_vectors(s,tangent,normal);
511 tangent_file << r_contact[0] <<
" " 512 << r_contact[1] <<
" " 513 << r_contact[2] <<
" " 516 << tangent[2] <<
" " << std::endl;
518 normal_file << r_contact[0] <<
" " 519 << r_contact[1] <<
" " 520 << r_contact[2] <<
" " 523 << normal[2] <<
" " << std::endl;
525 contact_angle_file << r_contact[1] <<
" " 526 << el_pt->actual_cos_contact_angle(s)
533 tangent_file.close();
535 contact_angle_file.close();
538 cout <<
"\n********************************************" << endl << endl;
557 doc_info.set_directory(
"RESLT");
561 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
562 trace_file.open(filename);
565 trace_file <<
"VARIABLES=\"<GREEK>k</GREEK>\",\"h\"" << std::endl;
566 trace_file <<
"ZONE" << std::endl;
577 problem.refine_uniformly();
587 double increment=0.1;
591 for (
unsigned istep=0;istep<nstep;istep++)
596 unsigned max_adapt=1;
597 problem.newton_solve(max_adapt);
double L_x
Length and width of the domain.
RefineableYoungLaplaceProblem()
Constructor:
double Controlled_height
Height control value.
double Alpha_min
Min. spine angle against horizontal plane.
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.
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()
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...
Namespace for "global" problem parameters.
Mesh * Contact_angle_mesh_pt
Pointer to the contact angle 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...
void actions_after_adapt()
Actions after adapt: Rebuild the mesh of contact angle elements.
Node * Control_node_pt
Node at which the height (displacement along spine) is controlled/doced.
double Cos_gamma
Cos of contact angle.
double Alpha_max
Max. spine angle against horizontal plane.
double L_y
Width of domain.
Mesh * Height_control_mesh_pt
Pointer to mesh containing the height control element.
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...
Data * Kappa_pt
Pointer to Data object that stores the prescribed curvature.
RefineableRectangularQuadMesh< ELEMENT > * Bulk_mesh_pt
Pointer to the "bulk" mesh.
void actions_after_newton_solve()
Update the problem after solve: Empty.
void delete_contact_angle_elements()
Delete contact angle elements.