43 #include "axisym_navier_stokes.h" 46 #include "fluid_interface.h" 49 #include "constitutive.h" 52 #include "meshes/rectangular_quadmesh.h" 58 using namespace oomph;
82 double Ca = pow(Film_Thickness,3.0);
91 double Alpha = 0.8537;
145 template<
class ELEMENT>
165 unsigned n_node = this->nnode();
168 const unsigned c_index = C_bulk_index;
180 for(
unsigned l=0;l<n_node;l++)
182 C += this->nodal_value(l,c_index)*psi(l);
192 TimeStepper* time_stepper_pt= this->node_pt(l)->time_stepper_pt();
197 if (time_stepper_pt->type()!=
"Steady")
200 const unsigned c_index = C_bulk_index;
203 const unsigned n_time = time_stepper_pt->ntstorage();
205 for(
unsigned t=0;t<n_time;t++)
207 dcdt += time_stepper_pt->weight(1,t)*this->nodal_value(t,l,c_index);
217 Vector<double> &residuals, DenseMatrix<double> &jacobian,
218 const unsigned &flag,
const Shape &psif,
const DShape &dpsifds,
219 const DShape &dpsifdS,
const DShape &dpsifdS_div,
220 const Vector<double> &s,
221 const Vector<double> &interpolated_x,
const Vector<double> &interpolated_n,
222 const double &W,
const double &J)
227 residuals, jacobian, flag,psif,dpsifds,dpsifdS,dpsifdS_div,
228 s, interpolated_x, interpolated_n, W, J);
231 const double k = this->k();
232 const double alpha = this->alpha();
234 unsigned n_node = this->nnode();
237 int local_eqn = 0, local_unknown = 0;
242 unsigned c_bulk_index = this->C_bulk_index;
246 double interpolated_C = 0.0;
247 double interpolated_C_bulk = 0.0;
250 for(
unsigned l=0;l<n_node;l++)
252 const double psi = psif(l);
253 const double C_ = this->nodal_value(l,this->C_index[l]);
255 interpolated_C += C_*psi;
256 interpolated_C_bulk += this->nodal_value(l,c_bulk_index)*psi;
260 double flux = alpha*(interpolated_C_bulk - interpolated_C);
263 for(
unsigned l=0;l<n_node;l++)
268 local_eqn = this->nodal_local_eqn(l,c_bulk_index);
274 residuals[local_eqn] -= k*flux*psif(l)*W*J;
278 for(
unsigned l2=0;l2<n_node;l2++)
280 local_unknown = this->nodal_local_eqn(l2,this->C_index[l2]);
281 if(local_unknown >= 0)
283 jacobian(local_eqn,local_unknown) += k*alpha*psif(l2)*psif(l)*W*J;
286 local_unknown = this->nodal_local_eqn(l2,c_bulk_index);
287 if(local_unknown >= 0)
289 jacobian(local_eqn,local_unknown) -= k*alpha*psif(l2)*psif(l)*W*J;
298 local_eqn = this->nodal_local_eqn(l,this->C_index[l]);
304 residuals[local_eqn] -= flux*psif(l)*W*J;
308 for(
unsigned l2=0;l2<n_node;l2++)
310 local_unknown = this->nodal_local_eqn(l2,this->C_index[l2]);
311 if(local_unknown >= 0)
313 jacobian(local_eqn,local_unknown) += alpha*psif(l2)*psif(l)*W*J;
316 local_unknown = this->nodal_local_eqn(l2,c_bulk_index);
317 if(local_unknown >= 0)
319 jacobian(local_eqn,local_unknown) -= alpha*psif(l2)*psif(l)*W*J;
333 FiniteElement*
const &element_pt,
const int &face_index) :
335 (element_pt,face_index)
338 Alpha_pt = &this->Default_Physical_Constant_Value;
339 K_pt = &this->Default_Physical_Constant_Value;
350 double k() {
return *K_pt;}
359 void output(std::ostream &outfile,
const unsigned &n_plot)
361 outfile.precision(16);
367 outfile <<
"ZONE I=" << n_plot << std::endl;
369 const unsigned n_node = this->nnode();
370 const unsigned dim = this->dim();
373 DShape dpsi(n_node,dim);
376 for(
unsigned l=0;l<n_plot;l++)
378 s[0] = -1.0 + l*2.0/(n_plot-1);
380 this->dshape_local(s,psi,dpsi);
381 Vector<double> interpolated_tangent(2,0.0);
382 for(
unsigned l=0;l<n_node;l++)
384 const double dpsi_ = dpsi(l,0);
385 for(
unsigned i=0;i<2;i++)
387 interpolated_tangent[i] += this->nodal_position(l,i)*dpsi_;
392 double t_vel = (this->interpolated_u(s,0)*interpolated_tangent[0] + this->interpolated_u(s,1)*interpolated_tangent[1])/
393 sqrt(interpolated_tangent[0]*interpolated_tangent[0] + interpolated_tangent[1]*interpolated_tangent[1]);
397 for(
unsigned i=0;i<2;i++) outfile << this->interpolated_x(s,i) <<
" ";
398 for(
unsigned i=0;i<2;i++) outfile << this->interpolated_u(s,i) <<
" ";
400 outfile << 0.0 <<
" ";
402 outfile << this->interpolated_C(s) <<
" ";
403 outfile << interpolated_C_bulk(s) <<
" ";
405 outfile << this->sigma(s) <<
" " << t_vel << std::endl;
407 outfile << std::endl;
416 template<
class ELEMENT,
class TIMESTEPPER>
436 const unsigned n_node = Bulk_mesh_pt->nnode();
439 for(
unsigned n=0;n<n_node;n++)
442 for(
unsigned i=0;i<3;i++)
445 Bulk_mesh_pt->node_pt(n)->set_value(i,0.0);
448 Bulk_mesh_pt->node_pt(n)->set_value(3,1.0);
453 assign_initial_values_impulsive();
464 double global_error = 0.0;
467 const unsigned n_node = Bulk_mesh_pt->nnode();
470 for(
unsigned n=0;n<n_node;n++)
473 const unsigned n_dim = 1;
475 double node_position_error = 0.0;
477 for(
unsigned i=0;i<n_dim;i++)
481 Bulk_mesh_pt->node_pt(n)->position_time_stepper_pt()->
482 temporal_error_in_position(Bulk_mesh_pt->node_pt(n),i);
485 node_position_error += error*error;
489 node_position_error /= n_dim;
491 global_error += node_position_error;
495 global_error /= n_node;
498 return sqrt(global_error);
506 Mesh* Interface_mesh_pt;
512 Node* Document_node_pt;
515 void doc_solution(DocInfo &doc_info);
518 void unsteady_run(
const double &t_max,
const double &dt);
527 const unsigned n_interface_element = Interface_mesh_pt->nelement();
530 for(
unsigned e=0;e<n_interface_element;e++)
535 (Interface_mesh_pt->element_pt(e));
549 const unsigned n_node = Bulk_mesh_pt->nnode();
550 for(
unsigned n=0;n<n_node;n++)
553 double r = Bulk_mesh_pt->node_pt(n)->x(0);
555 double z_value = Bulk_mesh_pt->node_pt(n)->x(1);
563 Bulk_mesh_pt->node_pt(n)->x(0) = 1.0 - (1.0-r)*thickness;
567 Bulk_mesh_pt->set_lagrangian_nodal_coordinates();
580 template<
class ELEMENT,
class TIMESTEPPER>
588 add_time_stepper_pt(
new TIMESTEPPER(
true));
592 Bulk_mesh_pt =
new ElasticRectangularQuadMesh<ELEMENT>(n_r,n_z,1.0,l_z,time_stepper_pt());
595 Interface_mesh_pt =
new Mesh;
604 unsigned n_element = Bulk_mesh_pt->nboundary_element(3);
607 for(
unsigned e=0;e<n_element;e++)
610 ELEMENT* bulk_elem_pt =
dynamic_cast<ELEMENT*
>(
611 Bulk_mesh_pt->boundary_element_pt(3,e));
614 int face_index = Bulk_mesh_pt->face_index_at_boundary(3,e);
621 Interface_mesh_pt->add_element_pt(interface_element_pt);
628 Document_node_pt = Bulk_mesh_pt->node_pt(0);
631 add_sub_mesh(Bulk_mesh_pt);
632 add_sub_mesh(Interface_mesh_pt);
646 unsigned n_node = this->Bulk_mesh_pt->nnode();
647 for(
unsigned n=0;n<n_node;++n)
649 this->Bulk_mesh_pt->node_pt(n)->pin(2);
650 this->Bulk_mesh_pt->node_pt(n)->pin_position(1);
657 unsigned n_node = Bulk_mesh_pt->nboundary_node(ibound);
658 for(
unsigned n=0;n<n_node;n++)
660 Bulk_mesh_pt->boundary_node_pt(ibound,n)->set_value(4,1.0);
664 const unsigned n_boundary = Bulk_mesh_pt->nboundary();
667 for(
unsigned b=0;b<n_boundary;b++)
670 const unsigned n_node = Bulk_mesh_pt->nboundary_node(b);
673 for(
unsigned n=0;n<n_node;n++)
676 Bulk_mesh_pt->boundary_node_pt(b,n)->pin(2);
681 Bulk_mesh_pt->boundary_node_pt(b,n)->pin(0);
682 Bulk_mesh_pt->boundary_node_pt(b,n)->pin(1);
683 Bulk_mesh_pt->boundary_node_pt(b,n)->pin_position(0);
688 Bulk_mesh_pt->boundary_node_pt(b,n)->pin(1);
699 const unsigned n_bulk = Bulk_mesh_pt->nelement();
702 for(
unsigned e=0;e<n_bulk;e++)
705 ELEMENT *el_pt =
dynamic_cast<ELEMENT*
>(Bulk_mesh_pt->element_pt(e));
721 el_pt->constitutive_law_pt() = Constitutive_law_pt;
732 Data* external_pressure_data_pt =
new Data(1);
737 external_pressure_data_pt->pin(0);
738 external_pressure_data_pt->set_value(0,p_ext);
741 const unsigned n_interface_element = Interface_mesh_pt->nelement();
744 for(
unsigned e=0;e<n_interface_element;e++)
749 (Interface_mesh_pt->element_pt(e));
775 cout <<
"Number of equations: " << assign_eqn_numbers() << std::endl;
784 template<
class ELEMENT,
class TIMESTEPPER>
790 double t= time_pt()->time();
791 cout <<
"Time is now " << t << std::endl;
794 Trace_file << time_pt()->time() <<
" " 795 << Document_node_pt->x(0)
796 <<
" " << this->compute_total_mass() << std::endl;
802 const unsigned npts = 5;
813 sprintf(filename,
"%s/int%i.dat",doc_info.directory().c_str(),
815 some_file.open(filename);
816 Interface_mesh_pt->output(some_file,npts);
853 template<
class ELEMENT,
class TIMESTEPPER>
862 deform_free_surface(epsilon);
868 doc_info.set_directory(
"RESLT");
875 sprintf(filename,
"%s/trace.dat",doc_info.directory().c_str());
876 Trace_file.open(filename);
879 Trace_file <<
"time" <<
", " 880 <<
"edge spine height" <<
", " 881 <<
"mass " <<
", " << std::endl;
887 set_initial_condition();
890 const unsigned n_timestep = unsigned(t_max/dt);
900 doc_solution(doc_info);
908 for(
unsigned t=1;t<=n_timestep;t++)
911 cout <<
"\nTimestep " << t <<
" of " << n_timestep << std::endl;
914 unsteady_newton_solve(dt);
922 doc_solution(doc_info);
928 Bulk_mesh_pt->set_lagrangian_nodal_coordinates();
947 int main(
int argc,
char* argv[])
951 CommandLineArgs::setup(argc,argv);
954 double t_max = 1000.0;
957 const double dt = 0.1;
960 if(CommandLineArgs::Argc>1)
966 const unsigned n_r = 10;
969 const unsigned n_z = 80;
982 problem(n_r,n_z,l_z);
double K
K parameter that describes solubility number.
double Peclet_S
Surface Peclet number.
ElasticAxisymmetricSolubleSurfactantTransportInterfaceElement(FiniteElement *const &element_pt, const int &face_index)
double global_temporal_error_norm()
int main(int argc, char *argv[])
Driver code for single fluid axisymmetric horizontal interface problem.
double Peclet_St_S
Sufrace Peclet number multiplied by Strouhal number.
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)
Problem constructor.
double * Alpha_pt
Pointer to adsorption 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...
double *& peclet_s_pt()
Access function for pointer to the surface Peclet number.
ofstream Pvd_file
Pvd file – a wrapper for all the different vtu output files plus information about continuous time t...
Specialise to the Axisymmetric geometry.
void add_additional_residual_contributions_interface(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag, const Shape &psif, const DShape &dpsifds, const DShape &dpsifdS, const DShape &dpsifdS_div, const Vector< double > &s, const Vector< double > &interpolated_x, const Vector< double > &interpolated_n, const double &W, const double &J)
Helper function to calculate the additional contributions to be added at each integration point...
double ReSt
Womersley = Reynolds times Strouhal.
double alpha()
Return the adsorption number.
double *& alpha_pt()
Access function for pointer to adsorption number.
~InterfaceProblem()
Destructor (empty)
double integrate_c()
Compute the concentration intergated over the surface area.
void output(std::ostream &outfile, const unsigned &n_plot)
Overload the output function.
double *& k_pt()
Access function for pointer to solubility number.
ElasticRectangularQuadMesh< ELEMENT > * Bulk_mesh_pt
Access function for the specific mesh.
double Re
Reynolds number.
double k()
Return the solubility nubmer.
double dc_bulk_dt_surface(const unsigned &l) const
The time derivative of the bulk surface concentration.
double Epsilon
Free surface cosine deformation parameter.
void set_initial_condition()
double *& beta_pt()
Access function for pointer to the Elasticity number.
double ReInvFr
Product of Reynolds and Froude number.
double * K_pt
Pointer to solubility number.
Vector< double > G(3)
Direction of gravity.
void unsteady_run(const unsigned &nstep)
Run an unsteady simulation with specified number of steps.
double Beta
Surface Elasticity number (weak case)
void deform_free_surface(const double &epsilon)
Deform the mesh/free surface to a prescribed function.
double P_ext
External pressure.
void doc_solution(DocInfo &doc_info)
Doc the solution.
double Pe_reference_scale
double *& peclet_strouhal_s_pt()
Access function for pointer to the surface Peclet x Strouhal number.
double interpolated_C_bulk(const Vector< double > &s)
Get the bulk surfactant concentration.
void add_additional_residual_contributions_interface(Vector< double > &residuals, DenseMatrix< double > &jacobian, const unsigned &flag, const Shape &psif, const DShape &dpsifds, const DShape &dpsifdS, const DShape &dpsifdS_div, const Vector< double > &s, const Vector< double > &interpolated_x, const Vector< double > &interpolated_n, const double &W, const double &J)
Overload the Helper function to calculate the residuals and jacobian entries. This particular functio...
ConstitutiveLaw * Constitutive_law_pt
Pointer to the constitutive law.
double Alpha_absorption
Alpha for absorption kinetics.
double Nu
Pseudo-solid Poisson ratio.
double Ca
Capillary number.
double Alpha
Wavelength of the domain.
double compute_total_mass()
Compute the total mass of the insoluble surfactant.
double *& ca_pt()
Pointer to the Capillary number.