SurfactantProblem< ELEMENT, INTERFACE_ELEMENT > Class Template Reference
+ Inheritance diagram for SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >:

Public Member Functions

 SurfactantProblem (const bool &pin=true)
 Constructor. The boolean indicates whether the free surface. More...
 
 ~SurfactantProblem ()
 Destructor. Empty. More...
 
void unpin_surface ()
 Release the free surface so that it can move. More...
 
void actions_before_newton_solve ()
 Update the problem specs before solve (empty) More...
 
void actions_after_newton_solve ()
 Update the problem after solve (empty) More...
 
void actions_before_newton_convergence_check ()
 Remember to update the nodes if the surface is not pinned. More...
 
void actions_before_implicit_timestep ()
 
void actions_before_adapt ()
 Strip off the interface elements before adapting the bulk mesh. More...
 
void actions_after_adapt ()
 Rebuild the mesh of interface elements after adapting the bulk mesh. More...
 
void create_dependent_position_elements ()
 Create the elements that make the position consistent on both sides. More...
 
void delete_dependent_position_elements ()
 Delete the 1d interface elements. More...
 
void create_interface_elements ()
 Create the 1d interface elements. More...
 
void delete_interface_elements ()
 Delete the 1d interface elements. More...
 
void fix_pressure (const unsigned &e, const unsigned &pdof, const double &pvalue)
 Fix pressure in element e at pressure dof pdof and set to pvalue. More...
 
void unfix_pressure (const unsigned &e, const unsigned &pdof)
 UnFix pressure in element e at pressure dof pdof and set to pvalue. More...
 
void deform_interface (const double &epsilon, const unsigned &n_periods)
 
void doc_solution (std::ofstream &trace)
 Doc the solution. More...
 
void set_boundary_conditions (const double &time)
 Set the boundary conditions. More...
 
double global_temporal_error_norm ()
 
void interface_min_max (double &min, double &max)
 
double l2_norm_of_height (const double &h0)
 
void compute_integrated_concentrations (double &surface, double &bulk, double &micelle)
 
void compute_areas (double &lower_area, double &upper_area)
 
 SurfactantProblem (const bool &pin=true)
 Constructor. The boolean indicates whether the free surface. More...
 
 ~SurfactantProblem ()
 Destructor. Empty. More...
 
void unpin_surface ()
 Release the free surface so that it can move. More...
 
void actions_before_newton_solve ()
 Update the problem specs before solve (empty) More...
 
void actions_after_newton_solve ()
 Update the problem after solve (empty) More...
 
void actions_before_newton_convergence_check ()
 Remember to update the nodes if the surface is not pinned. More...
 
void actions_before_implicit_timestep ()
 
void actions_before_adapt ()
 Strip off the interface elements before adapting the bulk mesh. More...
 
void actions_after_adapt ()
 Rebuild the mesh of interface elements after adapting the bulk mesh. More...
 
void create_slave_position_elements ()
 Create the elements that slave the position. More...
 
void delete_slave_position_elements ()
 Delete the 1d interface elements. More...
 
void create_interface_elements ()
 Create the 1d interface elements. More...
 
void delete_interface_elements ()
 Delete the 1d interface elements. More...
 
void fix_pressure (const unsigned &e, const unsigned &pdof, const double &pvalue)
 Fix pressure in element e at pressure dof pdof and set to pvalue. More...
 
void unfix_pressure (const unsigned &e, const unsigned &pdof)
 UnFix pressure in element e at pressure dof pdof and set to pvalue. More...
 
void deform_interface (const double &epsilon, const unsigned &n_periods)
 
void doc_solution (std::ofstream &trace)
 Doc the solution. More...
 
void set_boundary_conditions (const double &time)
 Set the boundary conditions. More...
 
double global_temporal_error_norm ()
 
void interface_min_max (double &min, double &max)
 
double l2_norm_of_height (const double &h0)
 
void compute_integrated_concentrations (double &surface, double &bulk, double &micelle)
 
void compute_areas (double &lower_area, double &upper_area)
 
 SurfactantProblem (const bool &pin=true)
 Constructor. The boolean indicates whether the free surface. More...
 
 ~SurfactantProblem ()
 Destructor. Empty. More...
 
void unpin_surface ()
 Release the free surface so that it can move. More...
 
void actions_before_newton_solve ()
 Update the problem specs before solve (empty) More...
 
void actions_after_newton_solve ()
 Update the problem after solve (empty) More...
 
void actions_before_newton_convergence_check ()
 Remember to update the nodes if the surface is not pinned. More...
 
void actions_before_implicit_timestep ()
 
void fix_pressure (const unsigned &e, const unsigned &pdof, const double &pvalue)
 Fix pressure in element e at pressure dof pdof and set to pvalue. More...
 
void unfix_pressure (const unsigned &e, const unsigned &pdof)
 UnFix pressure in element e at pressure dof pdof and set to pvalue. More...
 
void deform_interface (const double &epsilon, const unsigned &n_periods)
 
void doc_solution (std::ofstream &trace)
 Doc the solution. More...
 
void set_boundary_conditions (const double &time)
 Set the boundary conditions. More...
 
double global_temporal_error_norm ()
 
void interface_min_max (double &min, double &max)
 
double l2_norm_of_height (const double &h0)
 
void compute_integrated_concentrations (double &surface, double &bulk, double &micelle)
 
- Public Member Functions inherited from oomph::Problem
virtual void debug_hook_fct (const unsigned &i)
 
void set_analytic_dparameter (double *const &parameter_pt)
 
void unset_analytic_dparameter (double *const &parameter_pt)
 
bool is_dparameter_calculated_analytically (double *const &parameter_pt)
 
void set_analytic_hessian_products ()
 
void unset_analytic_hessian_products ()
 
bool are_hessian_products_calculated_analytically ()
 
void set_pinned_values_to_zero ()
 
bool distributed () const
 
OomphCommunicator * communicator_pt ()
 access function to the oomph-lib communicator More...
 
const OomphCommunicator * communicator_pt () const
 access function to the oomph-lib communicator, const version More...
 
 Problem ()
 
 Problem (const Problem &dummy)=delete
 Broken copy constructor. More...
 
void operator= (const Problem &)=delete
 Broken assignment operator. More...
 
virtual ~Problem ()
 Virtual destructor to clean up memory. More...
 
Mesh *& mesh_pt ()
 Return a pointer to the global mesh. More...
 
Mesh *const & mesh_pt () const
 Return a pointer to the global mesh (const version) More...
 
Mesh *& mesh_pt (const unsigned &imesh)
 
Mesh *const & mesh_pt (const unsigned &imesh) const
 Return a pointer to the i-th submesh (const version) More...
 
unsigned nsub_mesh () const
 Return number of submeshes. More...
 
unsigned add_sub_mesh (Mesh *const &mesh_pt)
 
void flush_sub_meshes ()
 
void build_global_mesh ()
 
void rebuild_global_mesh ()
 
LinearSolver *& linear_solver_pt ()
 Return a pointer to the linear solver object. More...
 
LinearSolver *const & linear_solver_pt () const
 Return a pointer to the linear solver object (const version) More...
 
LinearSolver *& mass_matrix_solver_for_explicit_timestepper_pt ()
 
LinearSolver * mass_matrix_solver_for_explicit_timestepper_pt () const
 
EigenSolver *& eigen_solver_pt ()
 Return a pointer to the eigen solver object. More...
 
EigenSolver *const & eigen_solver_pt () const
 Return a pointer to the eigen solver object (const version) More...
 
Time *& time_pt ()
 Return a pointer to the global time object. More...
 
Time * time_pt () const
 Return a pointer to the global time object (const version). More...
 
double & time ()
 Return the current value of continuous time. More...
 
double time () const
 Return the current value of continuous time (const version) More...
 
TimeStepper *& time_stepper_pt ()
 
const TimeStepper * time_stepper_pt () const
 
TimeStepper *& time_stepper_pt (const unsigned &i)
 Return a pointer to the i-th timestepper. More...
 
ExplicitTimeStepper *& explicit_time_stepper_pt ()
 Return a pointer to the explicit timestepper. More...
 
unsigned long set_timestepper_for_all_data (TimeStepper *const &time_stepper_pt, const bool &preserve_existing_data=false)
 
virtual void shift_time_values ()
 Shift all values along to prepare for next timestep. More...
 
AssemblyHandler *& assembly_handler_pt ()
 Return a pointer to the assembly handler object. More...
 
AssemblyHandler *const & assembly_handler_pt () const
 Return a pointer to the assembly handler object (const version) More...
 
double & minimum_dt ()
 Access function to min timestep in adaptive timestepping. More...
 
double & maximum_dt ()
 Access function to max timestep in adaptive timestepping. More...
 
unsigned & max_newton_iterations ()
 Access function to max Newton iterations before giving up. More...
 
void problem_is_nonlinear (const bool &prob_lin)
 Access function to Problem_is_nonlinear. More...
 
double & max_residuals ()
 
bool & time_adaptive_newton_crash_on_solve_fail ()
 Access function for Time_adaptive_newton_crash_on_solve_fail. More...
 
double & newton_solver_tolerance ()
 
void add_time_stepper_pt (TimeStepper *const &time_stepper_pt)
 
void set_explicit_time_stepper_pt (ExplicitTimeStepper *const &explicit_time_stepper_pt)
 
void initialise_dt (const double &dt)
 
void initialise_dt (const Vector< double > &dt)
 
Data *& global_data_pt (const unsigned &i)
 Return a pointer to the the i-th global data object. More...
 
void add_global_data (Data *const &global_data_pt)
 
void flush_global_data ()
 
LinearAlgebraDistribution *const & dof_distribution_pt () const
 Return the pointer to the dof distribution (read-only) More...
 
unsigned long ndof () const
 Return the number of dofs. More...
 
unsigned ntime_stepper () const
 Return the number of time steppers. More...
 
unsigned nglobal_data () const
 Return the number of global data values. More...
 
unsigned self_test ()
 Self-test: Check meshes and global data. Return 0 for OK. More...
 
void enable_store_local_dof_pt_in_elements ()
 
void disable_store_local_dof_pt_in_elements ()
 
unsigned long assign_eqn_numbers (const bool &assign_local_eqn_numbers=true)
 
void describe_dofs (std::ostream &out= *(oomph_info.stream_pt())) const
 
void enable_discontinuous_formulation ()
 
void disable_discontinuous_formulation ()
 
void get_dofs (DoubleVector &dofs) const
 
void get_dofs (const unsigned &t, DoubleVector &dofs) const
 Return vector of the t'th history value of all dofs. More...
 
void set_dofs (const DoubleVector &dofs)
 Set the values of the dofs. More...
 
void set_dofs (const unsigned &t, DoubleVector &dofs)
 Set the history values of the dofs. More...
 
void set_dofs (const unsigned &t, Vector< double * > &dof_pt)
 
void add_to_dofs (const double &lambda, const DoubleVector &increment_dofs)
 Add lambda x incremenet_dofs[l] to the l-th dof. More...
 
double * global_dof_pt (const unsigned &i)
 
double & dof (const unsigned &i)
 i-th dof in the problem More...
 
double dof (const unsigned &i) const
 i-th dof in the problem (const version) More...
 
double *& dof_pt (const unsigned &i)
 Pointer to i-th dof in the problem. More...
 
double * dof_pt (const unsigned &i) const
 Pointer to i-th dof in the problem (const version) More...
 
virtual void get_inverse_mass_matrix_times_residuals (DoubleVector &Mres)
 
virtual void get_dvaluesdt (DoubleVector &f)
 
virtual void get_residuals (DoubleVector &residuals)
 Get the total residuals Vector for the problem. More...
 
virtual void get_jacobian (DoubleVector &residuals, DenseDoubleMatrix &jacobian)
 
virtual void get_jacobian (DoubleVector &residuals, CRDoubleMatrix &jacobian)
 
virtual void get_jacobian (DoubleVector &residuals, CCDoubleMatrix &jacobian)
 
virtual void get_jacobian (DoubleVector &residuals, SumOfMatrices &jacobian)
 
void get_fd_jacobian (DoubleVector &residuals, DenseMatrix< double > &jacobian)
 Get the full Jacobian by finite differencing. More...
 
void get_derivative_wrt_global_parameter (double *const &parameter_pt, DoubleVector &result)
 
void get_hessian_vector_products (DoubleVectorWithHaloEntries const &Y, Vector< DoubleVectorWithHaloEntries > const &C, Vector< DoubleVectorWithHaloEntries > &product)
 
void solve_eigenproblem (const unsigned &n_eval, Vector< std::complex< double >> &eigenvalue, Vector< DoubleVector > &eigenvector, const bool &steady=true)
 Solve the eigenproblem. More...
 
void solve_eigenproblem (const unsigned &n_eval, Vector< std::complex< double >> &eigenvalue, const bool &steady=true)
 
virtual void get_eigenproblem_matrices (CRDoubleMatrix &mass_matrix, CRDoubleMatrix &main_matrix, const double &shift=0.0)
 
void assign_eigenvector_to_dofs (DoubleVector &eigenvector)
 Assign the eigenvector passed to the function to the dofs. More...
 
void add_eigenvector_to_dofs (const double &epsilon, const DoubleVector &eigenvector)
 
void store_current_dof_values ()
 Store the current values of the degrees of freedom. More...
 
void restore_dof_values ()
 Restore the stored values of the degrees of freedom. More...
 
void enable_jacobian_reuse ()
 
void disable_jacobian_reuse ()
 Disable recycling of Jacobian in Newton iteration. More...
 
bool jacobian_reuse_is_enabled ()
 Is recycling of Jacobian in Newton iteration enabled? More...
 
bool & use_predictor_values_as_initial_guess ()
 
void newton_solve ()
 Use Newton method to solve the problem. More...
 
void enable_globally_convergent_newton_method ()
 enable globally convergent Newton method More...
 
void disable_globally_convergent_newton_method ()
 disable globally convergent Newton method More...
 
void newton_solve (unsigned const &max_adapt)
 
void steady_newton_solve (unsigned const &max_adapt=0)
 
void copy (Problem *orig_problem_pt)
 
virtual Problem * make_copy ()
 
virtual void read (std::ifstream &restart_file, bool &unsteady_restart)
 
virtual void read (std::ifstream &restart_file)
 
virtual void dump (std::ofstream &dump_file) const
 
void dump (const std::string &dump_file_name) const
 
void delete_all_external_storage ()
 
virtual void symmetrise_eigenfunction_for_adaptive_pitchfork_tracking ()
 
double * bifurcation_parameter_pt () const
 
void get_bifurcation_eigenfunction (Vector< DoubleVector > &eigenfunction)
 
void activate_fold_tracking (double *const &parameter_pt, const bool &block_solve=true)
 
void activate_bifurcation_tracking (double *const &parameter_pt, const DoubleVector &eigenvector, const bool &block_solve=true)
 
void activate_bifurcation_tracking (double *const &parameter_pt, const DoubleVector &eigenvector, const DoubleVector &normalisation, const bool &block_solve=true)
 
void activate_pitchfork_tracking (double *const &parameter_pt, const DoubleVector &symmetry_vector, const bool &block_solve=true)
 
void activate_hopf_tracking (double *const &parameter_pt, const bool &block_solve=true)
 
void activate_hopf_tracking (double *const &parameter_pt, const double &omega, const DoubleVector &null_real, const DoubleVector &null_imag, const bool &block_solve=true)
 
void deactivate_bifurcation_tracking ()
 
void reset_assembly_handler_to_default ()
 Reset the system to the standard non-augemented state. More...
 
double arc_length_step_solve (double *const &parameter_pt, const double &ds, const unsigned &max_adapt=0)
 
double arc_length_step_solve (Data *const &data_pt, const unsigned &data_index, const double &ds, const unsigned &max_adapt=0)
 
void reset_arc_length_parameters ()
 
int & sign_of_jacobian ()
 
void explicit_timestep (const double &dt, const bool &shift_values=true)
 Take an explicit timestep of size dt. More...
 
void unsteady_newton_solve (const double &dt)
 
void unsteady_newton_solve (const double &dt, const bool &shift_values)
 
void unsteady_newton_solve (const double &dt, const unsigned &max_adapt, const bool &first, const bool &shift=true)
 
double doubly_adaptive_unsteady_newton_solve (const double &dt, const double &epsilon, const unsigned &max_adapt, const bool &first, const bool &shift=true)
 
double doubly_adaptive_unsteady_newton_solve (const double &dt, const double &epsilon, const unsigned &max_adapt, const unsigned &suppress_resolve_after_spatial_adapt_flag, const bool &first, const bool &shift=true)
 
double adaptive_unsteady_newton_solve (const double &dt_desired, const double &epsilon)
 
double adaptive_unsteady_newton_solve (const double &dt_desired, const double &epsilon, const bool &shift_values)
 
void assign_initial_values_impulsive ()
 
void assign_initial_values_impulsive (const double &dt)
 
void calculate_predictions ()
 Calculate predictions. More...
 
void enable_mass_matrix_reuse ()
 
void disable_mass_matrix_reuse ()
 
bool mass_matrix_reuse_is_enabled ()
 Return whether the mass matrix is being reused. More...
 
void refine_uniformly (const Vector< unsigned > &nrefine_for_mesh)
 
void refine_uniformly (const Vector< unsigned > &nrefine_for_mesh, DocInfo &doc_info)
 
void refine_uniformly_and_prune (const Vector< unsigned > &nrefine_for_mesh)
 
void refine_uniformly_and_prune (const Vector< unsigned > &nrefine_for_mesh, DocInfo &doc_info)
 
void refine_uniformly (DocInfo &doc_info)
 
void refine_uniformly_and_prune (DocInfo &doc_info)
 
void refine_uniformly ()
 
void refine_uniformly (const unsigned &i_mesh, DocInfo &doc_info)
 Do uniform refinement for submesh i_mesh with documentation. More...
 
void refine_uniformly (const unsigned &i_mesh)
 Do uniform refinement for submesh i_mesh without documentation. More...
 
void p_refine_uniformly (const Vector< unsigned > &nrefine_for_mesh)
 
void p_refine_uniformly (const Vector< unsigned > &nrefine_for_mesh, DocInfo &doc_info)
 
void p_refine_uniformly_and_prune (const Vector< unsigned > &nrefine_for_mesh)
 
void p_refine_uniformly_and_prune (const Vector< unsigned > &nrefine_for_mesh, DocInfo &doc_info)
 
void p_refine_uniformly (DocInfo &doc_info)
 
void p_refine_uniformly_and_prune (DocInfo &doc_info)
 
void p_refine_uniformly ()
 
void p_refine_uniformly (const unsigned &i_mesh, DocInfo &doc_info)
 Do uniform p-refinement for submesh i_mesh with documentation. More...
 
void p_refine_uniformly (const unsigned &i_mesh)
 Do uniform p-refinement for submesh i_mesh without documentation. More...
 
void refine_selected_elements (const Vector< unsigned > &elements_to_be_refined)
 
void refine_selected_elements (const Vector< RefineableElement * > &elements_to_be_refined_pt)
 
void refine_selected_elements (const unsigned &i_mesh, const Vector< unsigned > &elements_to_be_refined)
 
void refine_selected_elements (const unsigned &i_mesh, const Vector< RefineableElement * > &elements_to_be_refined_pt)
 
void refine_selected_elements (const Vector< Vector< unsigned >> &elements_to_be_refined)
 
void refine_selected_elements (const Vector< Vector< RefineableElement * >> &elements_to_be_refined_pt)
 
void p_refine_selected_elements (const Vector< unsigned > &elements_to_be_refined)
 
void p_refine_selected_elements (const Vector< PRefineableElement * > &elements_to_be_refined_pt)
 
void p_refine_selected_elements (const unsigned &i_mesh, const Vector< unsigned > &elements_to_be_refined)
 
void p_refine_selected_elements (const unsigned &i_mesh, const Vector< PRefineableElement * > &elements_to_be_refined_pt)
 
void p_refine_selected_elements (const Vector< Vector< unsigned >> &elements_to_be_refined)
 
void p_refine_selected_elements (const Vector< Vector< PRefineableElement * >> &elements_to_be_refined_pt)
 
unsigned unrefine_uniformly ()
 
unsigned unrefine_uniformly (const unsigned &i_mesh)
 
void p_unrefine_uniformly (DocInfo &doc_info)
 
void p_unrefine_uniformly (const unsigned &i_mesh, DocInfo &doc_info)
 Do uniform p-unrefinement for submesh i_mesh without documentation. More...
 
void adapt (unsigned &n_refined, unsigned &n_unrefined)
 
void adapt ()
 
void p_adapt (unsigned &n_refined, unsigned &n_unrefined)
 
void p_adapt ()
 
void adapt_based_on_error_estimates (unsigned &n_refined, unsigned &n_unrefined, Vector< Vector< double >> &elemental_error)
 
void adapt_based_on_error_estimates (Vector< Vector< double >> &elemental_error)
 
void get_all_error_estimates (Vector< Vector< double >> &elemental_error)
 
void doc_errors (DocInfo &doc_info)
 Get max and min error for all elements in submeshes. More...
 
void doc_errors ()
 Get max and min error for all elements in submeshes. More...
 
void enable_info_in_newton_solve ()
 
void disable_info_in_newton_solve ()
 Disable the output of information when in the newton solver. More...
 
- Public Member Functions inherited from oomph::ExplicitTimeSteppableObject
 ExplicitTimeSteppableObject ()
 Empty constructor. More...
 
 ExplicitTimeSteppableObject (const ExplicitTimeSteppableObject &)=delete
 Broken copy constructor. More...
 
void operator= (const ExplicitTimeSteppableObject &)=delete
 Broken assignment operator. More...
 
virtual ~ExplicitTimeSteppableObject ()
 Empty destructor. More...
 
virtual void actions_before_explicit_stage ()
 
virtual void actions_after_explicit_stage ()
 

Public Attributes

ElasticRefineableTwoLayerMesh< ELEMENT > * Bulk_mesh_pt
 
Mesh * Surface_mesh_pt
 Storage to the mesh of Surface interface elements. More...
 
BackupMeshForProjection< QElement< 1, 3 > > * Backed_up_surface_mesh_pt
 Storage for the back up the surface mesh. More...
 
Mesh * Point_mesh_pt
 Storage to point elements if needed for non-periodic domains. More...
 
Mesh * Inlet_traction_mesh_pt
 Storage for any traction elements applied to the inlet. More...
 
Mesh * Outlet_traction_mesh_pt
 Storage for any traction elements applied to the outlet. More...
 
Mesh * Dependent_position_mesh_pt
 
ConstitutiveLaw * Constitutive_law_pt
 Pointer to the constitutive law used to determine the mesh deformation. More...
 
Mesh * Slave_position_mesh_pt
 
TwoLayerSpineMesh< ELEMENT > * Bulk_mesh_pt
 
- Public Attributes inherited from oomph::Problem
bool Shut_up_in_newton_solve
 

Private Attributes

DocInfo Doc_info
 DocInfo object. More...
 
bool Surface_pinned
 Boolean to indicate whether the surface is pinned. More...
 
Node * Monitor_node_pt
 Node used to monitor the interface height. More...
 
unsigned Periodic_index
 

Additional Inherited Members

- Public Types inherited from oomph::Problem
typedef void(* SpatialErrorEstimatorFctPt) (Mesh *&mesh_pt, Vector< double > &elemental_error)
 Function pointer for spatial error estimator. More...
 
typedef void(* SpatialErrorEstimatorWithDocFctPt) (Mesh *&mesh_pt, Vector< double > &elemental_error, DocInfo &doc_info)
 Function pointer for spatial error estimator with doc. More...
 
- Static Public Attributes inherited from oomph::Problem
static bool Suppress_warning_about_actions_before_read_unstructured_meshes
 
- Protected Types inherited from oomph::Problem
enum  Assembly_method {
  Perform_assembly_using_vectors_of_pairs , Perform_assembly_using_two_vectors , Perform_assembly_using_maps , Perform_assembly_using_lists ,
  Perform_assembly_using_two_arrays
}
 Enumerated flags to determine which sparse assembly method is used. More...
 
- Protected Member Functions inherited from oomph::Problem
unsigned setup_element_count_per_dof ()
 
virtual void sparse_assemble_row_or_column_compressed (Vector< int * > &column_or_row_index, Vector< int * > &row_or_column_start, Vector< double * > &value, Vector< unsigned > &nnz, Vector< double * > &residual, bool compressed_row_flag)
 
virtual void actions_before_newton_step ()
 
virtual void actions_after_newton_step ()
 
virtual void actions_after_implicit_timestep ()
 
virtual void actions_after_implicit_timestep_and_error_estimation ()
 
virtual void actions_before_explicit_timestep ()
 Actions that should be performed before each explicit time step. More...
 
virtual void actions_after_explicit_timestep ()
 Actions that should be performed after each explicit time step. More...
 
virtual void actions_before_read_unstructured_meshes ()
 
virtual void actions_after_read_unstructured_meshes ()
 
virtual void actions_after_change_in_global_parameter (double *const &parameter_pt)
 
virtual void actions_after_change_in_bifurcation_parameter ()
 
virtual void actions_after_parameter_increase (double *const &parameter_pt)
 
double & dof_derivative (const unsigned &i)
 
double & dof_current (const unsigned &i)
 
virtual void set_initial_condition ()
 
unsigned newton_solve_continuation (double *const &parameter_pt)
 
unsigned newton_solve_continuation (double *const &parameter_pt, DoubleVector &z)
 
void calculate_continuation_derivatives (double *const &parameter_pt)
 
void calculate_continuation_derivatives (const DoubleVector &z)
 
void calculate_continuation_derivatives_fd (double *const &parameter_pt)
 
bool does_pointer_correspond_to_problem_data (double *const &parameter_pt)
 
void set_consistent_pinned_values_for_continuation ()
 
- Protected Attributes inherited from oomph::Problem
Vector< Problem * > Copy_of_problem_pt
 
std::map< double *, bool > Calculate_dparameter_analytic
 
bool Calculate_hessian_products_analytic
 
LinearAlgebraDistribution * Dof_distribution_pt
 
Vector< double * > Dof_pt
 Vector of pointers to dofs. More...
 
DoubleVectorWithHaloEntries Element_count_per_dof
 
double Relaxation_factor
 
double Newton_solver_tolerance
 
unsigned Max_newton_iterations
 Maximum number of Newton iterations. More...
 
unsigned Nnewton_iter_taken
 
Vector< double > Max_res
 Maximum residuals at start and after each newton iteration. More...
 
double Max_residuals
 
bool Time_adaptive_newton_crash_on_solve_fail
 
bool Jacobian_reuse_is_enabled
 Is re-use of Jacobian in Newton iteration enabled? Default: false. More...
 
bool Jacobian_has_been_computed
 
bool Problem_is_nonlinear
 
bool Pause_at_end_of_sparse_assembly
 
bool Doc_time_in_distribute
 
unsigned Sparse_assembly_method
 
unsigned Sparse_assemble_with_arrays_initial_allocation
 
unsigned Sparse_assemble_with_arrays_allocation_increment
 
Vector< Vector< unsigned > > Sparse_assemble_with_arrays_previous_allocation
 
double Numerical_zero_for_sparse_assembly
 
double FD_step_used_in_get_hessian_vector_products
 
bool Mass_matrix_reuse_is_enabled
 
bool Mass_matrix_has_been_computed
 
bool Discontinuous_element_formulation
 
double Minimum_dt
 Minimum desired dt: if dt falls below this value, exit. More...
 
double Maximum_dt
 Maximum desired dt. More...
 
double DTSF_max_increase
 
double DTSF_min_decrease
 
double Minimum_dt_but_still_proceed
 
bool Scale_arc_length
 Boolean to control whether arc-length should be scaled. More...
 
double Desired_proportion_of_arc_length
 Proportion of the arc-length to taken by the parameter. More...
 
double Theta_squared
 
int Sign_of_jacobian
 Storage for the sign of the global Jacobian. More...
 
double Continuation_direction
 
double Parameter_derivative
 Storage for the derivative of the global parameter wrt arc-length. More...
 
double Parameter_current
 Storage for the present value of the global parameter. More...
 
bool Use_continuation_timestepper
 Boolean to control original or new storage of dof stuff. More...
 
unsigned Dof_derivative_offset
 
unsigned Dof_current_offset
 
Vector< double > Dof_derivative
 Storage for the derivative of the problem variables wrt arc-length. More...
 
Vector< double > Dof_current
 Storage for the present values of the variables. More...
 
double Ds_current
 Storage for the current step value. More...
 
unsigned Desired_newton_iterations_ds
 
double Minimum_ds
 Minimum desired value of arc-length. More...
 
bool Bifurcation_detection
 Boolean to control bifurcation detection via determinant of Jacobian. More...
 
bool Bisect_to_find_bifurcation
 Boolean to control wheter bisection is used to located bifurcation. More...
 
bool First_jacobian_sign_change
 Boolean to indicate whether a sign change has occured in the Jacobian. More...
 
bool Arc_length_step_taken
 Boolean to indicate whether an arc-length step has been taken. More...
 
bool Use_finite_differences_for_continuation_derivatives
 
OomphCommunicator * Communicator_pt
 The communicator for this problem. More...
 
bool Always_take_one_newton_step
 
double Timestep_reduction_factor_after_nonconvergence
 
bool Keep_temporal_error_below_tolerance
 
- Static Protected Attributes inherited from oomph::Problem
static ContinuationStorageScheme Continuation_time_stepper
 Storage for the single static continuation timestorage object. More...
 

Detailed Description

template<class ELEMENT, class INTERFACE_ELEMENT>
class SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >

/////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////// 2D surfactant transport problem on rectangular domain, discretised with spine elements. The specific type of element is specified via the template parameter.

Constructor & Destructor Documentation

◆ SurfactantProblem() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem ( const bool &  pin = true)

Constructor. The boolean indicates whether the free surface.

Constructor for convection problem.

1383  : Surface_pinned(pin), Periodic_index(50)
1384 {
1385  //Allocate an (adaptive) timestepper
1386  add_time_stepper_pt(new BDF<2>(true));
1387  //Don't worry if the estimated error is above the tolerance
1389 
1390  // Set output directory
1391  Doc_info.set_directory("RESLT");
1392 
1393  // # of elements in x-direction (Coarse)
1394  unsigned n_x=20;//100;
1395 
1396  // # of elements in y-direction
1397  unsigned n_y1=4;//8;
1398 
1399  unsigned n_y2=4;//8;
1400 
1401  //Domain length in x direction
1402  double lx = 2.0*Global_Physical_Variables::L;
1403 
1404  // Domain length in y-direction
1406  double h2=1.0 - h1;
1407 
1408  // Build a standard rectangular quadmesh
1409  Bulk_mesh_pt =
1410  new ElasticRefineableTwoLayerMesh<ELEMENT>(n_x,n_y1,n_y2,lx,h1,h2,
1412  time_stepper_pt());
1413 
1414  // Create and set the error estimator for spatial adaptivity
1415  Bulk_mesh_pt->spatial_error_estimator_pt() = new Z2ErrorEstimator;
1416 
1417  // Set the maximum refinement level for the mesh to 4
1418  Bulk_mesh_pt->max_refinement_level() = 4;
1419 
1420 
1421  // Define a constitutive law for the solid equations: generalised Hookean
1423 
1424  // Complete the build of all elements so they are fully functional
1425 
1426  // Determine number of bulk elements in lower/upper fluids
1427  const unsigned n_lower = Bulk_mesh_pt->nlower();
1428  const unsigned n_upper = Bulk_mesh_pt->nupper();
1429 
1430  // Loop over bulk elements in lower fluid
1431  for(unsigned e=0;e<n_lower;e++)
1432  {
1433  // Upcast from GeneralisedElement to the present element
1434  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
1435  lower_layer_element_pt(e));
1436 
1437  // Set the diffusivities number
1438  el_pt->diff_pt() = &Global_Physical_Variables::D;
1439 
1440  // Set the timescales
1441  el_pt->tau_pt() =&Global_Physical_Variables::Tau;
1442 
1443  // Set the Reynolds number
1444  el_pt->re_pt() = &Global_Physical_Variables::Re;
1445 
1446  // Set the Womersley number
1447  el_pt->re_st_pt() = &Global_Physical_Variables::Re;
1448 
1449  // Set the product of the Reynolds number and the inverse of the
1450  // Froude number
1451  el_pt->re_invfr_pt() = &Global_Physical_Variables::ReInvFr;
1452 
1453  // Set the km parameter
1454  el_pt->km_pt() = &Global_Physical_Variables::K_m;
1455 
1456  // Set the N parameter
1457  el_pt->n_pt() = &Global_Physical_Variables::N;
1458 
1459 
1460  // Set the direction of gravity
1462 
1463  // Set the constitutive law
1464  el_pt->constitutive_law_pt() = this->Constitutive_law_pt;
1465 
1466  } // End of loop over bulk elements in lower fluid
1467 
1468  // Loop over bulk elements in upper fluid
1469  for(unsigned e=0;e<n_upper;e++)
1470  {
1471  // Upcast from GeneralisedElement to the present element
1472  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
1473  upper_layer_element_pt(e));
1474 
1475  // Set the diffusivities number
1476  el_pt->diff_pt() = &Global_Physical_Variables::D;
1477 
1478  // Set the timescales
1479  el_pt->tau_pt() =&Global_Physical_Variables::Tau;
1480 
1481  // Set the Reynolds number
1482  el_pt->re_pt() = &Global_Physical_Variables::Re;
1483 
1484  // Set the Womersley number
1485  el_pt->re_st_pt() = &Global_Physical_Variables::Re;
1486 
1487  // Set the product of the Reynolds number and the inverse of the
1488  // Froude number
1489  el_pt->re_invfr_pt() = &Global_Physical_Variables::ReInvFr;
1490 
1491  // Set the viscosity ratio
1492  el_pt->viscosity_ratio_pt() = &Global_Physical_Variables::M;
1493 
1494  // Set the density ratio
1495  el_pt->density_ratio_pt() = &Global_Physical_Variables::R;
1496 
1497  // Set the km parameter
1498  el_pt->km_pt() = &Global_Physical_Variables::K_m;
1499 
1500  // Set the N parameter
1501  el_pt->n_pt() = &Global_Physical_Variables::N;
1502 
1503  // Set the direction of gravity
1505 
1506  // Set the constitutive law
1507  el_pt->constitutive_law_pt() = Constitutive_law_pt;
1508 
1509 
1510  //Need to pin the values of concentration and micelle up here
1511  unsigned n_el_node = el_pt->nnode();
1512  for(unsigned n=0;n<n_el_node;++n)
1513  {
1514  el_pt->node_pt(n)->set_value(2,0.0);
1515  el_pt->node_pt(n)->set_value(3,0.0);
1516  el_pt->node_pt(n)->pin(2);
1517  el_pt->node_pt(n)->pin(3);
1518  }
1519 
1520  } // End of loop over bulk elements in upper fluid
1521 
1522 
1523  //Create the surface mesh that will contain the interface elements
1524  //First create storage, but with no elements or nodes
1525  Surface_mesh_pt = new Mesh;
1526  //Make point elements at the end to compensate for
1527  //the unbalanced line tension terms
1528  //if we DON'T have periodic boundaryc conditions
1530  {
1531  Point_mesh_pt = new Mesh;
1532  }
1533 
1534 
1535  //Must be done *after* the physical parameters have been set
1536  //because we are using the viscosity ratio pointer to determine
1537  //upper or lower elements
1539  //Setup the monitor node
1540  {
1541  unsigned n_surface_element = Surface_mesh_pt->nelement();
1542 
1543  Monitor_node_pt = Surface_mesh_pt->finite_element_pt(n_surface_element/2)->node_pt(1);
1544  }
1545 
1547  {
1549  //Create the dependent elements that ensure that the positions match
1551  }
1552 
1553  // Add the two sub-meshes to the problem
1557  {
1561  }
1562  else
1563  {
1565  }
1566 
1567  // Combine all sub-meshes into a single mesh
1569 
1570 
1571  //Pin the positions of all nodes and the Lagrange multipliers if the surface is pinned
1572  if(Surface_pinned)
1573  {
1574  unsigned n_node = Bulk_mesh_pt->nnode();
1575  for(unsigned n=0;n<n_node;n++)
1576  {
1577  SolidNode* nod_pt = Bulk_mesh_pt->node_pt(n);
1578  nod_pt->pin_position(0);
1579  nod_pt->pin_position(1);
1580  //Don't forget to pin the Lagrange multipliers as well
1581  if(nod_pt->is_on_boundary(4))
1582  {
1583  //Lagrange multiplier is always value 5
1584  unsigned lagrange_multiplier_index = 5;
1585  nod_pt->pin(lagrange_multiplier_index);
1586  }
1587  }
1588  }
1589 
1590  // Set the boundary conditions for this problem: All nodes are
1591  // free by default -- only need to pin the ones that have Dirichlet
1592  // conditions here
1593 
1594  //Loop over the boundaries
1595  unsigned num_bound = Bulk_mesh_pt->nboundary();
1596  for(unsigned ibound=0;ibound<num_bound;ibound++)
1597  {
1598  //If we are on the side-walls, the concentrations
1599  //satisfy natural boundary conditions, so we only pin the
1600  //v-velocity for now if not periodic
1602  {
1603  if((ibound==1) || (ibound==3))
1604  {
1605  //Loop over the number of nodes on the boundary
1606  unsigned num_nod= Bulk_mesh_pt->nboundary_node(ibound);
1607  for(unsigned inod=0;inod<num_nod;inod++)
1608  {
1609  //Cast to a solid node, so that we can impose boundary conditions
1610  SolidNode* nod_pt = static_cast<SolidNode*>(
1611  Bulk_mesh_pt->boundary_node_pt(ibound,inod));
1612  nod_pt->pin(1);
1613  //Also pin the horizontal displacement of the nodes
1614  nod_pt->pin_position(0);
1615 
1616  /*if((ibound==4) || (ibound==5))
1617  {
1618  Bulk_mesh_pt->boundary_node_pt(ibound,inod)->pin(0);
1619  }*/
1620  }
1621  }
1622  }
1623 
1624  //If we on the top or bottom wall, velocity is pinned
1625  //as is the nodal position
1626  if((ibound==0) || (ibound==2))
1627  {
1628  //Loop over the number of nodes on the boundary
1629  unsigned num_nod= Bulk_mesh_pt->nboundary_node(ibound);
1630  for(unsigned inod=0;inod<num_nod;inod++)
1631  {
1632  SolidNode* nod_pt = static_cast<SolidNode*>(Bulk_mesh_pt->boundary_node_pt(ibound,inod));
1633  nod_pt->pin(0);
1634  nod_pt->pin(1);
1635  nod_pt->pin_position(0);
1636  nod_pt->pin_position(1);
1637  }
1638  }
1639  }
1640 
1641 
1642  //Pin the zero-th pressure dof in element 0 and set its value to
1643  //zero:
1644  fix_pressure(0,0,0.0);
1645 
1646 
1647  // Loop over the interface elements to set up element-specific
1648  // things that cannot be handled by the (argument-free!) ELEMENT
1649  // constructor.
1650  unsigned n_interface = Surface_mesh_pt->nelement();
1651  for(unsigned i=0;i<n_interface;i++)
1652  {
1653  // Upcast from GeneralsedElement to the present element
1654  INTERFACE_ELEMENT *el_pt = dynamic_cast<INTERFACE_ELEMENT*>(
1656 
1657  //Need to unpin the values of concentration and micelle on the interface
1658  unsigned n_el_node = el_pt->nnode();
1659  for(unsigned n=0;n<n_el_node;++n)
1660  {
1661  el_pt->node_pt(n)->unpin(2); //unpin
1662  el_pt->node_pt(n)->unpin(3); //unpin
1663  el_pt->node_pt(n)->pin(4); //Pin Lagrange Multiplier initially
1664  }
1665 
1666  }
1667 
1668  //Pin all bulk concentrations ... to save
1669  //time and to avoid having to conserve global mass
1670  unsigned n_node = Bulk_mesh_pt->nnode();
1671  for(unsigned n=0;n<n_node;++n)
1672  {
1673  SolidNode* nod_pt = static_cast<SolidNode*>(Bulk_mesh_pt->node_pt(n));
1674  //Pin x position
1675  nod_pt->pin_position(0);
1676  nod_pt->pin_position(1);
1677  nod_pt->pin(2);
1678  nod_pt->pin(3);
1679  double y = nod_pt->x(1);
1680  nod_pt->set_value(0,y);
1681  nod_pt->set_value(1,0.0);
1682  }
1683 
1684  //We initialise need to pin the lagrange multipliers
1685  //associated with periodic boundary conditions on the side boundary
1686  {
1687  unsigned b=3;
1688  unsigned n_boundary_node = this->Bulk_mesh_pt->nboundary_node(b);
1689  for(unsigned n=0;n<n_boundary_node;++n)
1690  {
1691  Node* nod_pt = this->Bulk_mesh_pt->boundary_node_pt(b,n);
1692  if(!(nod_pt->is_on_boundary(0)) &&
1693  !(nod_pt->is_on_boundary(2)) &&
1694  !(nod_pt->is_on_boundary(4)))
1695  {
1696  //Pin all
1697  nod_pt->pin(dynamic_cast<BoundaryNodeBase*>(nod_pt)
1699  Periodic_index));
1700  }
1701  }
1702  }
1703 
1704 
1705  //Pin one surface concentration at the surface, if only
1706  //solving for insoluble surfactant
1707  //Surface_mesh_pt->finite_element_pt(0)->node_pt(1)->pin(4);
1708 
1709  // Setup equation numbering scheme
1710  cout <<"Number of equations: " << assign_eqn_numbers() << endl;
1711 
1712 } // end of constructor
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
@ R
Definition: StatisticsVector.h:21
Scalar * b
Definition: benchVecAdd.cpp:17
Definition: elastic_two_layer_interface_axisym.cc:108
bool Surface_pinned
Boolean to indicate whether the surface is pinned.
Definition: refineable_two_layer_soluble_surfactant.cc:1366
ConstitutiveLaw * Constitutive_law_pt
Pointer to the constitutive law used to determine the mesh deformation.
Definition: refineable_two_layer_soluble_surfactant.cc:1206
Mesh * Dependent_position_mesh_pt
Definition: refineable_two_layer_soluble_surfactant.cc:1203
unsigned Periodic_index
Definition: refineable_two_layer_soluble_surfactant.cc:1373
void fix_pressure(const unsigned &e, const unsigned &pdof, const double &pvalue)
Fix pressure in element e at pressure dof pdof and set to pvalue.
Definition: refineable_two_layer_soluble_surfactant.cc:1122
ElasticRefineableTwoLayerMesh< ELEMENT > * Bulk_mesh_pt
Definition: refineable_two_layer_soluble_surfactant.cc:1184
DocInfo Doc_info
DocInfo object.
Definition: refineable_two_layer_soluble_surfactant.cc:1363
void create_dependent_position_elements()
Create the elements that make the position consistent on both sides.
Definition: refineable_two_layer_soluble_surfactant.cc:956
void create_interface_elements()
Create the 1d interface elements.
Definition: refineable_two_layer_soluble_surfactant.cc:1011
Node * Monitor_node_pt
Node used to monitor the interface height.
Definition: refineable_two_layer_soluble_surfactant.cc:1369
Mesh * Surface_mesh_pt
Storage to the mesh of Surface interface elements.
Definition: refineable_two_layer_soluble_surfactant.cc:1187
Mesh * Inlet_traction_mesh_pt
Storage for any traction elements applied to the inlet.
Definition: refineable_two_layer_soluble_surfactant.cc:1196
Mesh * Outlet_traction_mesh_pt
Storage for any traction elements applied to the outlet.
Definition: refineable_two_layer_soluble_surfactant.cc:1199
Mesh * Point_mesh_pt
Storage to point elements if needed for non-periodic domains.
Definition: refineable_two_layer_soluble_surfactant.cc:1193
Definition: nodes.h:1996
unsigned index_of_first_value_assigned_by_face_element(const unsigned &face_id=0) const
Definition: nodes.h:2061
void pin(const unsigned &i)
Pin the i-th stored variable.
Definition: nodes.h:385
void set_value(const unsigned &i, const double &value_)
Definition: nodes.h:271
void set_directory(const std::string &directory)
Definition: oomph_utilities.cc:298
Node *& node_pt(const unsigned &n)
Return a pointer to the local node n.
Definition: elements.h:2175
Definition: constitutive_laws.h:699
Definition: mesh.h:67
FiniteElement * finite_element_pt(const unsigned &e) const
Definition: mesh.h:473
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Definition: mesh.h:448
unsigned long nelement() const
Return number of elements in the mesh.
Definition: mesh.h:590
Definition: nodes.h:906
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
virtual bool is_on_boundary() const
Definition: nodes.h:1373
void add_time_stepper_pt(TimeStepper *const &time_stepper_pt)
Definition: problem.cc:1545
unsigned add_sub_mesh(Mesh *const &mesh_pt)
Definition: problem.h:1330
void build_global_mesh()
Definition: problem.cc:1493
bool Keep_temporal_error_below_tolerance
Definition: problem.h:2209
unsigned long assign_eqn_numbers(const bool &assign_local_eqn_numbers=true)
Definition: problem.cc:1989
TimeStepper *& time_stepper_pt()
Definition: problem.h:1524
Definition: nodes.h:1686
void pin_position(const unsigned &i)
Pin the nodal position.
Definition: nodes.h:1816
Definition: error_estimator.h:266
@ N
Definition: constructor.cpp:22
Scalar * y
Definition: level1_cplx_impl.h:128
Vector< double > D(2, 1.0)
Diffusivity (identically one from our non-dimensionalisation)
double L
Length of beam.
Definition: adaptive_pitchfork.cc:51
double Nu
Poisson's ratio.
Definition: TwenteMeshGluing.cpp:71
Vector< double > Direction_of_gravity(2)
Gravity vector.
double Tau
Shear stress (for steady Poiseuille flow)
Definition: linearised_fsi_pulsewave.cc:142
double ReInvFr
Product of Reynolds number and inverse of Froude number.
Definition: fibre.cc:58
double Re
Reynolds number.
Definition: fibre.cc:55
const double lx
Definition: ConstraintElementsUnitTest.cpp:33
bool Periodic_BCs
Definition: refineable_two_layer_soluble_surfactant.cc:70
double H0
Definition: refineable_two_layer_soluble_surfactant.cc:97
double M
Definition: refineable_two_layer_soluble_surfactant.cc:94
double K_m
Definition: refineable_two_layer_soluble_surfactant.cc:154

References oomph::Problem::add_sub_mesh(), oomph::Problem::add_time_stepper_pt(), oomph::Problem::assign_eqn_numbers(), b, oomph::Problem::build_global_mesh(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Bulk_mesh_pt, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Constitutive_law_pt, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::create_dependent_position_elements(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::create_interface_elements(), Global_Physical_Variables::D, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Dependent_position_mesh_pt, Global_Physical_Variables::Direction_of_gravity, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Doc_info, e(), oomph::Mesh::element_pt(), oomph::Mesh::finite_element_pt(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::fix_pressure(), oomph::Global_Physical_Variables::H0, i, oomph::BoundaryNodeBase::index_of_first_value_assigned_by_face_element(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Inlet_traction_mesh_pt, oomph::Node::is_on_boundary(), oomph::Global_Physical_Variables::K_m, oomph::Problem::Keep_temporal_error_below_tolerance, Global_Physical_Variables::L, Mesh_Parameters::lx, oomph::Global_Physical_Variables::M, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Monitor_node_pt, n, N, oomph::Mesh::nelement(), oomph::FiniteElement::node_pt(), Global_Physical_Variables::Nu, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Outlet_traction_mesh_pt, oomph::Control_Parameters::Periodic_BCs, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Periodic_index, oomph::Data::pin(), oomph::SolidNode::pin_position(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Point_mesh_pt, R, Global_Physical_Variables::Re, Global_Physical_Variables::ReInvFr, oomph::DocInfo::set_directory(), oomph::Data::set_value(), SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Surface_mesh_pt, SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Surface_pinned, Global_Physical_Variables::Tau, oomph::Problem::time_stepper_pt(), oomph::Node::x(), and y.

◆ ~SurfactantProblem() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::~SurfactantProblem ( )
inline

Destructor. Empty.

655 {}

◆ SurfactantProblem() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem ( const bool &  pin = true)

Constructor. The boolean indicates whether the free surface.

◆ ~SurfactantProblem() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::~SurfactantProblem ( )
inline

Destructor. Empty.

652 {}

◆ SurfactantProblem() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem ( const bool &  pin = true)

Constructor. The boolean indicates whether the free surface.

◆ ~SurfactantProblem() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::~SurfactantProblem ( )
inline

Destructor. Empty.

272 {}

Member Function Documentation

◆ actions_after_adapt() [1/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_after_adapt ( )
inlinevirtual

Rebuild the mesh of interface elements after adapting the bulk mesh.

Reimplemented from oomph::Problem.

818  {
819  //Need to update the pointers to upper and lower elements
820  this->Bulk_mesh_pt->setup_upper_and_lower_elements();
821 
822  // Create the interface elements
824 
825  //Now we need to make sure that we set up the correct insoluble surfactant
826  //concentration
827  //We do this by interpolating from the previous mesh
828 
829  // Now project from backup of original contact mesh to new one
831  Surface_mesh_pt);
832  //Now delete the backed up mesh
835 
837  {
838  //Create the dependent position elements
840  }
841 
842  // Rebuild the Problem's global mesh from its various sub-meshes
843  this->rebuild_global_mesh();
844 
845  // Pin horizontal displacement of all nodes
846  const unsigned n_node = Bulk_mesh_pt->nnode();
847  for(unsigned n=0;n<n_node;n++) {Bulk_mesh_pt->node_pt(n)->pin_position(0); }
848 
849  // Determine number of bulk elements in lower/upper fluids
850  const unsigned n_lower = Bulk_mesh_pt->nlower();
851  const unsigned n_upper = Bulk_mesh_pt->nupper();
852 
853  // Loop over bulk elements in upper fluid
854  for(unsigned e=0;e<n_upper;e++)
855  {
856  // Upcast from GeneralisedElement to the present element
857  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
858  upper_layer_element_pt(e));
859 
860 
861  //Need to pin the values of concentration and micelle up here
862  unsigned n_el_node = el_pt->nnode();
863  for(unsigned n=0;n<n_el_node;++n)
864  {
865  Node* const nod_pt = el_pt->node_pt(n);
866  if(nod_pt->is_on_boundary(4) == false)
867  {
868  //Set all the history values to zero as well
869  unsigned nprev_values = nod_pt->time_stepper_pt()->nprev_values();
870  for(unsigned t=0;t<=nprev_values;++t)
871  {
872  nod_pt->set_value(t,2,0.0);
873  nod_pt->set_value(t,3,0.0);
874  }
875 
876  nod_pt->pin(2);
877  nod_pt->pin(3);
878  }
879  }
880  } // End of loop over bulk elements in upper fluid
881 
882 
883  // Loop over bulk elements in lower fluid and unpin
884  for(unsigned e=0;e<n_lower;e++)
885  {
886  // Upcast from GeneralisedElement to the present element
887  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
888  lower_layer_element_pt(e));
889 
890 
891  //No need to pin the values of concentration and micelle down here
892  //But don't unpin if they are hanging
893  unsigned n_el_node = el_pt->nnode();
894  for(unsigned n=0;n<n_el_node;++n)
895  {
896  Node* const nod_pt = el_pt->node_pt(n);
897  if(!(nod_pt->is_constrained(2))) {nod_pt->unpin(2);}
898  if(!(nod_pt->is_constrained(3))) {nod_pt->unpin(3);}
899  }
900  }
901 
902  // Set the boundary conditions for this problem: All nodes are
903  // free by default -- only need to pin the ones that have Dirichlet
904  // conditions here
905 
906  //Loop over the boundaries
907  unsigned num_bound = Bulk_mesh_pt->nboundary();
908  for(unsigned ibound=0;ibound<num_bound;ibound++)
909  {
910  //If we are on the side-walls, the concentrations
911  //satisfy natural boundary conditions, so we only pin the
912  //v-velocity for now if not periodic
914  {
915  if((ibound==1) || (ibound==3))
916  {
917  //Loop over the number of nodes on the boundary
918  unsigned num_nod= Bulk_mesh_pt->nboundary_node(ibound);
919  for(unsigned inod=0;inod<num_nod;inod++)
920  {
921  //Cast to a solid node, so that we can impose boundary conditions
922  SolidNode* nod_pt = static_cast<SolidNode*>(
923  Bulk_mesh_pt->boundary_node_pt(ibound,inod));
924  nod_pt->pin(1);
925  //Also pin the horizontal displacement of the nodes
926  nod_pt->pin_position(0);
927  }
928  }
929  }
930 
931  //If we on the top or bottom wall, velocity is pinned
932  //as is the nodal position
933  if((ibound==0) || (ibound==2))
934  {
935  //Loop over the number of nodes on the boundary
936  unsigned num_nod= Bulk_mesh_pt->nboundary_node(ibound);
937  for(unsigned inod=0;inod<num_nod;inod++)
938  {
939  SolidNode* nod_pt = static_cast<SolidNode*>(Bulk_mesh_pt->boundary_node_pt(ibound,inod));
940  nod_pt->pin(0);
941  nod_pt->pin(1);
942  nod_pt->pin_position(0);
943  nod_pt->pin_position(1);
944  }
945  }
946  }
947 
948  // Now set the pressure in the first element at 'node' 0 to 0.0
949  fix_pressure(0,0,0.0);
950 
951  // Reset the boundary conditions
953  }
void set_boundary_conditions(const double &time)
Set the boundary conditions.
Definition: refineable_two_layer_soluble_surfactant.cc:1721
BackupMeshForProjection< QElement< 1, 3 > > * Backed_up_surface_mesh_pt
Storage for the back up the surface mesh.
Definition: refineable_two_layer_soluble_surfactant.cc:1190
void project_onto_new_mesh(Mesh *new_mesh_pt)
Definition: face_mesh_project.h:394
void unpin(const unsigned &i)
Unpin the i-th stored variable.
Definition: nodes.h:391
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:238
bool is_constrained(const unsigned &i)
Definition: nodes.h:472
void rebuild_global_mesh()
Definition: problem.cc:1533
Time *& time_pt()
Return a pointer to the global time object.
Definition: problem.h:1504
double & time()
Return the current value of continuous time.
Definition: problem.cc:11531
virtual unsigned nprev_values() const =0
Number of previous values available: 0 for static, 1 for BDF<1>,...
t
Definition: plotPSD.py:36

References e(), oomph::Data::is_constrained(), oomph::Node::is_on_boundary(), n, oomph::TimeStepper::nprev_values(), oomph::Control_Parameters::Periodic_BCs, oomph::Data::pin(), oomph::SolidNode::pin_position(), oomph::Data::set_value(), plotPSD::t, oomph::Data::time_stepper_pt(), and oomph::Data::unpin().

◆ actions_after_adapt() [2/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_after_adapt ( )
inlinevirtual

Rebuild the mesh of interface elements after adapting the bulk mesh.

Reimplemented from oomph::Problem.

816  {
817  //Need to update the pointers to upper and lower elements
818  this->Bulk_mesh_pt->setup_upper_and_lower_elements();
819 
820  // Create the interface elements
822 
823  //Now we need to make sure that we set up the correct insoluble surfactant
824  //concentration
825  //We do this by interpolating from the previous mesh
826 
827  // Now project from backup of original contact mesh to new one
829  Surface_mesh_pt);
830  //Now delete the backed up mesh
833 
835  {
836  //Create the slave position elements
838  }
839 
840  // Rebuild the Problem's global mesh from its various sub-meshes
841  this->rebuild_global_mesh();
842 
843  // Pin horizontal displacement of all nodes
844  const unsigned n_node = Bulk_mesh_pt->nnode();
845  for(unsigned n=0;n<n_node;n++) {Bulk_mesh_pt->node_pt(n)->pin_position(0); }
846 
847  // Determine number of bulk elements in lower/upper fluids
848  const unsigned n_lower = Bulk_mesh_pt->nlower();
849  const unsigned n_upper = Bulk_mesh_pt->nupper();
850 
851  // Loop over bulk elements in upper fluid
852  for(unsigned e=0;e<n_upper;e++)
853  {
854  // Upcast from GeneralisedElement to the present element
855  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
856  upper_layer_element_pt(e));
857 
858 
859  //Need to pin the values of concentration and micelle up here
860  unsigned n_el_node = el_pt->nnode();
861  for(unsigned n=0;n<n_el_node;++n)
862  {
863  Node* const nod_pt = el_pt->node_pt(n);
864  if(nod_pt->is_on_boundary(4) == false)
865  {
866  //Set all the history values to zero as well
867  unsigned nprev_values = nod_pt->time_stepper_pt()->nprev_values();
868  for(unsigned t=0;t<=nprev_values;++t)
869  {
870  nod_pt->set_value(t,2,0.0);
871  nod_pt->set_value(t,3,0.0);
872  }
873 
874  nod_pt->pin(2);
875  nod_pt->pin(3);
876  }
877  }
878  } // End of loop over bulk elements in upper fluid
879 
880 
881  // Loop over bulk elements in lower fluid and unpin
882  for(unsigned e=0;e<n_lower;e++)
883  {
884  // Upcast from GeneralisedElement to the present element
885  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
886  lower_layer_element_pt(e));
887 
888 
889  //No need to pin the values of concentration and micelle down here
890  //But don't unpin if they are hanging
891  unsigned n_el_node = el_pt->nnode();
892  for(unsigned n=0;n<n_el_node;++n)
893  {
894  Node* const nod_pt = el_pt->node_pt(n);
895  if(!(nod_pt->is_constrained(2))) {nod_pt->unpin(2);}
896  if(!(nod_pt->is_constrained(3))) {nod_pt->pin(3);}
897  //{nod_pt->unpin(3);}
898  }
899  }
900 
901  // Set the boundary conditions for this problem: All nodes are
902  // free by default -- only need to pin the ones that have Dirichlet
903  // conditions here
904 
905  //Loop over the boundaries
906  unsigned num_bound = Bulk_mesh_pt->nboundary();
907  for(unsigned ibound=0;ibound<num_bound;ibound++)
908  {
909  //If we are on the side-walls, the concentrations
910  //satisfy natural boundary conditions, so we only pin the
911  //v-velocity for now if not periodic
913  {
914  if((ibound==1) || (ibound==3))
915  {
916  //Loop over the number of nodes on the boundary
917  unsigned num_nod= Bulk_mesh_pt->nboundary_node(ibound);
918  for(unsigned inod=0;inod<num_nod;inod++)
919  {
920  //Cast to a solid node, so that we can impose boundary conditions
921  SolidNode* nod_pt = static_cast<SolidNode*>(
922  Bulk_mesh_pt->boundary_node_pt(ibound,inod));
923  nod_pt->pin(1);
924  //Also pin the horizontal displacement of the nodes
925  nod_pt->pin_position(0);
926  }
927  }
928  }
929 
930  //If we on the top or bottom wall, velocity is pinned
931  //as is the nodal position
932  if((ibound==0) || (ibound==2))
933  {
934  //Loop over the number of nodes on the boundary
935  unsigned num_nod= Bulk_mesh_pt->nboundary_node(ibound);
936  for(unsigned inod=0;inod<num_nod;inod++)
937  {
938  SolidNode* nod_pt = static_cast<SolidNode*>(Bulk_mesh_pt->boundary_node_pt(ibound,inod));
939  nod_pt->pin(0);
940  nod_pt->pin(1);
941  nod_pt->pin_position(0);
942  nod_pt->pin_position(1);
943  }
944  }
945  }
946 
947  // Now set the pressure in the first element at 'node' 0 to 0.0
948  fix_pressure(0,0,0.0);
949 
950  // Reset the boundary conditions
952  }
void create_slave_position_elements()
Create the elements that slave the position.
Definition: refineable_unstructured_two_layer_ss.cc:955

References e(), oomph::Data::is_constrained(), oomph::Node::is_on_boundary(), n, oomph::TimeStepper::nprev_values(), oomph::Control_Parameters::Periodic_BCs, oomph::Data::pin(), oomph::SolidNode::pin_position(), oomph::Data::set_value(), plotPSD::t, oomph::Data::time_stepper_pt(), and oomph::Data::unpin().

◆ actions_after_newton_solve() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_after_newton_solve ( )
inlinevirtual

Update the problem after solve (empty)

Reimplemented from oomph::Problem.

756 {}

◆ actions_after_newton_solve() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_after_newton_solve ( )
inlinevirtual

Update the problem after solve (empty)

Reimplemented from oomph::Problem.

754 {}

◆ actions_after_newton_solve() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_after_newton_solve ( )
inlinevirtual

Update the problem after solve (empty)

Reimplemented from oomph::Problem.

358 {}

◆ actions_before_adapt() [1/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_adapt ( )
inlinevirtual

Strip off the interface elements before adapting the bulk mesh.

Reimplemented from oomph::Problem.

795  {
796  //Unfix the pressure to avoid double fixing
797  this->unfix_pressure(0,0);
798 
800  {
801  //Delete the dependent elements and wipe the mesh
803  }
804 
805  //Backup the surface mesh
808 
809  // Delete the interface elements and wipe the surface mesh
811 
812  // Rebuild the Problem's global mesh from its various sub-meshes
814  }
void unfix_pressure(const unsigned &e, const unsigned &pdof)
UnFix pressure in element e at pressure dof pdof and set to pvalue.
Definition: refineable_two_layer_soluble_surfactant.cc:1132
void delete_interface_elements()
Delete the 1d interface elements.
Definition: refineable_two_layer_soluble_surfactant.cc:1105
void delete_dependent_position_elements()
Delete the 1d interface elements.
Definition: refineable_two_layer_soluble_surfactant.cc:994
Definition: face_mesh_project.h:223

References oomph::Control_Parameters::Periodic_BCs.

◆ actions_before_adapt() [2/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_adapt ( )
inlinevirtual

Strip off the interface elements before adapting the bulk mesh.

Reimplemented from oomph::Problem.

793  {
794  //Unfix the pressure to avoid double fixing
795  this->unfix_pressure(0,0);
796 
798  {
799  //Delete the slave elements and wipe the mesh
801  }
802 
803  //Backup the surface mesh
806 
807  // Delete the interface elements and wipe the surface mesh
809 
810  // Rebuild the Problem's global mesh from its various sub-meshes
812  }
void delete_slave_position_elements()
Delete the 1d interface elements.
Definition: refineable_unstructured_two_layer_ss.cc:991

References oomph::Control_Parameters::Periodic_BCs.

◆ actions_before_implicit_timestep() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_implicit_timestep ( )
inlinevirtual

Actions before the timestep (update the the time-dependent boundary conditions)

Reimplemented from oomph::Problem.

764  {
766  Bulk_mesh_pt->set_lagrangian_nodal_coordinates();
767  //Also set lagrange multipliers to zero
768  unsigned n_boundary_node = Bulk_mesh_pt->nboundary_node(4);
769  for(unsigned n=0;n<n_boundary_node;++n)
770  {
771  Bulk_mesh_pt->boundary_node_pt(4,n)->set_value(5,0.0);
772  }
773 
774  //Lagrange multipliers associated with the periodicity constraint
775  n_boundary_node = this->Bulk_mesh_pt->nboundary_node(3);
776  for(unsigned n=0;n<n_boundary_node;++n)
777  {
778  Node* nod_pt = Bulk_mesh_pt->boundary_node_pt(3,n);
779  if(!(nod_pt->is_on_boundary(0)) &&
780  !(nod_pt->is_on_boundary(2)) &&
781  !(nod_pt->is_on_boundary(4)))
782  {
783  unsigned lm_index = dynamic_cast<BoundaryNodeBase*>(nod_pt)
784  ->index_of_first_value_assigned_by_face_element(
786  nod_pt->set_value(lm_index,0.0);
787  }
788  }
789 
790  }

References oomph::Node::is_on_boundary(), n, and oomph::Data::set_value().

◆ actions_before_implicit_timestep() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_implicit_timestep ( )
inlinevirtual

Actions before the timestep (update the the time-dependent boundary conditions)

Reimplemented from oomph::Problem.

762  {
764  Bulk_mesh_pt->set_lagrangian_nodal_coordinates();
765  //Also set lagrange multipliers to zero
766  unsigned n_boundary_node = Bulk_mesh_pt->nboundary_node(4);
767  for(unsigned n=0;n<n_boundary_node;++n)
768  {
769  Bulk_mesh_pt->boundary_node_pt(4,n)->set_value(5,0.0);
770  }
771 
772  //Lagrange multipliers associated with the periodicity constraint
773  n_boundary_node = this->Bulk_mesh_pt->nboundary_node(3);
774  for(unsigned n=0;n<n_boundary_node;++n)
775  {
776  Node* nod_pt = Bulk_mesh_pt->boundary_node_pt(3,n);
777  if(!(nod_pt->is_on_boundary(0)) &&
778  !(nod_pt->is_on_boundary(2)) &&
779  !(nod_pt->is_on_boundary(4)))
780  {
781  unsigned lm_index = dynamic_cast<BoundaryNodeBase*>(nod_pt)
782  ->index_of_first_value_assigned_by_face_element(
784  nod_pt->set_value(lm_index,0.0);
785  }
786  }
787 
788  }

References oomph::Node::is_on_boundary(), n, and oomph::Data::set_value().

◆ actions_before_implicit_timestep() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_implicit_timestep ( )
inlinevirtual

Actions before the timestep (update the the time-dependent boundary conditions)

Reimplemented from oomph::Problem.

◆ actions_before_newton_convergence_check() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_newton_convergence_check ( )
inlinevirtual

Remember to update the nodes if the surface is not pinned.

Reimplemented from oomph::Problem.

759 {}

◆ actions_before_newton_convergence_check() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_newton_convergence_check ( )
inlinevirtual

Remember to update the nodes if the surface is not pinned.

Reimplemented from oomph::Problem.

757 {}

◆ actions_before_newton_convergence_check() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_newton_convergence_check ( )
inlinevirtual

Remember to update the nodes if the surface is not pinned.

Reimplemented from oomph::Problem.

362  {if(!Surface_pinned) {Bulk_mesh_pt->node_update();}}

◆ actions_before_newton_solve() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_newton_solve ( )
inlinevirtual

Update the problem specs before solve (empty)

Reimplemented from oomph::Problem.

753 {}

◆ actions_before_newton_solve() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_newton_solve ( )
inlinevirtual

Update the problem specs before solve (empty)

Reimplemented from oomph::Problem.

751 {}

◆ actions_before_newton_solve() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::actions_before_newton_solve ( )
inlinevirtual

Update the problem specs before solve (empty)

Reimplemented from oomph::Problem.

355 {}

◆ compute_areas() [1/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::compute_areas ( double &  lower_area,
double &  upper_area 
)
inline
1343  {
1344  // Loop over bulk elements in lower fluid and add each elemental
1345  // contribution
1346  const unsigned n_lower = Bulk_mesh_pt->nlower();
1347  for(unsigned e=0;e<n_lower;e++)
1348  {
1349  lower_area += Bulk_mesh_pt->lower_layer_element_pt(e)->size();
1350  }
1351  const unsigned n_upper = Bulk_mesh_pt->nupper();
1352  for(unsigned e=0;e<n_upper;e++)
1353  {
1354  upper_area += Bulk_mesh_pt->upper_layer_element_pt(e)->size();
1355  }
1356  }

References e(), ElasticRefineableTwoLayerMesh< ELEMENT >::lower_layer_element_pt(), ElasticRefineableTwoLayerMesh< ELEMENT >::nlower(), ElasticRefineableTwoLayerMesh< ELEMENT >::nupper(), oomph::FiniteElement::size(), and ElasticRefineableTwoLayerMesh< ELEMENT >::upper_layer_element_pt().

◆ compute_areas() [2/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::compute_areas ( double &  lower_area,
double &  upper_area 
)
inline
1340  {
1341  // Loop over bulk elements in lower fluid and add each elemental
1342  // contribution
1343  const unsigned n_lower = Bulk_mesh_pt->nlower();
1344  for(unsigned e=0;e<n_lower;e++)
1345  {
1346  lower_area += Bulk_mesh_pt->lower_layer_element_pt(e)->size();
1347  }
1348  const unsigned n_upper = Bulk_mesh_pt->nupper();
1349  for(unsigned e=0;e<n_upper;e++)
1350  {
1351  upper_area += Bulk_mesh_pt->upper_layer_element_pt(e)->size();
1352  }
1353  }

References e(), ElasticRefineableTwoLayerMesh< ELEMENT >::lower_layer_element_pt(), ElasticRefineableTwoLayerMesh< ELEMENT >::nlower(), ElasticRefineableTwoLayerMesh< ELEMENT >::nupper(), oomph::FiniteElement::size(), and ElasticRefineableTwoLayerMesh< ELEMENT >::upper_layer_element_pt().

◆ compute_integrated_concentrations() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::compute_integrated_concentrations ( double &  surface,
double &  bulk,
double &  micelle 
)
inline

Return the total concentrations of the surfactant integrated over the bulk or surface accordingly

1305  {
1306  //Initialise to zero
1307  surface = 0.0;
1308  //Loop over the interface and add each elemental contribution
1309  const unsigned n_interface = Surface_mesh_pt->nelement();
1310  for(unsigned i=0;i<n_interface;i++)
1311  {
1312  // Upcast from GeneralsedElement to the present element
1313  INTERFACE_ELEMENT *el_pt =
1314  dynamic_cast<INTERFACE_ELEMENT*>(
1316 
1317  surface += el_pt->integrated_C();
1318  }
1319 
1320  //Initialise to zero
1321  bulk = 0.0; micelle = 0.0;
1322 
1323  // Loop over bulk elements in lower fluid and add each elemental
1324  // contribution
1325  const unsigned n_lower = Bulk_mesh_pt->nlower();
1326  for(unsigned e=0;e<n_lower;e++)
1327  {
1328  // Upcast from GeneralisedElement to the present element
1329  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
1330  lower_layer_element_pt(e));
1331  double int_M=0.0, int_C=0.0;
1332  el_pt->integrated_C_and_M(int_C,int_M);
1333  bulk += int_C;
1334  micelle += int_M;
1335  }
1336  }

References e(), oomph::Mesh::element_pt(), i, oomph::Mesh::nelement(), and ElasticRefineableTwoLayerMesh< ELEMENT >::nlower().

◆ compute_integrated_concentrations() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::compute_integrated_concentrations ( double &  surface,
double &  bulk,
double &  micelle 
)
inline

Return the total concentrations of the surfactant integrated over the bulk or surface accordingly

1302  {
1303  //Initialise to zero
1304  surface = 0.0;
1305  //Loop over the interface and add each elemental contribution
1306  const unsigned n_interface = Surface_mesh_pt->nelement();
1307  for(unsigned i=0;i<n_interface;i++)
1308  {
1309  // Upcast from GeneralsedElement to the present element
1310  INTERFACE_ELEMENT *el_pt =
1311  dynamic_cast<INTERFACE_ELEMENT*>(
1313 
1314  surface += el_pt->integrated_C();
1315  }
1316 
1317  //Initialise to zero
1318  bulk = 0.0; micelle = 0.0;
1319 
1320  // Loop over bulk elements in lower fluid and add each elemental
1321  // contribution
1322  const unsigned n_lower = Bulk_mesh_pt->nlower();
1323  for(unsigned e=0;e<n_lower;e++)
1324  {
1325  // Upcast from GeneralisedElement to the present element
1326  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
1327  lower_layer_element_pt(e));
1328  double int_M=0.0, int_C=0.0;
1329  el_pt->integrated_C_and_M(int_C,int_M);
1330  bulk += int_C;
1331  micelle += int_M;
1332  }
1333  }

References e(), oomph::Mesh::element_pt(), i, oomph::Mesh::nelement(), and ElasticRefineableTwoLayerMesh< ELEMENT >::nlower().

◆ compute_integrated_concentrations() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::compute_integrated_concentrations ( double &  surface,
double &  bulk,
double &  micelle 
)
inline

Return the total concentrations of the surfactant integrated over the bulk or surface accordingly

533  {
534  //Initialise to zero
535  surface = 0.0;
536  //Loop over the interface and add each elemental contribution
537  const unsigned n_interface = Surface_mesh_pt->nelement();
538  for(unsigned i=0;i<n_interface;i++)
539  {
540  // Upcast from GeneralsedElement to the present element
541  INTERFACE_ELEMENT *el_pt =
542  dynamic_cast<INTERFACE_ELEMENT*>(
544 
545  surface += el_pt->integrated_C();
546  }
547 
548  //Initialise to zero
549  bulk = 0.0; micelle = 0.0;
550 
551  // Loop over bulk elements in lower fluid and add each elemental
552  // contribution
553  const unsigned n_lower = Bulk_mesh_pt->nlower();
554  for(unsigned e=0;e<n_lower;e++)
555  {
556  // Upcast from GeneralisedElement to the present element
557  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
558  lower_layer_element_pt(e));
559  double int_M=0.0, int_C=0.0;
560  el_pt->integrated_C_and_M(int_C,int_M);
561  bulk += int_C;
562  micelle += int_M;
563  }
564  }

References e(), oomph::Mesh::element_pt(), i, oomph::Mesh::nelement(), and oomph::TwoLayerSpineMesh< ELEMENT >::nlower().

◆ create_dependent_position_elements()

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::create_dependent_position_elements ( )
inline

Create the elements that make the position consistent on both sides.

957  {
958  //We know that boundary 1 is made periodic from boundary 3
959  //We also know that the nodes have already been made
960  //periodic so we simply need
961  //to create the dependent elements to match the vertical positions
962  const unsigned n_boundary_node = this->Bulk_mesh_pt->nboundary_node(1);
963  for(unsigned n=0;n<n_boundary_node;++n)
964  {
965  //Cache the boundary node
966  Node* nod_pt = this->Bulk_mesh_pt->boundary_node_pt(1,n);
967  //Cache the master node
968  Node* master_node_pt = nod_pt->copied_node_pt();
969  //If there is no master node, then the node has no
970  //counterpart on the other side and is therefore
971  //not a degree of freedom and does not need to be
972  //made dependent
973  if(master_node_pt!=0)
974  {
975 
976  //Only create dependent for nodes that are not on the interface
977  if(!(master_node_pt->is_on_boundary(0)) &&
978  !(master_node_pt->is_on_boundary(2)) &&
979  !(master_node_pt->is_on_boundary(4)))
980  {
981  //Create the dependent node with a position ID
983  add_element_pt(new DependentPositionPointElement(
984  master_node_pt,
985  nod_pt,Periodic_index));
986  }
987  }
988  }
989  }
Definition: refineable_two_layer_soluble_surfactant.cc:267
virtual Node * copied_node_pt() const
Definition: nodes.h:1107

References oomph::Node::copied_node_pt(), oomph::Node::is_on_boundary(), and n.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ create_interface_elements() [1/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::create_interface_elements ( )
inline

Create the 1d interface elements.

1012  {
1013  //In the adaptive formulation the only way that we will know which elements
1014  //are on the lower or upper side is to use the density ratio
1015 
1016  //Store number of 1d nodes
1017  const unsigned n_node_1d = Bulk_mesh_pt->finite_element_pt(0)->nnode_1d();
1018 
1019  // Determine number of bulk elements adjacent to interface (boundary 4)
1020  const unsigned n_element = this->Bulk_mesh_pt->nboundary_element(4);
1021 
1022  // Loop over those elements adjacent to the interface
1023  for(unsigned e=0;e<n_element;e++)
1024  {
1025  // Get pointer to the bulk element that is adjacent to the interface
1026  ELEMENT* bulk_elem_pt = dynamic_cast<ELEMENT*>(
1027  this->Bulk_mesh_pt->boundary_element_pt(4,e));
1028 
1029  // We only want to attach interface elements to the bulk elements
1030  // which are BELOW the interface, and so we filter out those above by
1031  // referring to the viscosity_ratio_pt
1032  if(bulk_elem_pt->viscosity_ratio_pt() !=&Global_Physical_Variables::M)
1033  {
1034  // Find index of the face of element e that corresponds to the interface
1035  const int face_index = this->Bulk_mesh_pt->face_index_at_boundary(4,e);
1036 
1037  // Create the interface element
1038  INTERFACE_ELEMENT* interface_element_element_pt =
1039  new INTERFACE_ELEMENT(bulk_elem_pt,face_index);
1040 
1041  // Add the interface element to the surface mesh
1042  this->Surface_mesh_pt->add_element_pt(interface_element_element_pt);
1043  }
1044 //Otherwise it's on the upper side
1045  else
1046  {
1047  //Hijack all nodes of all elements
1048  unsigned n_max_node = n_node_1d;
1049  for(unsigned n=0;n<n_max_node;++n)
1050  {
1051  (void)bulk_elem_pt->hijack_nodal_value(n,2,false);
1052  (void)bulk_elem_pt->hijack_nodal_value(n,3,false);
1053  }
1054  }
1055  }
1056 
1057  // --------------------------------------------------------
1058  // Complete the setup to make the elements fully functional
1059  // --------------------------------------------------------
1060 
1061  // Determine number of 1D interface elements in mesh
1062  const unsigned n_interface_element = this->Surface_mesh_pt->nelement();
1063 
1064  // Loop over the interface elements
1065  for(unsigned e=0;e<n_interface_element;e++)
1066  {
1067  // Upcast from GeneralisedElement to the present element
1068  INTERFACE_ELEMENT* el_pt =
1069  dynamic_cast<INTERFACE_ELEMENT*>
1071 
1072  // Set the Biot number
1073  el_pt->bi_pt() = &Global_Physical_Variables::Biot;
1074 
1075  // Set the Marangoni number
1076  el_pt->ma_pt() =&Global_Physical_Variables::Ma;
1077 
1078  // Set the Ca number
1079  el_pt->ca_pt() = &Global_Physical_Variables::Ca;
1080 
1081  // Set the surface elasticity number
1082  el_pt->beta_pt() = &Global_Physical_Variables::Beta_s;
1083 
1084  // Set the surface peclect number
1085  el_pt->peclet_s_pt() = &Global_Physical_Variables::Pe_s;
1086 
1087  // Set the surface peclect number multiplied by strouhal number
1088  el_pt->peclet_strouhal_s_pt() = &Global_Physical_Variables::Pe_s;
1089 
1090  // Set the reaction ratio
1091  el_pt->k_pt() = &Global_Physical_Variables::K_b;
1092 
1093 
1094  el_pt->beta_b_pt() = &Global_Physical_Variables::Beta_b;
1095 
1096 
1097  } // End of loop over interface elements
1098 
1099  }
void add_element_pt(GeneralisedElement *const &element_pt)
Add a (pointer to) an element to the mesh.
Definition: mesh.h:617
double Biot
Biot number.
Definition: surfactant.cc:611
double Ca
Capillary number.
Definition: fibre.cc:61
double Ma
Surfactant Parameters.
Definition: refineable_two_layer_soluble_surfactant.cc:127
double Pe_s
Surface Peclet number.
Definition: refineable_two_layer_soluble_surfactant.cc:133
double Beta_b
Definition: refineable_two_layer_soluble_surfactant.cc:151
double Beta_s
Surface Elasticity number (Capillary number x Marangoni number)
Definition: refineable_two_layer_soluble_surfactant.cc:130
double K_b
The ratio of adsorption-desorption times.
Definition: refineable_two_layer_soluble_surfactant.cc:148

References oomph::Global_Physical_Variables::Beta_b, oomph::Global_Physical_Variables::Beta_s, oomph::Global_Physical_Variables::Biot, oomph::Global_Physical_Variables::Ca, e(), oomph::Global_Physical_Variables::K_b, oomph::Global_Physical_Variables::M, oomph::Global_Physical_Variables::Ma, n, and oomph::Global_Physical_Variables::Pe_s.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ create_interface_elements() [2/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::create_interface_elements ( )
inline

Create the 1d interface elements.

1009  {
1010  //In the adaptive formulation the only way that we will know which elements
1011  //are on the lower or upper side is to use the density ratio
1012 
1013  //Store number of 1d nodes
1014  const unsigned n_node_1d = Bulk_mesh_pt->finite_element_pt(0)->nnode_1d();
1015 
1016  // Determine number of bulk elements adjacent to interface (boundary 4)
1017  const unsigned n_element = this->Bulk_mesh_pt->nboundary_element(4);
1018 
1019  // Loop over those elements adjacent to the interface
1020  for(unsigned e=0;e<n_element;e++)
1021  {
1022  // Get pointer to the bulk element that is adjacent to the interface
1023  ELEMENT* bulk_elem_pt = dynamic_cast<ELEMENT*>(
1024  this->Bulk_mesh_pt->boundary_element_pt(4,e));
1025 
1026  // We only want to attach interface elements to the bulk elements
1027  // which are BELOW the interface, and so we filter out those above by
1028  // referring to the viscosity_ratio_pt
1029  if(bulk_elem_pt->viscosity_ratio_pt() !=&Global_Physical_Variables::M)
1030  {
1031  // Find index of the face of element e that corresponds to the interface
1032  const int face_index = this->Bulk_mesh_pt->face_index_at_boundary(4,e);
1033 
1034  // Create the interface element
1035  INTERFACE_ELEMENT* interface_element_element_pt =
1036  new INTERFACE_ELEMENT(bulk_elem_pt,face_index);
1037 
1038  // Add the interface element to the surface mesh
1039  this->Surface_mesh_pt->add_element_pt(interface_element_element_pt);
1040  }
1041 //Otherwise it's on the upper side
1042  else
1043  {
1044  //Hijack all nodes of all elements
1045  unsigned n_max_node = n_node_1d;
1046  for(unsigned n=0;n<n_max_node;++n)
1047  {
1048  (void)bulk_elem_pt->hijack_nodal_value(n,2,false);
1049  (void)bulk_elem_pt->hijack_nodal_value(n,3,false);
1050  }
1051  }
1052  }
1053 
1054  // --------------------------------------------------------
1055  // Complete the setup to make the elements fully functional
1056  // --------------------------------------------------------
1057 
1058  // Determine number of 1D interface elements in mesh
1059  const unsigned n_interface_element = this->Surface_mesh_pt->nelement();
1060 
1061  // Loop over the interface elements
1062  for(unsigned e=0;e<n_interface_element;e++)
1063  {
1064  // Upcast from GeneralisedElement to the present element
1065  INTERFACE_ELEMENT* el_pt =
1066  dynamic_cast<INTERFACE_ELEMENT*>
1068 
1069  // Set the Biot number
1070  el_pt->bi_pt() = &Global_Physical_Variables::Biot;
1071 
1072  // Set the Marangoni number
1073  el_pt->ma_pt() =&Global_Physical_Variables::Ma;
1074 
1075  // Set the Ca number
1076  el_pt->ca_pt() = &Global_Physical_Variables::Ca;
1077 
1078  // Set the surface elasticity number
1079  el_pt->beta_pt() = &Global_Physical_Variables::Beta_s;
1080 
1081  // Set the surface peclect number
1082  el_pt->peclet_s_pt() = &Global_Physical_Variables::Pe_s;
1083 
1084  // Set the surface peclect number multiplied by strouhal number
1085  el_pt->peclet_strouhal_s_pt() = &Global_Physical_Variables::Pe_s;
1086 
1087  // Set the reaction ratio
1088  el_pt->k_pt() = &Global_Physical_Variables::K_b;
1089 
1090 
1091  el_pt->beta_b_pt() = &Global_Physical_Variables::Beta_b;
1092 
1093 
1094  } // End of loop over interface elements
1095 
1096  }
Matrix< RealScalar, Dynamic, Dynamic > M
Definition: bench_gemm.cpp:50

References oomph::Global_Physical_Variables::Beta_b, oomph::Global_Physical_Variables::Beta_s, oomph::Global_Physical_Variables::Biot, oomph::Global_Physical_Variables::Ca, e(), oomph::Global_Physical_Variables::K_b, oomph::Global_Physical_Variables::M, oomph::Global_Physical_Variables::Ma, n, and oomph::Global_Physical_Variables::Pe_s.

◆ create_slave_position_elements()

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::create_slave_position_elements ( )
inline

Create the elements that slave the position.

956  {
957  //We know that boundary 1 is made periodic from boundary 3
958  //We also know that the nodes have already been made periodic so we simply need
959  //to create the slave elements to match the vertical positions
960  const unsigned n_boundary_node = this->Bulk_mesh_pt->nboundary_node(1);
961  for(unsigned n=0;n<n_boundary_node;++n)
962  {
963  //Cache the boundary node
964  Node* nod_pt = this->Bulk_mesh_pt->boundary_node_pt(1,n);
965  //Cache the master node
966  Node* master_node_pt = nod_pt->copied_node_pt();
967  //If there is no master node, then the node has no
968  //counterpart on the other side and is therefore
969  //not a degree of freedom and does not need to be
970  //slaved
971  if(master_node_pt!=0)
972  {
973 
974  //Only create slaves for nodes that are not on the interface
975  if(!(master_node_pt->is_on_boundary(0)) &&
976  !(master_node_pt->is_on_boundary(2)) &&
977  !(master_node_pt->is_on_boundary(4)))
978  {
979  //Create the slave node with a position ID
980  this->Slave_position_mesh_pt->
981  add_element_pt(new SlavePositionPointElement(master_node_pt,
982  nod_pt,Periodic_index));
983  }
984  }
985  }
986  }
Definition: refineable_unstructured_two_layer_ss.cc:266
Mesh * Slave_position_mesh_pt
Definition: refineable_unstructured_two_layer_ss.cc:1200

References oomph::Node::copied_node_pt(), oomph::Node::is_on_boundary(), and n.

◆ deform_interface() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::deform_interface ( const double &  epsilon,
const unsigned &  n_periods 
)
inline
1143 {
1144  // Determine number of nodes in the "bulk" mesh
1145  const unsigned n_node = Bulk_mesh_pt->nnode();
1146 
1147  // Loop over all nodes in mesh
1148  for(unsigned n=0;n<n_node;n++)
1149  {
1150  // Determine eulerian position of node
1151  const double current_x_pos = Bulk_mesh_pt->node_pt(n)->x(0);
1152  const double current_y_pos = Bulk_mesh_pt->node_pt(n)->x(1);
1153 
1154  double y_scale = current_y_pos/Global_Physical_Variables::H0;
1155  if(current_y_pos > Global_Physical_Variables::H0)
1156  {
1157  y_scale = (1.0 - current_y_pos)/(1.0 - Global_Physical_Variables::H0);
1158  }
1159 
1160  // Determine new vertical position of node, *NEED TO THINK*
1161  const double new_y_pos = current_y_pos
1162  + y_scale*epsilon
1163  *(cos(n_periods*MathematicalConstants::Pi*
1165 
1166  // Set new position
1167  Bulk_mesh_pt->node_pt(n)->x(1) = new_y_pos;
1168  }
1169 } // End of deform_free_surface
AnnoyingScalar cos(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:136
double Pi
Definition: two_d_biharmonic.cc:235
double epsilon
Definition: osc_ring_sarah_asymptotics.h:43

References cos(), oomph::SarahBL::epsilon, oomph::Global_Physical_Variables::H0, oomph::Global_Physical_Variables::L, n, and oomph::MathematicalConstants::Pi.

◆ deform_interface() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::deform_interface ( const double &  epsilon,
const unsigned &  n_periods 
)
inline
1140 {
1141  // Determine number of nodes in the "bulk" mesh
1142  const unsigned n_node = Bulk_mesh_pt->nnode();
1143 
1144  // Loop over all nodes in mesh
1145  for(unsigned n=0;n<n_node;n++)
1146  {
1147  // Determine eulerian position of node
1148  const double current_x_pos = Bulk_mesh_pt->node_pt(n)->x(0);
1149  const double current_y_pos = Bulk_mesh_pt->node_pt(n)->x(1);
1150 
1151  double y_scale = current_y_pos/Global_Physical_Variables::H0;
1152  if(current_y_pos > Global_Physical_Variables::H0)
1153  {
1154  y_scale = (1.0 - current_y_pos)/(1.0 - Global_Physical_Variables::H0);
1155  }
1156 
1157  // Determine new vertical position of node, *NEED TO THINK*
1158  const double new_y_pos = current_y_pos
1159  + y_scale*epsilon
1160  *(cos(n_periods*MathematicalConstants::Pi*
1162 
1163  // Set new position
1164  Bulk_mesh_pt->node_pt(n)->x(1) = new_y_pos;
1165  }
1166 } // End of deform_free_surface

References cos(), oomph::SarahBL::epsilon, oomph::Global_Physical_Variables::H0, oomph::Global_Physical_Variables::L, n, and oomph::MathematicalConstants::Pi.

◆ deform_interface() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::deform_interface ( const double &  epsilon,
const unsigned &  n_periods 
)
inline
391 {
392  // Determine number of spines in mesh
393  const unsigned n_spine = Bulk_mesh_pt->nspine();
394 
395  // Loop over spines in mesh
396  for(unsigned i=0;i<n_spine;i++)
397  {
398  // Determine x coordinate of spine
399  double x_value = Bulk_mesh_pt->boundary_node_pt(0,i)->x(0);
400 
401  // Set spine height
402  Bulk_mesh_pt->spine_pt(i)->height() =
404  epsilon*(cos(n_periods*
406  }
407 
408  // Update nodes in bulk mesh
409  Bulk_mesh_pt->node_update();
410 } // End of deform_free_surface

References cos(), oomph::SarahBL::epsilon, oomph::Global_Physical_Variables::H0, i, oomph::Global_Physical_Variables::L, and oomph::MathematicalConstants::Pi.

◆ delete_dependent_position_elements()

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::delete_dependent_position_elements ( )
inline

Delete the 1d interface elements.

995  {
996  // Determine number of interface elements
997  const unsigned n_dependent_element = Dependent_position_mesh_pt->nelement();
998 
999  // Loop over interface elements and delete
1000  for(unsigned e=0;e<n_dependent_element;e++)
1001  {
1003  }
1004 
1005  // Wipe the mesh
1007  }
void flush_element_and_node_storage()
Definition: mesh.h:407

References e().

◆ delete_interface_elements() [1/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::delete_interface_elements ( )
inline

Delete the 1d interface elements.

1106  {
1107  // Determine number of interface elements
1108  const unsigned n_interface_element = Surface_mesh_pt->nelement();
1109 
1110  // Loop over interface elements and delete
1111  for(unsigned e=0;e<n_interface_element;e++)
1112  {
1113  delete Surface_mesh_pt->element_pt(e);
1114  }
1115 
1116  // Wipe the mesh
1118  }

References e().

◆ delete_interface_elements() [2/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::delete_interface_elements ( )
inline

Delete the 1d interface elements.

1103  {
1104  // Determine number of interface elements
1105  const unsigned n_interface_element = Surface_mesh_pt->nelement();
1106 
1107  // Loop over interface elements and delete
1108  for(unsigned e=0;e<n_interface_element;e++)
1109  {
1110  delete Surface_mesh_pt->element_pt(e);
1111  }
1112 
1113  // Wipe the mesh
1115  }

References e().

◆ delete_slave_position_elements()

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::delete_slave_position_elements ( )
inline

Delete the 1d interface elements.

992  {
993  // Determine number of interface elements
994  const unsigned n_slave_element = Slave_position_mesh_pt->nelement();
995 
996  // Loop over interface elements and delete
997  for(unsigned e=0;e<n_slave_element;e++)
998  {
1000  }
1001 
1002  // Wipe the mesh
1004  }

References e().

◆ doc_solution() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::doc_solution ( std::ofstream &  trace)

Doc the solution.

1806 {
1807  //Declare an output stream and filename
1808  ofstream some_file;
1809  char filename[100];
1810 
1811  // Number of plot points: npts x npts
1812  unsigned npts=5;
1813 
1814  // Output solution
1815  //-----------------
1816  sprintf(filename,"%s/soln%i.dat",Doc_info.directory().c_str(),
1817  Doc_info.number());
1818  some_file.open(filename);
1819  unsigned n_element = Bulk_mesh_pt->nelement();
1820  for(unsigned e=0;e<n_element;e++)
1821  {
1822  Bulk_mesh_pt->finite_element_pt(e)->output(some_file,npts);
1823  }
1824  some_file.close();
1825 
1826  //Output the interface
1827  sprintf(filename,"%s/int%i.dat",Doc_info.directory().c_str(),
1828  Doc_info.number());
1829  some_file.open(filename);
1830 
1831  unsigned n_interface = Surface_mesh_pt->nelement();
1832  for(unsigned i=0;i<n_interface;i++)
1833  {
1834  Surface_mesh_pt->finite_element_pt(i)->output(some_file,npts);
1835  }
1836  some_file.close();
1837 
1838  //Let's get the mases
1839  double surface=0.0, bulk=0.0, micelle=0.0;
1840  this->compute_integrated_concentrations(surface,bulk,micelle);
1841 
1842  //double upper_area = 0.0, lower_area = 0.0;
1843  //this->compute_areas(lower_area,upper_area);
1844 
1845  //Compute the max and min
1846  double max = 0.0; double min = 0.0;
1847  this->interface_min_max(min,max);
1848 
1849  trace << time_pt()->time() << " "
1850  << this->Monitor_node_pt->x(1) << " "
1851  << this->Monitor_node_pt->value(2) << " "
1852  << this->Monitor_node_pt->value(3) << " "
1853  << this->Monitor_node_pt->value(4) << " "
1855  << surface << " " << bulk << " " << micelle << " "
1856  << surface + (bulk + micelle)/(Global_Physical_Variables::Beta_b)
1857  << " " << min << " " << max << " "
1858  //<< " " << upper_area << " " << lower_area << " " << upper_area + lower_area
1859  << std::endl;
1860 
1861 
1862  Doc_info.number()++;
1863 } // end of doc
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
void interface_min_max(double &min, double &max)
Definition: refineable_two_layer_soluble_surfactant.cc:1210
double l2_norm_of_height(const double &h0)
Definition: refineable_two_layer_soluble_surfactant.cc:1282
void compute_integrated_concentrations(double &surface, double &bulk, double &micelle)
Definition: refineable_two_layer_soluble_surfactant.cc:1302
std::string directory() const
Output directory.
Definition: oomph_utilities.h:524
unsigned & number()
Number used (e.g.) for labeling output files.
Definition: oomph_utilities.h:554
virtual void output(std::ostream &outfile)
Definition: elements.h:3050
double value(const unsigned &i) const
Definition: nodes.cc:2408
double & time()
Return the current value of the continuous time.
Definition: timesteppers.h:123
#define min(a, b)
Definition: datatypes.h:22
#define max(a, b)
Definition: datatypes.h:23
string filename
Definition: MergeRestartFiles.py:39

References oomph::Global_Physical_Variables::Beta_b, oomph::DocInfo::directory(), GlobalParameters::Doc_info, e(), MergeRestartFiles::filename, oomph::Global_Physical_Variables::H0, i, Global_Physical_Variables::L, max, min, oomph::DocInfo::number(), and sqrt().

◆ doc_solution() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::doc_solution ( std::ofstream &  trace)

Doc the solution.

◆ doc_solution() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::doc_solution ( std::ofstream &  trace)

Doc the solution.

◆ fix_pressure() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::fix_pressure ( const unsigned &  e,
const unsigned &  pdof,
const double &  pvalue 
)
inline

Fix pressure in element e at pressure dof pdof and set to pvalue.

1124  {
1125  //Cast to specific element and fix pressure
1126  dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(e))->
1127  fix_pressure(pdof,pvalue);
1128  } // end_of_fix_pressure

References e().

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ fix_pressure() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::fix_pressure ( const unsigned &  e,
const unsigned &  pdof,
const double &  pvalue 
)
inline

Fix pressure in element e at pressure dof pdof and set to pvalue.

1121  {
1122  //Cast to specific element and fix pressure
1123  dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(e))->
1124  fix_pressure(pdof,pvalue);
1125  } // end_of_fix_pressure

References e().

◆ fix_pressure() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::fix_pressure ( const unsigned &  e,
const unsigned &  pdof,
const double &  pvalue 
)
inline

Fix pressure in element e at pressure dof pdof and set to pvalue.

372  {
373  //Cast to specific element and fix pressure
374  dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(e))->
375  fix_pressure(pdof,pvalue);
376  } // end_of_fix_pressure

References e().

◆ global_temporal_error_norm() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
double SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::global_temporal_error_norm
virtual

Function to calculate a global error norm, used in adaptive timestepping to control the change in timestep. Individual errors for each data object can be obtained via the data timestepper's temporal_error_in_value or temporal_error_in_position functions and should be combined to construct a global norm. For example, in fluids problems a suitable norm is usually the weighted sum of the errors in the velocities; for moving mesh problems is it usually better to use the weighted sum of the errors in position.

Reimplemented from oomph::Problem.

1870 {
1871  //Temp
1872  double global_error = 0.0;
1873 
1874  //Find out how many nodes there are in the problem
1875  unsigned long Nnode = Bulk_mesh_pt->nnode();
1876 
1877  //Loop over the nodes and calculate the errors in the positions
1878  for(unsigned long i=0;i<Nnode;i++)
1879  {
1880  //Find number of dimensions of the node
1881  unsigned Ndim = Bulk_mesh_pt->node_pt(i)->ndim();
1882  //Set the position error to zero
1883  double node_position_error = 0.0;
1884  //Loop over the dimensions (only need j=1)
1885  //for(unsigned j=0;j<Ndim;j++)
1886  unsigned j=1;
1887  {
1888  //Get position error
1889  double error =
1890  Bulk_mesh_pt->node_pt(i)->position_time_stepper_pt()->
1891  temporal_error_in_position(Bulk_mesh_pt->node_pt(i),j);
1892 
1893  //Add the square of the individual error to the position error
1894  node_position_error += error*error;
1895  }
1896 
1897  //Divide the position error by the number of dimensions
1898  node_position_error /= Ndim;
1899  //Now add to the global error
1900  global_error += node_position_error;
1901  }
1902 
1903  //Now the global error must be divided by the number of nodes
1904  global_error /= Nnode;
1905 
1906  //Return the square root of the errr
1907  return sqrt(global_error);
1908 }
int error
Definition: calibrate.py:297
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References calibrate::error, i, j, and sqrt().

◆ global_temporal_error_norm() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
double SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::global_temporal_error_norm ( )
virtual

Function to calculate a global error norm, used in adaptive timestepping to control the change in timestep. Individual errors for each data object can be obtained via the data timestepper's temporal_error_in_value or temporal_error_in_position functions and should be combined to construct a global norm. For example, in fluids problems a suitable norm is usually the weighted sum of the errors in the velocities; for moving mesh problems is it usually better to use the weighted sum of the errors in position.

Reimplemented from oomph::Problem.

◆ global_temporal_error_norm() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
double SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::global_temporal_error_norm ( )
virtual

Function to calculate a global error norm, used in adaptive timestepping to control the change in timestep. Individual errors for each data object can be obtained via the data timestepper's temporal_error_in_value or temporal_error_in_position functions and should be combined to construct a global norm. For example, in fluids problems a suitable norm is usually the weighted sum of the errors in the velocities; for moving mesh problems is it usually better to use the weighted sum of the errors in position.

Reimplemented from oomph::Problem.

◆ interface_min_max() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::interface_min_max ( double &  min,
double &  max 
)
inline
1211  {
1212  //Loop over the interface and add each elemental contribution
1213  const unsigned n_interface = Surface_mesh_pt->nelement();
1214  if(n_interface > 0)
1215  {
1216  //Set the initial values to the first nodal position
1218  min = max;
1219 
1220  //Loop over all elements and find the max
1221  for(unsigned i=0;i<n_interface;i++)
1222  {
1223  // Upcast from GeneralsedElement to the present element
1224  INTERFACE_ELEMENT *el_pt =
1225  dynamic_cast<INTERFACE_ELEMENT*>(
1227 
1228  const unsigned n_node = el_pt->nnode();
1229  if(n_node != 3)
1230  {
1231  std::cout << "Can't do max and min for elements that are not quadratic\n";
1232  return;
1233  }
1234 
1235 
1236  //Read out the y values from the nodes
1237  Vector<double> y(3);
1238  for(unsigned n=0;n<3;++n)
1239  {
1240  y[n] = el_pt->node_pt(n)->x(1);
1241  }
1242 
1243  double local_max = y[0];
1244  double local_min = y[0];
1245  //Find maximum and minimum nodes
1246  for(unsigned n=1;n<3;++n)
1247  {
1248  if(y[n] > local_max) {local_max = y[n];}
1249  if(y[n] < local_min) {local_min = y[n];}
1250  }
1251 
1252  //If we have a linear case then we are done
1253  //Check that it's not a degenerate (linear) case
1254  if(std::abs(y[0] - 2*y[1] + y[2]) > 1.0e-10)
1255  {
1256  //Calculate extreme value of the local coordinate based on known
1257  //quadratic basis functions (This shoudl really be inside the element class)
1258  Vector<double> extreme_s(1,0.5*(y[0] - y[2])/(y[0] - 2.0*y[1] + y[2]));
1259 
1260  //Find the extreme height if the local coordinate is within the
1261  //rane of the element
1262  if(std::abs(extreme_s[0]) <= 1.0)
1263  {
1264  double extreme_h = el_pt->interpolated_x(extreme_s,1);
1265  //Check whether the extreme value is greater than any of the nodes.
1266  if(extreme_h > local_max) {local_max = extreme_h;}
1267  if(extreme_h < local_min) {local_min = extreme_h;}
1268  }
1269  }
1270 
1271  //Now check whether local max and min are global
1272  if(local_max > max) {max = local_max;}
1273  if(local_min < min) {min = local_min;}
1274  }
1275  }
1276  }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135

References abs(), oomph::Mesh::element_pt(), oomph::Mesh::finite_element_pt(), i, max, min, n, oomph::Mesh::nelement(), oomph::FiniteElement::node_pt(), oomph::Node::x(), and y.

◆ interface_min_max() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::interface_min_max ( double &  min,
double &  max 
)
inline
1208  {
1209  //Loop over the interface and add each elemental contribution
1210  const unsigned n_interface = Surface_mesh_pt->nelement();
1211  if(n_interface > 0)
1212  {
1213  //Set the initial values to the first nodal position
1215  min = max;
1216 
1217  //Loop over all elements and find the max
1218  for(unsigned i=0;i<n_interface;i++)
1219  {
1220  // Upcast from GeneralsedElement to the present element
1221  INTERFACE_ELEMENT *el_pt =
1222  dynamic_cast<INTERFACE_ELEMENT*>(
1224 
1225  const unsigned n_node = el_pt->nnode();
1226  if(n_node != 3)
1227  {
1228  std::cout << "Can't do max and min for elements that are not quadratic\n";
1229  return;
1230  }
1231 
1232 
1233  //Read out the y values from the nodes
1234  Vector<double> y(3);
1235  for(unsigned n=0;n<3;++n)
1236  {
1237  y[n] = el_pt->node_pt(n)->x(1);
1238  }
1239 
1240  double local_max = y[0];
1241  double local_min = y[0];
1242  //Find maximum and minimum nodes
1243  for(unsigned n=1;n<3;++n)
1244  {
1245  if(y[n] > local_max) {local_max = y[n];}
1246  if(y[n] < local_min) {local_min = y[n];}
1247  }
1248 
1249  //If we have a linear case then we are done
1250  //Check that it's not a degenerate (linear) case
1251  if(std::abs(y[0] - 2*y[1] + y[2]) > 1.0e-10)
1252  {
1253  //Calculate extreme value of the local coordinate based on known
1254  //quadratic basis functions (This shoudl really be inside the element class)
1255  Vector<double> extreme_s(1,0.5*(y[0] - y[2])/(y[0] - 2.0*y[1] + y[2]));
1256 
1257  //Find the extreme height if the local coordinate is within the
1258  //rane of the element
1259  if(std::abs(extreme_s[0]) <= 1.0)
1260  {
1261  double extreme_h = el_pt->interpolated_x(extreme_s,1);
1262  //Check whether the extreme value is greater than any of the nodes.
1263  if(extreme_h > local_max) {local_max = extreme_h;}
1264  if(extreme_h < local_min) {local_min = extreme_h;}
1265  }
1266  }
1267 
1268  //Now check whether local max and min are global
1269  if(local_max > max) {max = local_max;}
1270  if(local_min < min) {min = local_min;}
1271  }
1272  }
1273  }

References abs(), oomph::Mesh::element_pt(), oomph::Mesh::finite_element_pt(), i, max, min, n, oomph::Mesh::nelement(), oomph::FiniteElement::node_pt(), oomph::Node::x(), and y.

◆ interface_min_max() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::interface_min_max ( double &  min,
double &  max 
)
inline
440  {
441  //Loop over the interface and add each elemental contribution
442  const unsigned n_interface = Surface_mesh_pt->nelement();
443  if(n_interface > 0)
444  {
445  //Set the initial values to the first nodal position
447  min = max;
448 
449  //Loop over all elements and find the max
450  for(unsigned i=0;i<n_interface;i++)
451  {
452  // Upcast from GeneralsedElement to the present element
453  INTERFACE_ELEMENT *el_pt =
454  dynamic_cast<INTERFACE_ELEMENT*>(
456 
457  const unsigned n_node = el_pt->nnode();
458  if(n_node != 3)
459  {
460  std::cout << "Can't do max and min for elements that are not quadratic\n";
461  return;
462  }
463 
464 
465  //Read out the y values from the nodes
466  Vector<double> y(3);
467  for(unsigned n=0;n<3;++n)
468  {
469  y[n] = el_pt->node_pt(n)->x(1);
470  }
471 
472  double local_max = y[0];
473  double local_min = y[0];
474  //Find maximum and minimum nodes
475  for(unsigned n=1;n<3;++n)
476  {
477  if(y[n] > local_max) {local_max = y[n];}
478  if(y[n] < local_min) {local_min = y[n];}
479  }
480 
481  //If we have a linear case then we are done
482  //Check that it's not a degenerate (linear) case
483  if(std::abs(y[0] - 2*y[1] + y[2]) > 1.0e-10)
484  {
485  //Calculate extreme value of the local coordinate based on known
486  //quadratic basis functions (This shoudl really be inside the element class)
487  Vector<double> extreme_s(1,0.5*(y[0] - y[2])/(y[0] - 2.0*y[1] + y[2]));
488 
489  //Find the extreme height if the local coordinate is within the
490  //rane of the element
491  if(std::abs(extreme_s[0]) <= 1.0)
492  {
493  double extreme_h = el_pt->interpolated_x(extreme_s,1);
494  //Check whether the extreme value is greater than any of the nodes.
495  if(extreme_h > local_max) {local_max = extreme_h;}
496  if(extreme_h < local_min) {local_min = extreme_h;}
497  }
498  }
499 
500  //Now check whether local max and min are global
501  if(local_max > max) {max = local_max;}
502  if(local_min < min) {min = local_min;}
503  }
504  }
505  }

References abs(), oomph::Mesh::element_pt(), oomph::Mesh::finite_element_pt(), i, max, min, n, oomph::Mesh::nelement(), oomph::FiniteElement::node_pt(), oomph::Node::x(), and y.

◆ l2_norm_of_height() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
double SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::l2_norm_of_height ( const double &  h0)
inline
1283  {
1284  double norm = 0.0;
1285  //Loop over the interface and add each elemental contribution
1286  const unsigned n_interface = Surface_mesh_pt->nelement();
1287  for(unsigned i=0;i<n_interface;i++)
1288  {
1289  // Upcast from GeneralsedElement to the present element
1290  INTERFACE_ELEMENT *el_pt =
1291  dynamic_cast<INTERFACE_ELEMENT*>(
1293 
1294  norm += el_pt->l2_norm_of_height(h0);
1295  }
1296  return norm;
1297  }

References oomph::Mesh::element_pt(), i, and oomph::Mesh::nelement().

◆ l2_norm_of_height() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
double SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::l2_norm_of_height ( const double &  h0)
inline
1280  {
1281  double norm = 0.0;
1282  //Loop over the interface and add each elemental contribution
1283  const unsigned n_interface = Surface_mesh_pt->nelement();
1284  for(unsigned i=0;i<n_interface;i++)
1285  {
1286  // Upcast from GeneralsedElement to the present element
1287  INTERFACE_ELEMENT *el_pt =
1288  dynamic_cast<INTERFACE_ELEMENT*>(
1290 
1291  norm += el_pt->l2_norm_of_height(h0);
1292  }
1293  return norm;
1294  }

References oomph::Mesh::element_pt(), i, and oomph::Mesh::nelement().

◆ l2_norm_of_height() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
double SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::l2_norm_of_height ( const double &  h0)
inline
511  {
512  double norm = 0.0;
513  //Loop over the interface and add each elemental contribution
514  const unsigned n_interface = Surface_mesh_pt->nelement();
515  for(unsigned i=0;i<n_interface;i++)
516  {
517  // Upcast from GeneralsedElement to the present element
518  INTERFACE_ELEMENT *el_pt =
519  dynamic_cast<INTERFACE_ELEMENT*>(
521 
522  norm += el_pt->l2_norm_of_height(h0);
523  }
524  return norm;
525  }

References oomph::Mesh::element_pt(), i, and oomph::Mesh::nelement().

◆ set_boundary_conditions() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::set_boundary_conditions ( const double &  time)

Set the boundary conditions.

Set the boundary conditions as a function of continuous time

1723 {
1724  //Set initial temperature profile
1725  if(time <= 0.0)
1726  {
1727  const double Gamma_init = 0.75;
1728  const double C_init = Gamma_init/(Global_Physical_Variables::K_b*(1.0-Gamma_init));
1729  const double M_init = pow(C_init,Global_Physical_Variables::N);
1730  unsigned n_lower = Bulk_mesh_pt->nlower();//nnode();
1731  for(unsigned e=0;e<n_lower;e++)
1732  {
1733  FiniteElement* el_pt =
1734  Bulk_mesh_pt->lower_layer_element_pt(e);
1735  unsigned n_node = el_pt->nnode();
1736  for(unsigned n=0;n<n_node;n++)
1737  {
1738  Node* nod_pt = el_pt->node_pt(n);
1739  //And in uniformly distributed surfactant
1740  //Be careful about upper and lower layers
1741  //If these are not set
1742  nod_pt->set_value(2,C_init);
1743  nod_pt->set_value(3,M_init);
1744 
1745  //Set the velocityq
1746  /*double y = nod_pt->x(1);
1747  nod_pt->set_value(0,y);
1748  nod_pt->set_value(1,0.0);*/
1749  }
1750  }
1751 
1752  //Set the initial surface concentration to be one
1753  unsigned n_surface_element = Surface_mesh_pt->nelement();
1754  for(unsigned e=0;e<n_surface_element;++e)
1755  {
1756  unsigned n_el_node = Surface_mesh_pt->finite_element_pt(e)->nnode();
1757  for(unsigned n=0;n<n_el_node;++n)
1758  {
1760  }
1761  }
1762  } //End of initial conditions
1763 
1764  // Loop over the boundaries
1765  unsigned num_bound = Bulk_mesh_pt->nboundary();
1766  for(unsigned ibound=0;ibound<num_bound;ibound++)
1767  {
1768  // Loop over the nodes on boundary
1769  unsigned num_nod=Bulk_mesh_pt->nboundary_node(ibound);
1770  for(unsigned inod=0;inod<num_nod;inod++)
1771  {
1772  // Get pointer to node
1773  Node* nod_pt=Bulk_mesh_pt->boundary_node_pt(ibound,inod);
1774 
1776  {
1777  //If we are on the side walls we only set the v-velocity.
1778  if((ibound==1) || (ibound==3))
1779  {
1780  nod_pt->set_value(1,0.0);
1781  }
1782  }
1783 
1784  //If we are on the top boundary, do not set the velocities
1785  //(yet)
1786  if(ibound==2)
1787  {
1788  nod_pt->set_value(0,1.0); nod_pt->set_value(1,0.0);
1789  }
1790 
1791  //If we are on the bottom boundary
1792  if(ibound==0)
1793  {
1794  nod_pt->set_value(0,0.0); nod_pt->set_value(1,0.0);
1795  }
1796  }
1797  }
1798 } // end_of_set_boundary_conditions
Definition: elements.h:1313
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625

References e(), oomph::Global_Physical_Variables::K_b, n, N, oomph::FiniteElement::nnode(), oomph::FiniteElement::node_pt(), oomph::Control_Parameters::Periodic_BCs, Eigen::ArrayBase< Derived >::pow(), and oomph::Data::set_value().

◆ set_boundary_conditions() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::set_boundary_conditions ( const double &  time)

Set the boundary conditions.

◆ set_boundary_conditions() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::set_boundary_conditions ( const double &  time)

Set the boundary conditions.

◆ unfix_pressure() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::unfix_pressure ( const unsigned &  e,
const unsigned &  pdof 
)
inline

UnFix pressure in element e at pressure dof pdof and set to pvalue.

1133  {
1134  //Cast to specific element and fix pressure
1135  dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(e))->
1136  unfix_pressure(pdof);
1137  } // end_of_unfix_pressure

References e().

◆ unfix_pressure() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::unfix_pressure ( const unsigned &  e,
const unsigned &  pdof 
)
inline

UnFix pressure in element e at pressure dof pdof and set to pvalue.

1130  {
1131  //Cast to specific element and fix pressure
1132  dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(e))->
1133  unfix_pressure(pdof);
1134  } // end_of_unfix_pressure

References e().

◆ unfix_pressure() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::unfix_pressure ( const unsigned &  e,
const unsigned &  pdof 
)
inline

UnFix pressure in element e at pressure dof pdof and set to pvalue.

381  {
382  //Cast to specific element and fix pressure
383  dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(e))->
384  unfix_pressure(pdof);
385  } // end_of_unfix_pressure

References e().

◆ unpin_surface() [1/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::unpin_surface ( )
inline

Release the free surface so that it can move.

659  {
660  //Only bother if the surface is pinned
661  if(Surface_pinned)
662  {
663  Surface_pinned = false;
664 
665  //Unpin the heights of all nodes not on the boundaries
666  unsigned n_node = Bulk_mesh_pt->nnode();
667  for(unsigned n=0;n<n_node;n++)
668  {
669  SolidNode* nod_pt = static_cast<SolidNode*>(Bulk_mesh_pt->node_pt(n));
670  if(!(nod_pt->is_on_boundary(0) || nod_pt->is_on_boundary(2)))
671  {
672  nod_pt->unpin_position(1);
673  }
674  }
675 
676  // Loop over the elements to re-enable ALE
677  unsigned n_element = Bulk_mesh_pt->nelement();
678  for(unsigned i=0;i<n_element;i++)
679  {
680  // Upcast from GeneralsedElement to the present element
681  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(i));
682  el_pt->enable_ALE();
683  }
684 
685  //Unpin the interfacial surfactant concentrations and Lagrange multipliers
686  unsigned n_interface = Surface_mesh_pt->nelement();
687  for(unsigned i=0;i<n_interface;i++)
688  {
690 
691  //Need to unpin the values of surfactant concentration and Lagrange multiplier
692  unsigned n_el_node = el_pt->nnode();
693  for(unsigned n=0;n<n_el_node;++n)
694  {
695  Node* nod_pt = el_pt->node_pt(n);
696  nod_pt->unpin(4);
697  nod_pt->unpin(5);
698  }
699  }
700 
701 
702  //Now unpin the bulk concentrations in the lower region
703  const unsigned n_lower = Bulk_mesh_pt->nlower();
704  // Loop over bulk elements in lower fluid
705  for(unsigned e=0;e<n_lower;e++)
706  {
707  // Upcast from GeneralisedElement to the present element
708  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
709  lower_layer_element_pt(e));
710  unsigned n_node = el_pt->nnode();
711  for(unsigned n=0;n<n_node;++n)
712  {
713  el_pt->node_pt(n)->unpin(2); //Bulk Concentration
714  el_pt->node_pt(n)->unpin(3); //Micelle Concentration
715  }
716  }
717 
718  //We also need to unpin the Lagrange multipliers for periodicity
719  //We must not clash with the lagrange multiplier used to drive
720  //the interface so we pin that at the left-hand-side
721  {
722  unsigned b=3;
723  unsigned n_boundary_node = this->Bulk_mesh_pt->nboundary_node(b);
724  for(unsigned n=0;n<n_boundary_node;++n)
725  {
726  Node* nod_pt = this->Bulk_mesh_pt->boundary_node_pt(b,n);
727  //If we are not on the top or bottom boundary unpin
728  if((!(nod_pt->is_on_boundary(0))) &&
729  (!(nod_pt->is_on_boundary(2))) &&
730  (!(nod_pt->is_on_boundary(4))))
731  {
732  unsigned lm_index = dynamic_cast<BoundaryNodeBase*>(nod_pt)
733  ->index_of_first_value_assigned_by_face_element(
735  nod_pt->unpin(lm_index);
736 
737  }
738 
739  }
740  }
741 
742 
743 
744 
745  //Reassign the equation number
746  std::cout << "Surface unpinned to give "
747  << assign_eqn_numbers() << " equation numbers\n";
748  }
749  }
void unpin_position(const unsigned &i)
Unpin the nodal position.
Definition: nodes.h:1829

References b, e(), i, oomph::Node::is_on_boundary(), n, oomph::FiniteElement::nnode(), oomph::FiniteElement::node_pt(), oomph::Data::unpin(), and oomph::SolidNode::unpin_position().

◆ unpin_surface() [2/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::unpin_surface ( )
inline

Release the free surface so that it can move.

656  {
657  //Only bother if the surface is pinned
658  if(Surface_pinned)
659  {
660  Surface_pinned = false;
661 
662  //Unpin the heights of all nodes not on the boundaries
663  unsigned n_node = Bulk_mesh_pt->nnode();
664  for(unsigned n=0;n<n_node;n++)
665  {
666  SolidNode* nod_pt = static_cast<SolidNode*>(Bulk_mesh_pt->node_pt(n));
667  if(!(nod_pt->is_on_boundary(0) || nod_pt->is_on_boundary(2)))
668  {
669  nod_pt->unpin_position(1);
670  }
671  }
672 
673  // Loop over the elements to re-enable ALE
674  unsigned n_element = Bulk_mesh_pt->nelement();
675  for(unsigned i=0;i<n_element;i++)
676  {
677  // Upcast from GeneralsedElement to the present element
678  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(i));
679  el_pt->enable_ALE();
680  }
681 
682  //Unpin the interfacial surfactant concentrations and Lagrange multipliers
683  unsigned n_interface = Surface_mesh_pt->nelement();
684  for(unsigned i=0;i<n_interface;i++)
685  {
687 
688  //Need to unpin the values of surfactant concentration and Lagrange multiplier
689  unsigned n_el_node = el_pt->nnode();
690  for(unsigned n=0;n<n_el_node;++n)
691  {
692  Node* nod_pt = el_pt->node_pt(n);
693  nod_pt->unpin(4);
694  nod_pt->unpin(5);
695  }
696  }
697 
698 
699  //Now unpin the bulk concentrations in the lower region
700  const unsigned n_lower = Bulk_mesh_pt->nlower();
701  // Loop over bulk elements in lower fluid
702  for(unsigned e=0;e<n_lower;e++)
703  {
704  // Upcast from GeneralisedElement to the present element
705  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
706  lower_layer_element_pt(e));
707  unsigned n_node = el_pt->nnode();
708  for(unsigned n=0;n<n_node;++n)
709  {
710  el_pt->node_pt(n)->unpin(2); //Bulk Concentration
711  el_pt->node_pt(n)->pin(3);
712  //el_pt->node_pt(n)->unpin(3); //Micelle Concentration
713  }
714  }
715 
716  //We also need to unpin the Lagrange multipliers for periodicity
717  //We must not clash with the lagrange multiplier used to drive
718  //the interface so we pin that at the left-hand-side
719  {
720  unsigned b=3;
721  unsigned n_boundary_node = this->Bulk_mesh_pt->nboundary_node(b);
722  for(unsigned n=0;n<n_boundary_node;++n)
723  {
724  Node* nod_pt = this->Bulk_mesh_pt->boundary_node_pt(b,n);
725  //If we are not on the top or bottom boundary unpin
726  if((!(nod_pt->is_on_boundary(0))) &&
727  (!(nod_pt->is_on_boundary(2))) &&
728  (!(nod_pt->is_on_boundary(4))))
729  {
730  unsigned lm_index = dynamic_cast<BoundaryNodeBase*>(nod_pt)
731  ->index_of_first_value_assigned_by_face_element(
733  nod_pt->unpin(lm_index);
734 
735  }
736 
737  }
738  }
739 
740 
741 
742 
743  //Reassign the equation number
744  std::cout << "Surface unpinned to give "
745  << assign_eqn_numbers() << " equation numbers\n";
746  }
747  }

References b, e(), i, oomph::Node::is_on_boundary(), n, oomph::FiniteElement::nnode(), oomph::FiniteElement::node_pt(), oomph::Data::unpin(), and oomph::SolidNode::unpin_position().

◆ unpin_surface() [3/3]

template<class ELEMENT , class INTERFACE_ELEMENT >
void SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::unpin_surface ( )
inline

Release the free surface so that it can move.

276  {
277  //Only bother if the surface is pinned
278  if(Surface_pinned)
279  {
280  Surface_pinned = false;
281 
282  //Unpin the heights of all the spines in the middle
283  unsigned n_spine = Bulk_mesh_pt->nspine();
284  for(unsigned n=0;n<n_spine;n++)
285  {
286  Bulk_mesh_pt->spine_pt(n)->spine_height_pt()->unpin(0);
287  }
288 
289  // Loop over the elements to re-enable ALE
290  unsigned n_element = Bulk_mesh_pt->nelement();
291  for(unsigned i=0;i<n_element;i++)
292  {
293  // Upcast from GeneralsedElement to the present element
294  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->element_pt(i));
295 
296  el_pt->enable_ALE();
297 
298  //For testing this is where you can pin the pressures
299  //unsigned n_internal = el_pt->ninternal_data();
300  //for(unsigned i=0;i<n_internal;++i)
301  // {
302  // el_pt->internal_data_pt(i)->pin_all();
303  // }
304  }
305 
306  //Pin the velocities
307  /*unsigned n_node = Bulk_mesh_pt->nnode();
308  for(unsigned n=0;n<n_node;++n)
309  {
310  Bulk_mesh_pt->node_pt(n)->pin(0);
311  Bulk_mesh_pt->node_pt(n)->pin(1);
312  }*/
313 
314 
315 
316  //Unpin the interfacial surfactant concentrations
317  unsigned n_interface = Surface_mesh_pt->nelement();
318  for(unsigned i=0;i<n_interface;i++)
319  {
321 
322  //Need to unpin the values of concentration and micelle
323  unsigned n_el_node = el_pt->nnode();
324  for(unsigned n=0;n<n_el_node;++n)
325  {
326  el_pt->node_pt(n)->unpin(4);
327  }
328  }
329 
330 
331  //Now unpin the bulk concentrations in the lower region
332  const unsigned n_lower = Bulk_mesh_pt->nlower();
333  // Loop over bulk elements in lower fluid
334  for(unsigned e=0;e<n_lower;e++)
335  {
336  // Upcast from GeneralisedElement to the present element
337  ELEMENT *el_pt = dynamic_cast<ELEMENT*>(Bulk_mesh_pt->
338  lower_layer_element_pt(e));
339  unsigned n_node = el_pt->nnode();
340  for(unsigned n=0;n<n_node;++n)
341  {
342  el_pt->node_pt(n)->unpin(2); //Bulk Concentration
343  el_pt->node_pt(n)->unpin(3); //Micelle Concentration
344  }
345  }
346 
347  //Reassign the equation number
348  std::cout << "Surface unpinned to give "
349  << assign_eqn_numbers() << " equation numbers\n";
350  }
351  }

References e(), i, n, oomph::FiniteElement::nnode(), oomph::FiniteElement::node_pt(), and oomph::Data::unpin().

Member Data Documentation

◆ Backed_up_surface_mesh_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
BackupMeshForProjection< QElement< 1, 3 > > * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Backed_up_surface_mesh_pt

Storage for the back up the surface mesh.

◆ Bulk_mesh_pt [1/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
ElasticRefineableTwoLayerMesh< ELEMENT > * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Bulk_mesh_pt

Overloaded version of the problem's access function to the mesh. Recasts the pointer to the base Mesh object to the actual mesh type.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Bulk_mesh_pt [2/2]

template<class ELEMENT , class INTERFACE_ELEMENT >
TwoLayerSpineMesh<ELEMENT>* SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Bulk_mesh_pt

Overloaded version of the problem's access function to the mesh. Recasts the pointer to the base Mesh object to the actual mesh type.

◆ Constitutive_law_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
ConstitutiveLaw * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Constitutive_law_pt

Pointer to the constitutive law used to determine the mesh deformation.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Dependent_position_mesh_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Mesh* SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Dependent_position_mesh_pt

Storage for elements that constraint the vertical positions of the periodic nodes on the boundaries

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Doc_info

template<class ELEMENT , class INTERFACE_ELEMENT >
DocInfo SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Doc_info
private

◆ Inlet_traction_mesh_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Mesh * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Inlet_traction_mesh_pt

Storage for any traction elements applied to the inlet.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Monitor_node_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Node * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Monitor_node_pt
private

Node used to monitor the interface height.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Outlet_traction_mesh_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Mesh * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Outlet_traction_mesh_pt

Storage for any traction elements applied to the outlet.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Periodic_index

template<class ELEMENT , class INTERFACE_ELEMENT >
unsigned SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Periodic_index
private

Integer used to specify the Face ID of the Lagrange multipliers Used to enforce periodicity

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Point_mesh_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Mesh * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Point_mesh_pt

Storage to point elements if needed for non-periodic domains.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Slave_position_mesh_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Mesh* SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Slave_position_mesh_pt

Storage for elements that constraint the vertical positions of the periodic nodes on the boundaries

◆ Surface_mesh_pt

template<class ELEMENT , class INTERFACE_ELEMENT >
Mesh * SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Surface_mesh_pt

Storage to the mesh of Surface interface elements.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().

◆ Surface_pinned

template<class ELEMENT , class INTERFACE_ELEMENT >
bool SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::Surface_pinned
private

Boolean to indicate whether the surface is pinned.

Referenced by SurfactantProblem< ELEMENT, INTERFACE_ELEMENT >::SurfactantProblem().


The documentation for this class was generated from the following files: