37 #include "navier_stokes.h"
38 #include "fluid_interface.h"
41 #include "meshes/single_layer_cubic_spine_mesh.h"
44 using namespace oomph;
98 bool operator()(GeneralisedElement*
const &x, GeneralisedElement*
const &y)
101 FiniteElement* cast_x =
dynamic_cast<FiniteElement*
>(x);
102 FiniteElement* cast_y =
dynamic_cast<FiniteElement*
>(y);
104 if((cast_x ==0) || (cast_y==0)) {
return 0;}
106 {
return (cast_x->node_pt(0)->x(1)< cast_y->node_pt(0)->x(1));}
119 template<
class ELEMENT>
125 const unsigned &n_theta,
126 const double &r_min,
const double &r_max,
128 const double &theta_min,
const double &theta_max,
129 TimeStepper* time_stepper_pt = &Mesh::Default_TimeStepper):
133 SingleLayerCubicSpineMesh<ELEMENT>(n_theta,n_y,n_r,r_max,l_y,theta_max,
138 unsigned n_node = this->nnode();
141 for (
unsigned n=0;n<n_node;n++)
144 Node* nod_pt=this->node_pt(n);
145 SpineNode* spine_node_pt=
dynamic_cast<SpineNode*
>(nod_pt);
147 double x_old=nod_pt->x(0);
148 double y_old=nod_pt->x(1);
149 double z_old=nod_pt->x(2);
153 double r = r_min + (r_max-r_min)*z_old;
154 double theta = (theta_min + (theta_max-theta_min)*x_old);
158 if(spine_node_pt->spine_pt()->ngeom_parameter()==0)
162 spine_node_pt->spine_pt()->add_geom_parameter(theta);
167 nod_pt->x(0)=r*cos(theta);
168 nod_pt->x(2)=r*sin(theta);
179 double W = spine_node_pt->fraction();
181 double theta = spine_node_pt->spine_pt()->geom_parameter(0);
183 double H = spine_node_pt->h();
185 spine_node_pt->x(0) = (1.0-W*H)*cos(theta);
186 spine_node_pt->x(2) = (1.0-W*H)*sin(theta);
195 template<
class ELEMENT,
class TIMESTEPPER>
205 const unsigned &n_theta,
const double &r_min,
206 const double &r_max,
const double &l_y,
207 const double &theta_max);
216 void unsteady_run(
const unsigned& nstep);
219 void doc_solution(DocInfo& doc_info);
227 const unsigned n_interface_element = Surface_mesh_pt->nelement();
230 for(
unsigned e=0;e<n_interface_element;e++)
235 (Surface_mesh_pt->element_pt(e));
269 template<
class ELEMENT,
class TIMESTEPPER>
271 (
const unsigned &n_r,
const unsigned &n_y,
const unsigned &n_theta,
273 const double &r_max,
const double &l_y,
const double &theta_max)
274 : R_max(r_max), L_y(l_y)
283 add_time_stepper_pt(
new TIMESTEPPER);
287 (n_r,n_y,n_theta,r_min,r_max,l_y,0.0,theta_max,time_stepper_pt());
299 for(
unsigned e1=0;e1<n_y;e1++)
301 for(
unsigned e2=0;e2<n_theta;e2++)
305 FiniteElement* bulk_element_pt =
306 Bulk_mesh_pt->finite_element_pt(n_theta*n_y*(n_r-1) + e2 + e1*n_theta);
309 FiniteElement* interface_element_pt =
325 unsigned long n_boundary_node =
Bulk_mesh_pt->nboundary_node(0);
326 for(
unsigned long n=0;n<n_boundary_node;n++)
328 for(
unsigned i=0;i<3;i++)
335 for(
unsigned b=1;b<4;b+=2)
338 for(
unsigned long n=0;n<n_boundary_node;n++)
345 for(
unsigned b=4;b<5;b+=2)
348 for(
unsigned long n=0;n<n_boundary_node;n++)
355 for(
unsigned b=2;b<3;b++)
358 for(
unsigned long n=0;n<n_boundary_node;n++)
368 for(
unsigned long n=0;n<n_boundary_node;n++)
377 Data* external_pressure_data_pt =
new Data(1);
380 external_pressure_data_pt->set_value(0,1.31);
381 external_pressure_data_pt->pin(0);
387 for(
unsigned e=0;e<n_bulk;e++)
390 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(
Bulk_mesh_pt->element_pt(e));
401 unsigned long interface_element_pt_range =
403 for(
unsigned e=0;e<interface_element_pt_range;e++)
428 cout << assign_eqn_numbers() << std::endl;
431 std::sort(mesh_pt()->element_pt().begin(),
432 mesh_pt()->element_pt().end(),
442 template<
class ELEMENT,
class TIMESTEPPER>
453 cout <<
"Time is now " << time_pt()->time() << std::endl;
456 Trace_file << time_pt()->time();
457 Trace_file <<
" " << Document_node_pt->x(0) <<
" "
458 << this->compute_total_mass()
469 sprintf(filename,
"%s/surface%i.dat",doc_info.directory().c_str(),
471 some_file.open(filename);
472 Surface_mesh_pt->output(some_file,npts);
483 template<
class ELEMENT,
class TIMESTEPPER>
488 Problem::Max_residuals=500.0;
492 unsigned Nspine = Bulk_mesh_pt->nspine();
493 for(
unsigned i=0;i<Nspine;i++)
495 double y_value = Bulk_mesh_pt->boundary_node_pt(0,i)->x(1);
497 Bulk_mesh_pt->spine_pt(i)->height() =
503 Bulk_mesh_pt->node_update();
509 doc_info.set_directory(
"RESLT");
514 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
515 Trace_file.open(filename);
517 Trace_file <<
"VARIABLES=\"time\",";
518 Trace_file <<
"\"h<sub>left</sub>\",\"h<sub>right</sub>\"";
525 assign_initial_values_impulsive(dt);
528 doc_solution(doc_info);
531 for(
unsigned t=1;t<=nstep;t++)
533 cout <<
"TIMESTEP " << t << std::endl;
536 unsteady_newton_solve(dt);
540 doc_solution(doc_info);
553 int main(
int argc,
char *argv[])
568 double r_min = r_max - h;
570 const double pi = MathematicalConstants::Pi;
574 double l_y = pi/alpha;
576 double theta_max = 0.5*pi;
581 unsigned n_theta = 4;
591 problem(n_r,n_y,n_theta,r_min,r_max,l_y,theta_max);
int main(int argc, char *argv[])
Driver code for unsteady two-layer fluid problem. If there are any command line arguments,...
Function-type-object to perform comparison of elements in y-direction.
bool operator()(GeneralisedElement *const &x, GeneralisedElement *const &y) const
Comparison. Are the values identical or not?
Single fluid interface problem including transport of an insoluble surfactant.
Mesh * Surface_mesh_pt
Pointer to the surface mes.
void unsteady_run(const unsigned &nstep)
Run an unsteady simulation with specified number of steps.
InterfaceProblem(const unsigned &n_r, const unsigned &n_y, const unsigned &n_theta, const double &r_min, const double &r_max, const double &l_y, const double &theta_max)
Constructor: Pass number of elements in x and y directions. Also lengths of the domain in x- and y-di...
AnnularSpineMesh< ELEMENT > * Bulk_mesh_pt
Pointer to bulk mesh.
ofstream Trace_file
Trace file.
void doc_solution(DocInfo &doc_info)
Doc the solution.
Node * Document_node_pt
Pointer to a node for documentation purposes.
double R_max
Axial lengths of domain.
double compute_total_mass()
Compute the total mass.
void actions_before_newton_convergence_check()
Spine heights/lengths are unknowns in the problem so their values get corrected during each Newton st...
Deform the existing cubic spine mesh into a annular section with spines directed radially inwards fro...
virtual void spine_node_update(SpineNode *spine_node_pt)
AnnularSpineMesh(const unsigned &n_r, const unsigned &n_y, const unsigned &n_theta, const double &r_min, const double &r_max, const double &l_y, const double &theta_min, const double &theta_max, TimeStepper *time_stepper_pt=&Mesh::Default_TimeStepper)
double *& ca_pt()
Pointer to the Capillary number.
void set_external_pressure_data(Data *external_pressure_data_pt)
Set the Data that contains the single pressure value that specifies the "external pressure" for the i...
Specialise to surface geometry.
double *& peclet_s_pt()
Access function for pointer to the surface Peclet number.
double *& beta_pt()
Access function for pointer to the Elasticity number.
double integrate_c()
Compute the concentration intergated over the surface area.
double *& peclet_strouhal_s_pt()
Access function for pointer to the surface Peclet x Strouhal number.
Namepspace for global parameters, chosen from Campana et al. as in the axisymmetric problem.
double ReSt
Womersley = Reynolds times Strouhal.
double Epsilon
Free surface cosine deformation parameter.
double Beta
Surface Elasticity number (weak case)
double Ca
Capillary number.
double Peclet_S
Surface Peclet number.
double Alpha
Wavelength of the domain.
double ReInvFr
Product of Reynolds and Froude number.
double Re
Reynolds number.
double Peclet_St_S
Sufrace Peclet number multiplied by Strouhal number.
Vector< double > G(3)
Direction of gravity.