TwoDDGProblem< ELEMENT > Class Template Reference
+ Inheritance diagram for TwoDDGProblem< ELEMENT >:

Public Member Functions

TwoDDGMesh< ELEMENT > * mesh_pt ()
 
 TwoDDGProblem (const unsigned &Nx, const unsigned &Ny)
 
void compute_error (const double &t, Vector< double > &error)
 Compute the complete errors in the problem. More...
 
void apply_initial_conditions ()
 
void parameter_study (std::ostream &trace, const bool &disc)
 
TwoDDGMesh< ELEMENT > * mesh_pt ()
 
 ~TwoDDGProblem ()
 
 TwoDDGProblem (const unsigned &Nx, const unsigned &Ny)
 
void compute_error (const double &t, Vector< double > &error)
 Compute the complete errors in the problem. More...
 
void apply_initial_conditions ()
 
void parameter_study (std::ostream &trace, const bool &disc)
 
TwoDDGMesh< ELEMENT > * mesh_pt ()
 
 ~TwoDDGProblem ()
 
 TwoDDGProblem (const unsigned &Nx, const unsigned &Ny)
 
void apply_initial_conditions ()
 
void limit ()
 
void parameter_study (std::ostream &trace, const bool &disc)
 
TwoDDGMesh< ELEMENT > * mesh_pt ()
 
 ~TwoDDGProblem ()
 
 TwoDDGProblem (const unsigned &Nx, const unsigned &Ny)
 
void apply_initial_conditions ()
 
void limit ()
 
void parameter_study (std::ostream &trace, const bool &disc)
 
TwoDDGMesh< ELEMENT > * mesh_pt ()
 
 ~TwoDDGProblem ()
 
 TwoDDGProblem (const unsigned &Nx, const unsigned &Ny)
 
void compute_error (const double &t, Vector< double > &error)
 Compute the complete errors in the problem. More...
 
void apply_boundary_conditions (const double &t)
 
void actions_after_explicit_stage ()
 
void apply_initial_conditions ()
 
void parameter_study (std::ostream &trace, const bool &disc)
 
- 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
 
virtual void actions_before_adapt ()
 
virtual void actions_after_adapt ()
 Actions that are to be performed after a mesh adaptation. More...
 
OomphCommunicatorcommunicator_pt ()
 access function to the oomph-lib communicator More...
 
const OomphCommunicatorcommunicator_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 ()
 
LinearSolvermass_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...
 
Timetime_pt () const
 Return a pointer to the global time object (const version). More...
 
doubletime ()
 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 TimeSteppertime_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...
 
doubleminimum_dt ()
 Access function to min timestep in adaptive timestepping. More...
 
doublemaximum_dt ()
 Access function to max timestep in adaptive timestepping. More...
 
unsignedmax_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...
 
doublemax_residuals ()
 
booltime_adaptive_newton_crash_on_solve_fail ()
 Access function for Time_adaptive_newton_crash_on_solve_fail. More...
 
doublenewton_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...
 
doubleglobal_dof_pt (const unsigned &i)
 
doubledof (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...
 
doubledof_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...
 
booluse_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 Problemmake_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 ()
 
doublebifurcation_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 ()
 
intsign_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 ()
 

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...
 
- Public Attributes inherited from oomph::Problem
bool Shut_up_in_newton_solve
 
- 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_solve ()
 
virtual void actions_after_newton_solve ()
 
virtual void actions_before_newton_convergence_check ()
 
virtual void actions_before_newton_step ()
 
virtual void actions_after_newton_step ()
 
virtual void actions_before_implicit_timestep ()
 
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)
 
doubledof_derivative (const unsigned &i)
 
doubledof_current (const unsigned &i)
 
virtual void set_initial_condition ()
 
virtual double global_temporal_error_norm ()
 
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 *, boolCalculate_dparameter_analytic
 
bool Calculate_hessian_products_analytic
 
LinearAlgebraDistributionDof_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< doubleMax_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< doubleDof_derivative
 Storage for the derivative of the problem variables wrt arc-length. More...
 
Vector< doubleDof_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
 
OomphCommunicatorCommunicator_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...
 

Constructor & Destructor Documentation

◆ TwoDDGProblem() [1/5]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::TwoDDGProblem ( const unsigned Nx,
const unsigned Ny 
)
inline
244  {
247 
249 
250  Problem::mesh_pt() = new TwoDDGMesh<ELEMENT>(Nx,Ny);
251 
252  unsigned n_element = Problem::mesh_pt()->nelement();
253  for(unsigned e=0;e<n_element;e++)
254  {
255  ELEMENT* cast_element_pt =
256  dynamic_cast<ELEMENT*>(Problem::mesh_pt()->element_pt(e));
257 
258  cast_element_pt->wind_fct_pt() = &Global::two_d_wind;
259  }
260 
261 
262  std::cout << "How many " << assign_eqn_numbers() << std::endl;
263  }
Array< double, 1, 3 > e(1./3., 0.5, 2.)
Definition: two_d_advection.cc:66
void set_explicit_time_stepper_pt(ExplicitTimeStepper *const &explicit_time_stepper_pt)
Definition: problem.cc:1586
unsigned long assign_eqn_numbers(const bool &assign_local_eqn_numbers=true)
Definition: problem.cc:1989
void disable_info_in_newton_solve()
Disable the output of information when in the newton solver.
Definition: problem.h:2941
void enable_discontinuous_formulation()
Definition: problem.h:1727
Definition: explicit_timesteppers.h:187
unsigned Nx
Number of elements in each direction (used by SimpleCubicMesh)
Definition: structured_cubic_point_source.cc:114
unsigned Ny
Definition: structured_cubic_point_source.cc:115
void two_d_wind(const oomph::Vector< double > &x, oomph::Vector< double > &wind)
Definition: two_d_advection.cc:47

References e(), oomph::Mesh::element_pt(), oomph::Problem::mesh_pt(), oomph::Mesh::nelement(), GlobalParameters::Nx, GlobalParameters::Ny, and Global::two_d_wind().

◆ ~TwoDDGProblem() [1/4]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::~TwoDDGProblem ( )
inline
381  {
382  delete Problem::mesh_pt();
383  delete this->explicit_time_stepper_pt();
384  }
ExplicitTimeStepper *& explicit_time_stepper_pt()
Return a pointer to the explicit timestepper.
Definition: problem.h:1555

References oomph::Problem::mesh_pt().

◆ TwoDDGProblem() [2/5]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::TwoDDGProblem ( const unsigned Nx,
const unsigned Ny 
)
inline
388  {
391 
393 
394  Problem::mesh_pt() = new TwoDDGMesh<ELEMENT>(Nx,Ny);
395 
396  unsigned n_element = Problem::mesh_pt()->nelement();
397  for(unsigned e=0;e<n_element;e++)
398  {
399  ELEMENT* cast_element_pt =
400  dynamic_cast<ELEMENT*>(Problem::mesh_pt()->element_pt(e));
401 
402  cast_element_pt->gamma_pt() = &Global::Gamma;
403 
404  }
405 
406  //Set the boundary conditions
407  Vector<double> u_initial(4);
408  Vector<double> x(2);
409  //Pin all boundaries
410  for(unsigned b=0;b<2;b++)
411  {
412  const unsigned n_node = mesh_pt()->nboundary_node(b);
413  for(unsigned n=0;n<n_node;n++)
414  {
415  Node* nod_pt = mesh_pt()->boundary_node_pt(b,n);
416  const unsigned n_value = nod_pt->nvalue();
417  for(unsigned i=0;i<n_value;i++) {nod_pt->pin(i);}
418  //Now set the values
419  for(unsigned i=0;i<2;i++) {x[i] = nod_pt->x(i);}
420  Global::exact_solution(0.0,x,u_initial);
421  for(unsigned i=0;i<n_value;i++) {nod_pt->set_value(i,u_initial[i]);}
422  }
423  }
424 
425 
426  std::cout << "How many " << assign_eqn_numbers() << std::endl;
427  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Scalar * b
Definition: benchVecAdd.cpp:17
TwoDDGMesh< ELEMENT > * mesh_pt()
Definition: two_d_advection.cc:239
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
unsigned nvalue() const
Return number of values stored in data object (incl pinned ones).
Definition: nodes.h:483
Definition: nodes.h:906
double & x(const unsigned &i)
Return the i-th nodal coordinate.
Definition: nodes.h:1060
double Gamma
Definition: couette.cc:44
void exact_solution(const double &t, const Vector< double > &x, Vector< double > &u)
Function that determines the initial conditions.
Definition: couette.cc:47
list x
Definition: plotDoE.py:28

References b, e(), oomph::Mesh::element_pt(), Global::exact_solution(), Global::Gamma, i, oomph::Problem::mesh_pt(), n, oomph::Mesh::nelement(), oomph::Data::nvalue(), GlobalParameters::Nx, GlobalParameters::Ny, oomph::Data::pin(), oomph::Data::set_value(), plotDoE::x, and oomph::Node::x().

◆ ~TwoDDGProblem() [2/4]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::~TwoDDGProblem ( )
inline
849  {
850  delete Problem::mesh_pt();
851  delete this->explicit_time_stepper_pt();
852  }

References oomph::Problem::mesh_pt().

◆ TwoDDGProblem() [3/5]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::TwoDDGProblem ( const unsigned Nx,
const unsigned Ny 
)
inline
856  {
859 
861 
862  Problem::mesh_pt() = new TwoDDGMesh<ELEMENT>(Nx,Ny);
863 
864  unsigned n_element = Problem::mesh_pt()->nelement();
865  for(unsigned e=0;e<n_element;e++)
866  {
867  ELEMENT* cast_element_pt =
868  dynamic_cast<ELEMENT*>(Problem::mesh_pt()->element_pt(e));
869 
870  cast_element_pt->gamma_pt() = &Global::Gamma;
871 
872  }
873 
874  //Pin the inlet boundary
875  {
876  unsigned b=3;
877  {
878  const unsigned n_node = mesh_pt()->nboundary_node(b);
879  for(unsigned n=0;n<n_node;n++)
880  {
881  Node* nod_pt = mesh_pt()->boundary_node_pt(b,n);
882  const unsigned n_value = nod_pt->nvalue();
883  for(unsigned i=0;i<n_value;i++) {nod_pt->pin(i);}
884  }
885  }
886  }
887 
888 
889  std::cout << "How many " << assign_eqn_numbers() << std::endl;
890  }
Definition: ff_step.cc:45

References b, e(), oomph::Mesh::element_pt(), Global::Gamma, i, oomph::Problem::mesh_pt(), n, oomph::Mesh::nelement(), oomph::Data::nvalue(), GlobalParameters::Nx, GlobalParameters::Ny, and oomph::Data::pin().

◆ ~TwoDDGProblem() [3/4]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::~TwoDDGProblem ( )
inline
486  {
487  delete Problem::mesh_pt();
488  delete this->explicit_time_stepper_pt();
489  }

References oomph::Problem::mesh_pt().

◆ TwoDDGProblem() [4/5]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::TwoDDGProblem ( const unsigned Nx,
const unsigned Ny 
)
inline
493  {
496 
498 
499  Problem::mesh_pt() = new TwoDDGMesh<ELEMENT>(Nx,Ny);
500 
501  unsigned n_element = Problem::mesh_pt()->nelement();
502  for(unsigned e=0;e<n_element;e++)
503  {
504  ELEMENT* cast_element_pt =
505  dynamic_cast<ELEMENT*>(Problem::mesh_pt()->element_pt(e));
506 
507  cast_element_pt->gamma_pt() = &Global::Gamma;
508 
509  }
510 
511  //Pin the inlet boundary
512  {
513  unsigned b=3;
514  {
515  const unsigned n_node = mesh_pt()->nboundary_node(b);
516  for(unsigned n=0;n<n_node;n++)
517  {
518  Node* nod_pt = mesh_pt()->boundary_node_pt(b,n);
519  const unsigned n_value = nod_pt->nvalue();
520  for(unsigned i=0;i<n_value;i++) {nod_pt->pin(i);}
521  }
522  }
523  }
524 
525 
526  std::cout << "How many " << assign_eqn_numbers() << std::endl;
527  }

References b, e(), oomph::Mesh::element_pt(), Global::Gamma, i, oomph::Problem::mesh_pt(), n, oomph::Mesh::nelement(), oomph::Data::nvalue(), GlobalParameters::Nx, GlobalParameters::Ny, and oomph::Data::pin().

◆ ~TwoDDGProblem() [4/4]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::~TwoDDGProblem ( )
inline
410  {
411  delete Problem::mesh_pt();
412  delete this->explicit_time_stepper_pt();
413  }

References oomph::Problem::mesh_pt().

◆ TwoDDGProblem() [5/5]

template<class ELEMENT >
TwoDDGProblem< ELEMENT >::TwoDDGProblem ( const unsigned Nx,
const unsigned Ny 
)
inline
417  {
420 
422 
423  Problem::mesh_pt() = new TwoDDGMesh<ELEMENT>(Nx,Ny);
424 
425  unsigned n_element = Problem::mesh_pt()->nelement();
426  for(unsigned e=0;e<n_element;e++)
427  {
428  ELEMENT* cast_element_pt =
429  dynamic_cast<ELEMENT*>(Problem::mesh_pt()->element_pt(e));
430 
431  cast_element_pt->gamma_pt() = &Global::Gamma;
432 
433  }
434 
435  //Set the boundary conditions
436  Vector<double> u_initial(4);
437  Vector<double> x(2);
438  //Pin all boundaries
439  for(unsigned b=0;b<4;b++)
440  {
441  const unsigned n_node = mesh_pt()->nboundary_node(b);
442  for(unsigned n=0;n<n_node;n++)
443  {
444  Node* nod_pt = mesh_pt()->boundary_node_pt(b,n);
445  const unsigned n_value = nod_pt->nvalue();
446  for(unsigned i=0;i<n_value;i++) {nod_pt->pin(i);}
447  //Now set the values
448  for(unsigned i=0;i<2;i++) {x[i] = nod_pt->x(i);}
449  Global::exact_solution(0.0,x,u_initial);
450  for(unsigned i=0;i<n_value;i++) {nod_pt->set_value(i,u_initial[i]);}
451  }
452  }
453 
454 
455  std::cout << "How many " << assign_eqn_numbers() << std::endl;
456  }

References b, e(), oomph::Mesh::element_pt(), Global::exact_solution(), Global::Gamma, i, oomph::Problem::mesh_pt(), n, oomph::Mesh::nelement(), oomph::Data::nvalue(), GlobalParameters::Nx, GlobalParameters::Ny, oomph::Data::pin(), oomph::Data::set_value(), plotDoE::x, and oomph::Node::x().

Member Function Documentation

◆ actions_after_explicit_stage()

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::actions_after_explicit_stage ( )
inlinevirtual

Empty virtual function that should be overloaded to update any dependent data or boundary conditions that should be advanced after each stage of an explicit time step (Runge-Kutta steps contain multiple stages per time step, most others only contain one).

Reimplemented from oomph::ExplicitTimeSteppableObject.

505  {
507  }
void apply_boundary_conditions(const double &t)
Definition: two_d_euler.cc:483
double & time()
Return the current value of continuous time.
Definition: problem.cc:11531

◆ apply_boundary_conditions()

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::apply_boundary_conditions ( const double t)
inline
484  {
485  //Set the boundary conditions
486  Vector<double> u_initial(4);
487  Vector<double> x(2);
488  //Pin all boundaries
489  for(unsigned b=0;b<4;b++)
490  {
491  const unsigned n_node = mesh_pt()->nboundary_node(b);
492  for(unsigned n=0;n<n_node;n++)
493  {
494  Node* nod_pt = mesh_pt()->boundary_node_pt(b,n);
495  const unsigned n_value = nod_pt->nvalue();
496  //Now set the values
497  for(unsigned i=0;i<2;i++) {x[i] = nod_pt->x(i);}
498  Global::exact_solution(t,x,u_initial);
499  for(unsigned i=0;i<n_value;i++) {nod_pt->set_value(i,u_initial[i]);}
500  }
501  }
502  }
t
Definition: plotPSD.py:36

References b, Global::exact_solution(), i, n, oomph::Data::nvalue(), oomph::Data::set_value(), plotPSD::t, plotDoE::x, and oomph::Node::x().

◆ apply_initial_conditions() [1/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::apply_initial_conditions ( )
inline
288  {
289  //Storage for the coordinates
290  Vector<double> x(2);
291  //Storage for the initial condition
292  Vector<double> initial_u(1);
293  //Loop over all the nodes in the mesh
294  unsigned n_node = mesh_pt()->nnode();
295  for(unsigned n=0;n<n_node;n++)
296  {
297  x[0] = mesh_pt()->node_pt(n)->x(0);
298  x[1] = mesh_pt()->node_pt(n)->x(1);
299  //Get the initial conditions
300  Global::initial_condition(0.0,x,initial_u);
301 
302  mesh_pt()->node_pt(n)->set_value(0,initial_u[0]);
303  }
304  }
void initial_condition(const double &time, const Vector< double > &x, Vector< double > &u)
Function that determines the initial conditions.
Definition: one_d_advection.cc:51

References Global::initial_condition(), n, and plotDoE::x.

◆ apply_initial_conditions() [2/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::apply_initial_conditions ( )
inline
454  {
455  //Storage for the coordinates
456  Vector<double> x(2);
457  //Storage for the initial condition
458  Vector<double> initial_u(4);
459  //Loop over all the nodes in the mesh
460  unsigned n_node = mesh_pt()->nnode();
461  for(unsigned n=0;n<n_node;n++)
462  {
463  Node* nod_pt = mesh_pt()->node_pt(n);
464  x[0] = nod_pt->x(0);
465  x[1] = nod_pt->x(1);
466  //Get the initial conditions
467  Global::exact_solution(0.0,x,initial_u);
468  //Set them
469  for(unsigned i=0;i<4;i++)
470  {
471  nod_pt->set_value(i,initial_u[i]);
472  }
473  }
474  }

References Global::exact_solution(), i, n, oomph::Data::set_value(), plotDoE::x, and oomph::Node::x().

◆ apply_initial_conditions() [3/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::apply_initial_conditions ( )
inline
893  {
894  const double gamma = Global::Gamma;
895  const double E = 1.0/(gamma-1.0) + 4.5*gamma;
896  //Loop over all the nodes in the mesh
897  unsigned n_node = mesh_pt()->nnode();
898  for(unsigned n=0;n<n_node;n++)
899  {
900  Node* nod_pt = mesh_pt()->node_pt(n);
901  //Set the values
902  nod_pt->set_value(0,gamma);
903  nod_pt->set_value(1,E);
904  nod_pt->set_value(2,3*gamma);
905  nod_pt->set_value(3,0.0);
906  }
907  }
double E
Elastic modulus.
Definition: TwenteMeshGluing.cpp:68
Mdouble gamma(Mdouble gamma_in)
This is the gamma function returns the true value for the half integer value.
Definition: ExtendedMath.cc:116

References Global_Physical_Variables::E, mathsFunc::gamma(), Global::Gamma, n, and oomph::Data::set_value().

◆ apply_initial_conditions() [4/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::apply_initial_conditions ( )
inline
530  {
531  double M = 2.0;
532  const double gamma = Global::Gamma;
533  const double E = 1.0/(gamma-1.0) + 0.5*M*M*gamma;
534  //Loop over all the nodes in the mesh
535  unsigned n_node = mesh_pt()->nnode();
536  for(unsigned n=0;n<n_node;n++)
537  {
538  Node* nod_pt = mesh_pt()->node_pt(n);
539  //Set the values
540  nod_pt->set_value(0,gamma);
541  nod_pt->set_value(1,E);
542  nod_pt->set_value(2,M*gamma);
543  nod_pt->set_value(3,0.0);
544  }
545  }
The matrix class, also used for vectors and row-vectors.
Definition: Eigen/Eigen/src/Core/Matrix.h:186

References Global_Physical_Variables::E, mathsFunc::gamma(), Global::Gamma, n, and oomph::Data::set_value().

◆ apply_initial_conditions() [5/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::apply_initial_conditions ( )
inline
511  {
512  //Storage for the coordinates
513  Vector<double> x(2);
514  //Storage for the initial condition
515  Vector<double> initial_u(4);
516  //Loop over all the nodes in the mesh
517  unsigned n_node = mesh_pt()->nnode();
518  for(unsigned n=0;n<n_node;n++)
519  {
520  Node* nod_pt = mesh_pt()->node_pt(n);
521  x[0] = nod_pt->x(0);
522  x[1] = nod_pt->x(1);
523  //Get the initial conditions
524  Global::exact_solution(0.0,x,initial_u);
525  //Set them
526  for(unsigned i=0;i<4;i++)
527  {
528  nod_pt->set_value(i,initial_u[i]);
529  }
530  }
531  }

References Global::exact_solution(), i, n, oomph::Data::set_value(), plotDoE::x, and oomph::Node::x().

◆ compute_error() [1/3]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::compute_error ( const double t,
Vector< double > &  error 
)
inline

Compute the complete errors in the problem.

267  {
268  error[0] = 0.0;
269 
270  Vector<double> local_error(1);
271  Vector<double> local_norm(1);
272 
273  const unsigned n_element = Problem::mesh_pt()->nelement();
274  //Do the timestep
275  for(unsigned e=0;e<n_element;e++)
276  {
277  dynamic_cast<ScalarAdvectionEquations<2>*>(
278  Problem::mesh_pt()->element_pt(e))
279  ->compute_error(std::cout,
280  Global::initial_condition,t,local_error,
281  local_norm);
282  error[0] += local_error[0];
283  }
284  }
void compute_error(const double &t, Vector< double > &error)
Compute the complete errors in the problem.
Definition: two_d_advection.cc:266
Base class for advection equations.
Definition: scalar_advection_elements.h:48
int error
Definition: calibrate.py:297

References oomph::compute_error(), e(), oomph::Mesh::element_pt(), calibrate::error, Global::initial_condition(), oomph::Problem::mesh_pt(), oomph::Mesh::nelement(), and plotPSD::t.

◆ compute_error() [2/3]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::compute_error ( const double t,
Vector< double > &  error 
)
inline

Compute the complete errors in the problem.

431  {
432  error.initialise(0.0);
433 
434  Vector<double> local_error(4);
435  Vector<double> local_norm(4);
436 
437  const unsigned n_element = Problem::mesh_pt()->nelement();
438  //Do the timestep
439  for(unsigned e=0;e<n_element;e++)
440  {
441  dynamic_cast<ELEMENT*>(
442  Problem::mesh_pt()->element_pt(e))
443  ->compute_error(std::cout,
444  Global::exact_solution,t,local_error,
445  local_norm);
446  for(unsigned i=0;i<4;i++)
447  {
448  error[i] += local_error[i];
449  }
450  }
451  }

References oomph::compute_error(), e(), oomph::Mesh::element_pt(), calibrate::error, Global::exact_solution(), i, oomph::Problem::mesh_pt(), oomph::Mesh::nelement(), and plotPSD::t.

◆ compute_error() [3/3]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::compute_error ( const double t,
Vector< double > &  error 
)
inline

Compute the complete errors in the problem.

460  {
461  error.initialise(0.0);
462 
463  Vector<double> local_error(4);
464  Vector<double> local_norm(4);
465 
466  const unsigned n_element = Problem::mesh_pt()->nelement();
467  //Do the timestep
468  for(unsigned e=0;e<n_element;e++)
469  {
470  dynamic_cast<ELEMENT*>(
471  Problem::mesh_pt()->element_pt(e))
472  ->compute_error(std::cout,
473  Global::exact_solution,t,local_error,
474  local_norm);
475  for(unsigned i=0;i<4;i++)
476  {
477  error[i] += local_error[i];
478  }
479  }
480  }

References oomph::compute_error(), e(), oomph::Mesh::element_pt(), calibrate::error, Global::exact_solution(), i, oomph::Problem::mesh_pt(), oomph::Mesh::nelement(), and plotPSD::t.

◆ limit() [1/2]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::limit ( )
inline
910  {
911  const double eps = 1.0e-14;
912  //First stage is to calculate the averages of all elements
913  const unsigned n_element = this->mesh_pt()->nelement();
914  for(unsigned e=0;e<n_element;e++)
915  {
916  //Calculate the averages
917  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e))
918  ->allocate_memory_for_averages();
919  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e))->calculate_averages();
920  }
921 
922  Vector<double> s(2,0.0), x(2);
923 
924  const unsigned n_flux = 4;
925 
926  const unsigned n_dim = 2;
927 
928 
929  //Store pointers to neighbours
930  DenseMatrix<ELEMENT*> bulk_neighbour(n_element,4);
931  //Storage for the unknowns
932  Vector<double> interpolated_u(n_flux);
933 
934  //Now we need to actually do the limiting, but let's check things first
935  for(unsigned e=0;e<n_element;e++)
936  {
937  //Store the element
938  ELEMENT* cast_element_pt =
939  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
940  //Find the centre of the element
941  cast_element_pt->interpolated_x(s,x);
942 
943 
944  //Storage for the approximation to the central gradient from all four
945  //faces
946  RankThreeTensor<double> grad(4,n_flux,2);
947  //Storage for the neighbours size
948  Vector<double> size(4);
949 
950  //Get the local coordinate of the nodes
951  Vector<double> s_face(1), s_bulk(2);
952  //Get the central value
953  DenseMatrix<double> prim_centre(2,n_flux);
954  //My Centre
955  for(unsigned i=0;i<n_flux;i++)
956  {interpolated_u[i] = cast_element_pt->average_value(i);}
957  prim_centre(0,0) = interpolated_u[0];
958  prim_centre(0,1) = cast_element_pt->pressure(interpolated_u);
959  prim_centre(0,2) = interpolated_u[2]/interpolated_u[0];
960  prim_centre(0,3) = interpolated_u[3]/interpolated_u[0];
961 
962  //Now store the average primitivee values
963  for(unsigned i=0;i<n_flux;i++)
964  {cast_element_pt->average_prim_value(i) = prim_centre(0,i);}
965 
966  //Loop over all the faces
967  for(unsigned f=0;f<4;f++)
968  {
969  DGFaceElement* face_element_pt =
970  dynamic_cast<DGFaceElement*>(cast_element_pt->face_element_pt(f));
971 
972  //Get the average of the nodal points on the face
973  //(***NOT GENERAL**)
974  const unsigned n_face_node = face_element_pt->nnode();
975 
976  //Storage for the average nodal values
977  DenseMatrix<double> face_average(n_face_node,n_flux);
978 
979  //Storage for the neighbouring cell's centre average
980  DenseMatrix<double> cell_average(n_face_node,n_flux);
981 
982  //Storage for the sizes of the neighbouring bulk elements
983  Vector<double> neighbour_size(n_face_node);
984 
985  //Now the storage for the nodal values and centre values
986  DenseMatrix<double> nodal_x(n_face_node,n_dim);
987  //Now the storage for the centre values
988  DenseMatrix<double> centre_x(n_face_node,n_dim);
989 
990  //Neighbours face
991  FaceElement* neighbour_face_pt=0;
992 
993  //Now calculate those average values
994  for(unsigned n=0;n<n_face_node;n++)
995  {
996  //Get the local coordinates of the node
997  face_element_pt->local_coordinate_of_node(n,s_face);
998  //Get the global coordinate of the node
999  for(unsigned i=0;i<n_dim;i++)
1000  {
1001  nodal_x(n,i) = face_element_pt->interpolated_x(s_face,i);
1002  }
1003 
1004  //Get the flux at the node in this face
1005  face_element_pt->interpolated_u(s_face,interpolated_u);
1006 
1007  /*std::cout << "Values at face :";
1008  for(unsigned i=0;i<n_flux;i++)
1009  {
1010  std::cout << interpolated_u[i] << " ";
1011  }
1012  std::cout << std::endl;*/
1013 
1014  for(unsigned i=0;i<n_flux;i++)
1015  {
1016  face_average(n,i) = interpolated_u[i];
1017  }
1018 
1019  //Now get the bulk coordinate
1020  face_element_pt->get_local_coordinate_in_bulk(s_face,s_bulk);
1021  //Now get the neighbour
1022  cast_element_pt->
1023  get_neighbouring_face_and_local_coordinate(
1024  face_element_pt->face_index(),s_bulk,neighbour_face_pt,s_face);
1025 
1026  //Get the fluxes of the neighbour
1027  dynamic_cast<DGFaceElement*>(neighbour_face_pt)
1028  ->interpolated_u(s_face,interpolated_u);
1029  //Add the flux from the neighbour
1030  ELEMENT* neighbour_bulk_element_pt = dynamic_cast<ELEMENT*>(
1031  neighbour_face_pt->bulk_element_pt());
1032 
1033  /*std::cout << "Values at face neighbour :";
1034  for(unsigned i=0;i<n_flux;i++)
1035  {
1036  std::cout << interpolated_u[i] << " ";
1037  }
1038  std::cout << std::endl;
1039 
1040  std::cout << "SANITY CHECK " << face_element_pt << " "
1041  << neighbour_face_pt << " "
1042  << cast_element_pt << " "
1043  << neighbour_bulk_element_pt << "\n";*/
1044 
1045 
1046  //Get the centre of the neighbouring bulk element
1047  for(unsigned i=0;i<n_dim;i++) {s_bulk[i] = 0.0;}
1048  //Do it
1049  for(unsigned i=0;i<n_dim;i++)
1050  {
1051  centre_x(n,i) = neighbour_bulk_element_pt
1052  ->interpolated_x(s_bulk,i);
1053  }
1054 
1055  for(unsigned i=0;i<n_flux;i++)
1056  {
1057  face_average(n,i) += interpolated_u[i];
1058  face_average(n,i) *= 0.5;
1059  //Get the neighbour
1060  cell_average(n,i) = neighbour_bulk_element_pt->average_value(i);
1061  }
1062 
1063  //Get the size of the neighbour
1064  neighbour_size[n] = neighbour_bulk_element_pt->average_value(n_flux);
1065 
1066  //Only bother to store the first one
1067  if(n==0)
1068  {
1069  bulk_neighbour(e,f) = neighbour_bulk_element_pt;
1070  }
1071  }
1072 
1073  //Now we have the face averages and the cell averages
1074  //Check that we have a conforming mesh
1075  for(unsigned n=1;n<n_face_node;n++)
1076  {
1077  if((std::abs(centre_x(0,0) - centre_x(n,0)) > eps) ||
1078  (std::abs(centre_x(0,1) - centre_x(n,1)) > eps))
1079  {
1080  throw OomphLibError("Mesh is not conforming in limiter",
1083  }
1084  }
1085 
1086 
1087  //Set centre_x(0,0) to be the current element
1088  for(unsigned i=0;i<n_dim;i++)
1089  {
1090  centre_x(0,i) = x[i];
1091  }
1092 
1093  //Set the size of the neighbour
1094  size[f] = neighbour_size[0];
1095 
1096  //Convert our values to primitive variables
1097  DenseMatrix<double> prim_nodal(2,n_flux);
1098 
1099  //Face averages (corner nodes)
1100  //std::cout << "Nodal values \n";
1101  for(unsigned n=0;n<2;n++)
1102  {
1103  //Load the fluxes
1104  for(unsigned i=0;i<n_flux;i++)
1105  {interpolated_u[i] = face_average(n,i);}
1106 
1107  //Output the fluxes
1108  /*std::cout << n << " : ";
1109  for(unsigned i=0;i<n_flux;i++)
1110  {std::cout << interpolated_u[i] << " ";}
1111  std::cout << std::endl;*/
1112 
1113  prim_nodal(n,0) = interpolated_u[0];
1114  prim_nodal(n,1) = cast_element_pt->pressure(interpolated_u);
1115  prim_nodal(n,2) = interpolated_u[2]/interpolated_u[0];
1116  prim_nodal(n,3) = interpolated_u[3]/interpolated_u[0];
1117  }
1118 
1119  //Neighbours centre (use value from first node
1120  for(unsigned i=0;i<n_flux;i++)
1121  {interpolated_u[i] = cell_average(0,i);}
1122 
1123  /*std::cout << "Neighbour centre : ";
1124  for(unsigned i=0;i<n_flux;i++)
1125  {std::cout << interpolated_u[i] << " ";}
1126  std::cout << std::endl;*/
1127 
1128  prim_centre(1,0) = interpolated_u[0];
1129  //Should really use neighbour here
1130  prim_centre(1,1) = cast_element_pt->pressure(interpolated_u);
1131  prim_centre(1,2) = interpolated_u[2]/interpolated_u[0];
1132  prim_centre(1,3) = interpolated_u[3]/interpolated_u[0];
1133 
1134 
1135  //We can now estimate the gradients
1136 
1137 
1138  //Output first
1139  /*std::cout << "Centre " << x[0] << " " << x[1] << " : ";
1140  for(unsigned i=0;i<n_flux;i++)
1141  {std::cout << prim_centre(0,i) << " ";}
1142 
1143  std::cout << "\n Neighbour " << centre_x(0,0) << " "
1144  << centre_x(0,1) << " : ";
1145  for(unsigned i=0;i<n_flux;i++)
1146  {std::cout << prim_centre(1,i) << " ";}
1147 
1148  for(unsigned n=0;n<2;n++)
1149  {
1150  std::cout << "\n Node " << nodal_x(n,0) << " "
1151  << nodal_x(n,1) << " : ";
1152  for(unsigned i=0;i<n_flux;i++)
1153  {std::cout << prim_nodal(n,i) << " ";}
1154  }
1155  std::cout << std::endl;*/
1156 
1157 
1158  double x_len = centre_x(1,0) - centre_x(0,0);
1159  double y_len = centre_x(1,1) - centre_x(0,1);
1160 
1161  double X_len = nodal_x(1,0) - nodal_x(0,0);
1162  double Y_len = nodal_x(1,1) - nodal_x(0,1);
1163 
1164  //If we have ghost cell's handle it!
1165  if((std::abs(x_len) < eps) && (std::abs(y_len) < eps))
1166  {
1167  //The distance is twice the distance from the centre to
1168  //the midpoint of the edges
1169  double X_mid = nodal_x(0,0) + 0.5*X_len;
1170  double Y_mid = nodal_x(0,1) + 0.5*Y_len;
1171 
1172  x_len = 2.0*(X_mid - centre_x(0,0));
1173  y_len = 2.0*(Y_mid - centre_x(0,1));
1174  }
1175 
1176  double A = X_len*y_len + x_len*Y_len;
1177 
1178  for(unsigned i=0;i<n_flux;i++)
1179  {
1180  grad(f,i,0) =
1181  ((prim_centre(1,i) - prim_centre(0,i))*Y_len
1182  - (prim_nodal(1,i) - prim_nodal(0,i))*y_len)/A;
1183  grad(f,i,1) =
1184  ((prim_centre(1,i) - prim_centre(0,i))*X_len
1185  - (prim_nodal(1,i) - prim_nodal(0,i))*x_len)/A;
1186  }
1187  }
1188 
1189  //Let's output the face gradients
1190  /*for(unsigned f=0;f<4;f++)
1191  {
1192  std::cout << "Neighbour " << size[f] << " : ";
1193  for(unsigned i=0;i<n_flux;i++)
1194  {
1195  std::cout << grad(f,i,0) << " " << grad(f,i,1) << " ";
1196  }
1197  std::cout << std::endl;
1198  }*/
1199 
1200  //Zero out the gradients
1201  for(unsigned i=0;i<n_flux;i++)
1202  {
1203  for(unsigned j=0;j<2;j++)
1204  {
1205  cast_element_pt->average_gradient(i,j) = 0.0;
1206  }
1207  }
1208 
1209  double sum = 0.0;
1210  for(unsigned f=0;f<4;f++)
1211  {
1212  const double A = size[f];
1213  sum += A;
1214  for(unsigned i=0;i<n_flux;i++)
1215  {
1216  for(unsigned j=0;j<2;j++)
1217  {
1218  cast_element_pt->average_gradient(i,j) += A*grad(f,i,j);
1219  }
1220  }
1221  }
1222 
1223  //Divide by the combined sum
1224  for(unsigned i=0;i<n_flux;i++)
1225  {
1226  for(unsigned j=0;j<2;j++)
1227  {
1228  cast_element_pt->average_gradient(i,j) /= sum;
1229  }
1230  }
1231  }
1232 
1233  //Let's have a look at it
1234  /*for(unsigned e=0;e<n_element;e++)
1235  {
1236  std::cout << "Approximate gradient in element " << e << " : ";
1237  for(unsigned i=0;i<n_flux;i++)
1238  {
1239  for(unsigned j=0;j<2;j++)
1240  {
1241  std::cout << dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e))->
1242  average_gradient(i,j) << " " ;
1243  }
1244  }
1245  std::cout << "\n";
1246  }*/
1247 
1248  //OK now we use the weighted gradients to construct our limited gradient
1249  const double eps2 = 1.0e-10;
1250 
1251  for(unsigned e=0;e<n_element;e++)
1252  {
1253  ELEMENT* cast_element_pt =
1254  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
1255 
1256  /*std::cout << "Base element \n";
1257  cast_element_pt->output(std::cout);*/
1258 
1259  DenseMatrix<double> g(n_flux,4,0.0);
1260 
1261  //Get the neighbours
1262  for(unsigned f=0;f<4;f++)
1263  {
1264  ELEMENT* neighbour_bulk_element_pt = bulk_neighbour(e,f);
1265 
1266  /*std::cout << "Neighbour face" << f << "\n";
1267  neighbour_bulk_element_pt->output(std::cout);*/
1268 
1269 
1270  //Now sort it out
1271  for(unsigned i=0;i<n_flux;i++)
1272  {
1273  for(unsigned j=0;j<2;j++)
1274  {
1275  g(i,f) +=
1276  std::pow(neighbour_bulk_element_pt->average_gradient(i,j),2.0);
1277  }
1278  }
1279  }
1280 
1281  DenseMatrix<double> limited_gradient(n_flux,2,0.0);
1282 
1283  //Let's now see it
1284  for(unsigned i=0;i<n_flux;i++)
1285  {
1286 
1287  //Calcaulte the denominators
1288  double denom = 4.0*eps2;
1289  for(unsigned f=0;f<4;f++) {denom += g(i,f)*g(i,f)*g(i,f);}
1290 
1291  //Calculate the weights
1292  Vector<double> w(4,0.0);
1293  w[0] = (g(i,1)*g(i,2)*g(i,3) + eps2)/denom;
1294  w[1] = (g(i,0)*g(i,2)*g(i,3) + eps2)/denom;
1295  w[2] = (g(i,0)*g(i,1)*g(i,3) + eps2)/denom;
1296  w[3] = (g(i,0)*g(i,1)*g(i,2) + eps2)/denom;
1297 
1298  //Now reconstruct the limited gradient
1299  for(unsigned f=0;f<4;f++)
1300  {
1301  for(unsigned j=0;j<2;j++)
1302  {
1303  limited_gradient(i,j) +=
1304  w[f]*bulk_neighbour(e,f)->average_gradient(i,j);
1305  }
1306  }
1307  }
1308 
1309  //std::cout << "In element " << e << " :\n ";
1310  //We should now have the limited gradients for all fluxe
1311  /*for(unsigned i=0;i<n_flux;i++)
1312  {
1313  std::cout << cast_element_pt->average_gradient(i,0) << " "
1314  << cast_element_pt->average_gradient(i,1) << " : ";
1315  std::cout << limited_gradient(i,0) << " "
1316  << limited_gradient(i,1) << "\n";
1317  }
1318  std::cout << "\n";*/
1319 
1320  //Now we have limited the primitive variables we have to evaluate the
1321  //values at each node
1322  const unsigned n_node = cast_element_pt->nnode();
1323  //Find the centre of the element
1324  cast_element_pt->interpolated_x(s,x);
1325 
1326 
1327  //Work out distances to the nodes
1328  DenseMatrix<double> dx(n_node,2);
1329  for(unsigned n=0;n<n_node;n++)
1330  {
1331  Node* nod_pt = cast_element_pt->node_pt(n);
1332  for(unsigned i=0;i<n_dim;i++) {dx(n,i) = nod_pt->x(i) - x[i];}
1333  }
1334 
1335  //New gradients of primitive values
1336  DenseMatrix<double> dprim(n_node,n_flux);
1337 
1338 
1339  //Reconstruct limited primitive value gradients
1340  for(unsigned n=0;n<n_node;n++)
1341  {
1342  for(unsigned i=0;i<n_flux;i++)
1343  {
1344  dprim(n,i) = dx(n,0)*limited_gradient(i,0)
1345  + dx(n,1)*limited_gradient(i,1);
1346  }
1347  }
1348 
1349  //Limited values
1350  DenseMatrix<double> limited_value(n_node,n_flux);
1351  //Density
1352  for(unsigned n=0;n<n_node;n++)
1353  {
1354  limited_value(n,0) =
1355  cast_element_pt->average_prim_value(0) + dprim(n,0);
1356  }
1357 
1358  //If any are too small correct
1359  double min = 1.0e-2;
1360  bool loop_flag=false;
1361  do
1362  {
1363  bool limit_more=false;
1364  for(unsigned n=0;n<n_node;n++)
1365  {
1366  //If we're too small, reduce the gradient
1367  if(limited_value(n,0) < min)
1368  {
1369  limit_more=true;
1370  break;
1371  }
1372  }
1373 
1374  //Now do we limit more
1375  if(limit_more)
1376  {
1377  std::cout << "Limiting density gradient further \n";
1378  limited_gradient(0,0) *= 0.5;
1379  limited_gradient(0,1) *= 0.5;
1380  //Calculated the densities again
1381  for(unsigned n=0;n<n_node;n++)
1382  {
1383  limited_value(n,0) = cast_element_pt->average_prim_value(0)
1384  + dx(n,0)*limited_gradient(0,0)
1385  + dx(n,1)*limited_gradient(0,1);
1386  }
1387  //Loop again
1388  loop_flag = true;
1389  }
1390  } while(loop_flag);
1391 
1392  //Reconstruct the momentum
1393  for(unsigned n=0;n<n_node;n++)
1394  {
1395  for(unsigned i=0;i<2;i++)
1396  {
1397  limited_value(n,2+i) =
1398  cast_element_pt->average_value(2+i)
1399  + cast_element_pt->average_prim_value(0)*dprim(n,2+i)
1400  + cast_element_pt->average_prim_value(2+i)*dprim(n,0);
1401  }
1402  }
1403 
1404  //Now reconstruct the energy
1405  const double gamma = cast_element_pt->gamma();
1406 
1407  for(unsigned n=0;n<n_node;n++)
1408  {
1409  limited_value(n,1) = cast_element_pt->average_value(1)
1410  + (1.0/(gamma-1.0))*dprim(n,1)
1411  + 0.5*dprim(n,0)*(cast_element_pt->average_prim_value(2)*
1412  cast_element_pt->average_prim_value(2) +
1413  cast_element_pt->average_prim_value(3)*
1414  cast_element_pt->average_prim_value(3))
1415  + cast_element_pt->average_prim_value(0)*(
1416  cast_element_pt->average_prim_value(2)*dprim(2,n) +
1417  cast_element_pt->average_prim_value(3)*dprim(3,n));
1418  }
1419 
1420  //Check for negative pressures
1421  bool negative_pressure = false;
1422  for(unsigned n=0;n<n_node;n++)
1423  {
1424  for(unsigned i=0;i<n_flux;i++)
1425  {interpolated_u[i] = limited_value(n,i);}
1426 
1427  //Get the pressure
1428  double p = cast_element_pt->pressure(interpolated_u);
1429  if(p < eps2) {negative_pressure = true; break;}
1430  }
1431 
1432  //Correct negative pressure by limiting energy gradient to zero
1433  if(negative_pressure)
1434  {
1435  std::cout << "Correcting negative pressure\n";
1436  //If the average value is zero, then set the average value from
1437  //the average velocities
1438  double average_E = cast_element_pt->average_value(1);
1439  double rho_u = cast_element_pt->average_value(2);
1440  double rho_v = cast_element_pt->average_value(3);
1441  double rho = cast_element_pt->average_value(0);
1442 
1443  //Find the average kinetic energy
1444  double kin = 0.5*(rho_u*rho_u + rho_v*rho_v)/rho;
1445 
1446  //If the average energy is less than the average kinetic energy
1447  //we will have negative pressures (we don't want this!)
1448  if(average_E < kin)
1449  {
1450  if(average_E < 0)
1451  {
1452  throw OomphLibError("Real problem energy negative\n",
1455  }
1456 
1457  //Keep the ratio of the momentum transport the same
1458  double ratio = rho_u/rho_v;
1459 
1460  //Find the sign of rho_v
1461  int sign = 1;
1462  if(rho_v < 0.0) {sign *= -1;}
1463 
1464  double sum_square_momenta = 2.0*average_E*rho;
1465 
1466  //Reset the values preserving the sign of v
1467  rho_v = sign*sqrt(sum_square_momenta/(1.0 + ratio*ratio));
1468  rho_u = ratio*rho_v;
1469  }
1470 
1471  for(unsigned n=0;n<n_node;n++)
1472  {
1473  //Set consistent averages
1474  limited_value(n,0) = rho;
1475  limited_value(n,1) = average_E;
1476  limited_value(n,2) = rho_u;
1477  limited_value(n,3) = rho_v;
1478  }
1479  }
1480 
1481  //Will have to think about boundary conditions
1482 
1483  //Finally set the limited values
1484  for(unsigned n=0;n<n_node;n++)
1485  {
1486  //Cache the node
1487  Node* nod_pt = cast_element_pt->node_pt(n);
1488  for(unsigned i=0;i<n_flux;i++)
1489  {
1490  //Only limit if it's not pinned!
1491  if(!nod_pt->is_pinned(i))
1492  {
1493  /*std::cout << "Limiting " <<
1494  nod_pt->value(i) << " to " <<
1495  limited_value(n,i) << "\n";*/
1496  //Do it
1497  nod_pt->set_value(i,limited_value(n,i));
1498  }
1499  }
1500  }
1501  }
1502 
1503  }
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
RowVector3d w
Definition: Matrix_resize_int.cpp:3
float * p
Definition: Tutorial_Map_using.cpp:9
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
Matrix< SCALARA, Dynamic, Dynamic, opt_A > A
Definition: bench_gemm.cpp:47
Definition: dg_elements.h:50
virtual void interpolated_u(const Vector< double > &s, Vector< double > &f)
Return the interpolated values of the unknown fluxes.
Definition: dg_elements.cc:196
bool is_pinned(const unsigned &i) const
Test whether the i-th variable is pinned (1: true; 0: false).
Definition: nodes.h:417
Definition: matrices.h:386
Definition: elements.h:4338
int & face_index()
Definition: elements.h:4626
FiniteElement *& bulk_element_pt()
Pointer to higher-dimensional "bulk" element.
Definition: elements.h:4735
double interpolated_x(const Vector< double > &s, const unsigned &i) const
Definition: elements.h:4528
void get_local_coordinate_in_bulk(const Vector< double > &s, Vector< double > &s_bulk) const
Definition: elements.cc:6384
virtual void local_coordinate_of_node(const unsigned &j, Vector< double > &s) const
Definition: elements.h:1842
unsigned nnode() const
Return the number of nodes.
Definition: elements.h:2210
Definition: oomph_definitions.h:222
A Rank 3 Tensor class.
Definition: matrices.h:1370
static int f(const TensorMap< Tensor< int, 3 > > &tensor)
Definition: cxx11_tensor_map.cpp:237
#define min(a, b)
Definition: datatypes.h:22
RealScalar s
Definition: level1_cplx_impl.h:130
double eps
Definition: crbond_bessel.cc:24
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
T sign(T x)
Definition: cxx11_tensor_builtins_sycl.cpp:172
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References abs(), oomph::FaceElement::bulk_element_pt(), e(), CRBond_Bessel::eps, f(), oomph::FaceElement::face_index(), mathsFunc::gamma(), oomph::FaceElement::get_local_coordinate_in_bulk(), i, oomph::DGFaceElement::interpolated_u(), oomph::FaceElement::interpolated_x(), oomph::Data::is_pinned(), j, oomph::FiniteElement::local_coordinate_of_node(), min, n, oomph::FiniteElement::nnode(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, p, Eigen::bfloat16_impl::pow(), s, oomph::Data::set_value(), SYCL::sign(), size, sqrt(), w, plotDoE::x, and oomph::Node::x().

◆ limit() [2/2]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::limit ( )
inline
549  {
550  const double eps = 1.0e-14;
551  //First stage is to calculate the averages of all elements
552  const unsigned n_element = this->mesh_pt()->nelement();
553  for(unsigned e=0;e<n_element;e++)
554  {
555  //Calculate the averages
556  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e))
557  ->allocate_memory_for_averages();
558  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e))->calculate_averages();
559  }
560 
561  Vector<double> s(2,0.0), x(2);
562 
563  const unsigned n_flux = 4;
564 
565  const unsigned n_dim = 2;
566 
567 
568  //Store pointers to neighbours
569  DenseMatrix<ELEMENT*> bulk_neighbour(n_element,4);
570  //Storage for the unknowns
571  Vector<double> interpolated_u(n_flux);
572 
573  //Now we need to actually do the limiting, but let's check things first
574  for(unsigned e=0;e<n_element;e++)
575  {
576  //Store the element
577  ELEMENT* cast_element_pt =
578  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
579  //Find the centre of the element
580  cast_element_pt->interpolated_x(s,x);
581 
582 
583  //Storage for the approximation to the central gradient from all four
584  //faces
585  RankThreeTensor<double> grad(4,n_flux,2);
586  //Storage for the neighbours size
587  Vector<double> size(4);
588 
589  //Get the local coordinate of the nodes
590  Vector<double> s_face(1), s_bulk(2);
591  //Get the central value
592  DenseMatrix<double> prim_centre(2,n_flux);
593  //My Centre
594  for(unsigned i=0;i<n_flux;i++)
595  {interpolated_u[i] = cast_element_pt->average_value(i);}
596  prim_centre(0,0) = interpolated_u[0];
597  prim_centre(0,1) = cast_element_pt->pressure(interpolated_u);
598  prim_centre(0,2) = interpolated_u[2]/interpolated_u[0];
599  prim_centre(0,3) = interpolated_u[3]/interpolated_u[0];
600 
601  //Now store the average primitivee values
602  for(unsigned i=0;i<n_flux;i++)
603  {cast_element_pt->average_prim_value(i) = prim_centre(0,i);}
604 
605  //Loop over all the faces
606  for(unsigned f=0;f<4;f++)
607  {
608  DGFaceElement* face_element_pt =
609  dynamic_cast<DGFaceElement*>(cast_element_pt->face_element_pt(f));
610 
611  //Get the average of the nodal points on the face
612  //(***NOT GENERAL**)
613  const unsigned n_face_node = face_element_pt->nnode();
614 
615  //Storage for the average nodal values
616  DenseMatrix<double> face_average(n_face_node,n_flux);
617 
618  //Storage for the neighbouring cell's centre average
619  DenseMatrix<double> cell_average(n_face_node,n_flux);
620 
621  //Storage for the sizes of the neighbouring bulk elements
622  Vector<double> neighbour_size(n_face_node);
623 
624  //Now the storage for the nodal values and centre values
625  DenseMatrix<double> nodal_x(n_face_node,n_dim);
626  //Now the storage for the centre values
627  DenseMatrix<double> centre_x(n_face_node,n_dim);
628 
629  //Neighbours face
630  FaceElement* neighbour_face_pt=0;
631 
632  //Now calculate those average values
633  for(unsigned n=0;n<n_face_node;n++)
634  {
635  //Get the local coordinates of the node
636  face_element_pt->local_coordinate_of_node(n,s_face);
637  //Get the global coordinate of the node
638  for(unsigned i=0;i<n_dim;i++)
639  {
640  nodal_x(n,i) = face_element_pt->interpolated_x(s_face,i);
641  }
642 
643  //Get the flux at the node in this face
644  face_element_pt->interpolated_u(s_face,interpolated_u);
645 
646  /*std::cout << "Values at face :";
647  for(unsigned i=0;i<n_flux;i++)
648  {
649  std::cout << interpolated_u[i] << " ";
650  }
651  std::cout << std::endl;*/
652 
653  for(unsigned i=0;i<n_flux;i++)
654  {
655  face_average(n,i) = interpolated_u[i];
656  }
657 
658  //Now get the bulk coordinate
659  face_element_pt->get_local_coordinate_in_bulk(s_face,s_bulk);
660  //Now get the neighbour
661  cast_element_pt->
662  get_neighbouring_face_and_local_coordinate(
663  face_element_pt->face_index(),s_bulk,neighbour_face_pt,s_face);
664 
665  //Get the fluxes of the neighbour
666  dynamic_cast<DGFaceElement*>(neighbour_face_pt)
667  ->interpolated_u(s_face,interpolated_u);
668  //Add the flux from the neighbour
669  ELEMENT* neighbour_bulk_element_pt = dynamic_cast<ELEMENT*>(
670  neighbour_face_pt->bulk_element_pt());
671 
672  /*std::cout << "Values at face neighbour :";
673  for(unsigned i=0;i<n_flux;i++)
674  {
675  std::cout << interpolated_u[i] << " ";
676  }
677  std::cout << std::endl;
678 
679  std::cout << "SANITY CHECK " << face_element_pt << " "
680  << neighbour_face_pt << " "
681  << cast_element_pt << " "
682  << neighbour_bulk_element_pt << "\n";*/
683 
684 
685  //Get the centre of the neighbouring bulk element
686  for(unsigned i=0;i<n_dim;i++) {s_bulk[i] = 0.0;}
687  //Do it
688  for(unsigned i=0;i<n_dim;i++)
689  {
690  centre_x(n,i) = neighbour_bulk_element_pt
691  ->interpolated_x(s_bulk,i);
692  }
693 
694  for(unsigned i=0;i<n_flux;i++)
695  {
696  face_average(n,i) += interpolated_u[i];
697  face_average(n,i) *= 0.5;
698  //Get the neighbour
699  cell_average(n,i) = neighbour_bulk_element_pt->average_value(i);
700  }
701 
702  //Get the size of the neighbour
703  neighbour_size[n] = neighbour_bulk_element_pt->average_value(n_flux);
704 
705  //Only bother to store the first one
706  if(n==0)
707  {
708  bulk_neighbour(e,f) = neighbour_bulk_element_pt;
709  }
710  }
711 
712  //Now we have the face averages and the cell averages
713  //Check that we have a conforming mesh
714  for(unsigned n=1;n<n_face_node;n++)
715  {
716  if((std::abs(centre_x(0,0) - centre_x(n,0)) > eps) ||
717  (std::abs(centre_x(0,1) - centre_x(n,1)) > eps))
718  {
719  throw OomphLibError("Mesh is not conforming in limiter",
722  }
723  }
724 
725 
726  //Set centre_x(0,0) to be the current element
727  for(unsigned i=0;i<n_dim;i++)
728  {
729  centre_x(0,i) = x[i];
730  }
731 
732  //Set the size of the neighbour
733  size[f] = neighbour_size[0];
734 
735  //Convert our values to primitive variables
736  DenseMatrix<double> prim_nodal(2,n_flux);
737 
738  //Face averages (corner nodes)
739  //std::cout << "Nodal values \n";
740  for(unsigned n=0;n<2;n++)
741  {
742  //Load the fluxes
743  for(unsigned i=0;i<n_flux;i++)
744  {interpolated_u[i] = face_average(n,i);}
745 
746  //Output the fluxes
747  /*std::cout << n << " : ";
748  for(unsigned i=0;i<n_flux;i++)
749  {std::cout << interpolated_u[i] << " ";}
750  std::cout << std::endl;*/
751 
752  prim_nodal(n,0) = interpolated_u[0];
753  prim_nodal(n,1) = cast_element_pt->pressure(interpolated_u);
754  prim_nodal(n,2) = interpolated_u[2]/interpolated_u[0];
755  prim_nodal(n,3) = interpolated_u[3]/interpolated_u[0];
756  }
757 
758  //Neighbours centre (use value from first node
759  for(unsigned i=0;i<n_flux;i++)
760  {interpolated_u[i] = cell_average(0,i);}
761 
762  /*std::cout << "Neighbour centre : ";
763  for(unsigned i=0;i<n_flux;i++)
764  {std::cout << interpolated_u[i] << " ";}
765  std::cout << std::endl;*/
766 
767  prim_centre(1,0) = interpolated_u[0];
768  //Should really use neighbour here
769  prim_centre(1,1) = cast_element_pt->pressure(interpolated_u);
770  prim_centre(1,2) = interpolated_u[2]/interpolated_u[0];
771  prim_centre(1,3) = interpolated_u[3]/interpolated_u[0];
772 
773 
774  //We can now estimate the gradients
775 
776 
777  //Output first
778  /*std::cout << "Centre " << x[0] << " " << x[1] << " : ";
779  for(unsigned i=0;i<n_flux;i++)
780  {std::cout << prim_centre(0,i) << " ";}
781 
782  std::cout << "\n Neighbour " << centre_x(0,0) << " "
783  << centre_x(0,1) << " : ";
784  for(unsigned i=0;i<n_flux;i++)
785  {std::cout << prim_centre(1,i) << " ";}
786 
787  for(unsigned n=0;n<2;n++)
788  {
789  std::cout << "\n Node " << nodal_x(n,0) << " "
790  << nodal_x(n,1) << " : ";
791  for(unsigned i=0;i<n_flux;i++)
792  {std::cout << prim_nodal(n,i) << " ";}
793  }
794  std::cout << std::endl;*/
795 
796 
797  double x_len = centre_x(1,0) - centre_x(0,0);
798  double y_len = centre_x(1,1) - centre_x(0,1);
799 
800  double X_len = nodal_x(1,0) - nodal_x(0,0);
801  double Y_len = nodal_x(1,1) - nodal_x(0,1);
802 
803  //If we have ghost cell's handle it!
804  if((std::abs(x_len) < eps) && (std::abs(y_len) < eps))
805  {
806  //The distance is twice the distance from the centre to
807  //the midpoint of the edges
808  double X_mid = nodal_x(0,0) + 0.5*X_len;
809  double Y_mid = nodal_x(0,1) + 0.5*Y_len;
810 
811  x_len = 2.0*(X_mid - centre_x(0,0));
812  y_len = 2.0*(Y_mid - centre_x(0,1));
813  }
814 
815  double A = X_len*y_len + x_len*Y_len;
816 
817  for(unsigned i=0;i<n_flux;i++)
818  {
819  grad(f,i,0) =
820  ((prim_centre(1,i) - prim_centre(0,i))*Y_len
821  - (prim_nodal(1,i) - prim_nodal(0,i))*y_len)/A;
822  grad(f,i,1) =
823  ((prim_centre(1,i) - prim_centre(0,i))*X_len
824  - (prim_nodal(1,i) - prim_nodal(0,i))*x_len)/A;
825  }
826  }
827 
828  //Let's output the face gradients
829  /*for(unsigned f=0;f<4;f++)
830  {
831  std::cout << "Neighbour " << size[f] << " : ";
832  for(unsigned i=0;i<n_flux;i++)
833  {
834  std::cout << grad(f,i,0) << " " << grad(f,i,1) << " ";
835  }
836  std::cout << std::endl;
837  }*/
838 
839  //Zero out the gradients
840  for(unsigned i=0;i<n_flux;i++)
841  {
842  for(unsigned j=0;j<2;j++)
843  {
844  cast_element_pt->average_gradient(i,j) = 0.0;
845  }
846  }
847 
848  double sum = 0.0;
849  for(unsigned f=0;f<4;f++)
850  {
851  const double A = size[f];
852  sum += A;
853  for(unsigned i=0;i<n_flux;i++)
854  {
855  for(unsigned j=0;j<2;j++)
856  {
857  cast_element_pt->average_gradient(i,j) += A*grad(f,i,j);
858  }
859  }
860  }
861 
862  //Divide by the combined sum
863  for(unsigned i=0;i<n_flux;i++)
864  {
865  for(unsigned j=0;j<2;j++)
866  {
867  cast_element_pt->average_gradient(i,j) /= sum;
868  }
869  }
870  }
871 
872  //Let's have a look at it
873  /*for(unsigned e=0;e<n_element;e++)
874  {
875  std::cout << "Approximate gradient in element " << e << " : ";
876  for(unsigned i=0;i<n_flux;i++)
877  {
878  for(unsigned j=0;j<2;j++)
879  {
880  std::cout << dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e))->
881  average_gradient(i,j) << " " ;
882  }
883  }
884  std::cout << "\n";
885  }*/
886 
887  //OK now we use the weighted gradients to construct our limited gradient
888  const double eps2 = 1.0e-10;
889 
890  for(unsigned e=0;e<n_element;e++)
891  {
892  ELEMENT* cast_element_pt =
893  dynamic_cast<ELEMENT*>(mesh_pt()->element_pt(e));
894 
895  /*std::cout << "Base element \n";
896  cast_element_pt->output(std::cout);*/
897 
898  DenseMatrix<double> g(n_flux,4,0.0);
899 
900  //Get the neighbours
901  for(unsigned f=0;f<4;f++)
902  {
903  ELEMENT* neighbour_bulk_element_pt = bulk_neighbour(e,f);
904 
905  /*std::cout << "Neighbour face" << f << "\n";
906  neighbour_bulk_element_pt->output(std::cout);*/
907 
908 
909  //Now sort it out
910  for(unsigned i=0;i<n_flux;i++)
911  {
912  for(unsigned j=0;j<2;j++)
913  {
914  g(i,f) +=
915  std::pow(neighbour_bulk_element_pt->average_gradient(i,j),2.0);
916  }
917  }
918  }
919 
920  DenseMatrix<double> limited_gradient(n_flux,2,0.0);
921 
922  //Let's now see it
923  for(unsigned i=0;i<n_flux;i++)
924  {
925 
926  //Calcaulte the denominators
927  double denom = 4.0*eps2;
928  for(unsigned f=0;f<4;f++) {denom += g(i,f)*g(i,f)*g(i,f);}
929 
930  //Calculate the weights
931  Vector<double> w(4,0.0);
932  w[0] = (g(i,1)*g(i,2)*g(i,3) + eps2)/denom;
933  w[1] = (g(i,0)*g(i,2)*g(i,3) + eps2)/denom;
934  w[2] = (g(i,0)*g(i,1)*g(i,3) + eps2)/denom;
935  w[3] = (g(i,0)*g(i,1)*g(i,2) + eps2)/denom;
936 
937  //Now reconstruct the limited gradient
938  for(unsigned f=0;f<4;f++)
939  {
940  for(unsigned j=0;j<2;j++)
941  {
942  limited_gradient(i,j) +=
943  w[f]*bulk_neighbour(e,f)->average_gradient(i,j);
944  }
945  }
946  }
947 
948  //std::cout << "In element " << e << " :\n ";
949  //We should now have the limited gradients for all fluxe
950  /*for(unsigned i=0;i<n_flux;i++)
951  {
952  std::cout << cast_element_pt->average_gradient(i,0) << " "
953  << cast_element_pt->average_gradient(i,1) << " : ";
954  std::cout << limited_gradient(i,0) << " "
955  << limited_gradient(i,1) << "\n";
956  }
957  std::cout << "\n";*/
958 
959  //Now we have limited the primitive variables we have to evaluate the
960  //values at each node
961  const unsigned n_node = cast_element_pt->nnode();
962  //Find the centre of the element
963  cast_element_pt->interpolated_x(s,x);
964 
965 
966  //Work out distances to the nodes
967  DenseMatrix<double> dx(n_node,2);
968  for(unsigned n=0;n<n_node;n++)
969  {
970  Node* nod_pt = cast_element_pt->node_pt(n);
971  for(unsigned i=0;i<n_dim;i++) {dx(n,i) = nod_pt->x(i) - x[i];}
972  }
973 
974  //New gradients of primitive values
975  DenseMatrix<double> dprim(n_node,n_flux);
976 
977 
978  //Reconstruct limited primitive value gradients
979  for(unsigned n=0;n<n_node;n++)
980  {
981  for(unsigned i=0;i<n_flux;i++)
982  {
983  dprim(n,i) = dx(n,0)*limited_gradient(i,0)
984  + dx(n,1)*limited_gradient(i,1);
985  }
986  }
987 
988  //Limited values
989  DenseMatrix<double> limited_value(n_node,n_flux);
990  //Density
991  for(unsigned n=0;n<n_node;n++)
992  {
993  limited_value(n,0) =
994  cast_element_pt->average_prim_value(0) + dprim(n,0);
995  }
996 
997  //If any are too small correct
998  double min = 1.0e-2;
999  bool loop_flag=false;
1000  do
1001  {
1002  bool limit_more=false;
1003  for(unsigned n=0;n<n_node;n++)
1004  {
1005  //If we're too small, reduce the gradient
1006  if(limited_value(n,0) < min)
1007  {
1008  limit_more=true;
1009  break;
1010  }
1011  }
1012 
1013  //Now do we limit more
1014  if(limit_more)
1015  {
1016  std::cout << "Limiting density gradient further \n";
1017  limited_gradient(0,0) *= 0.5;
1018  limited_gradient(0,1) *= 0.5;
1019  //Calculated the densities again
1020  for(unsigned n=0;n<n_node;n++)
1021  {
1022  limited_value(n,0) = cast_element_pt->average_prim_value(0)
1023  + dx(n,0)*limited_gradient(0,0)
1024  + dx(n,1)*limited_gradient(0,1);
1025  }
1026  //Loop again
1027  loop_flag = true;
1028  }
1029  } while(loop_flag);
1030 
1031  //Reconstruct the momentum
1032  for(unsigned n=0;n<n_node;n++)
1033  {
1034  for(unsigned i=0;i<2;i++)
1035  {
1036  limited_value(n,2+i) =
1037  cast_element_pt->average_value(2+i)
1038  + cast_element_pt->average_prim_value(0)*dprim(n,2+i)
1039  + cast_element_pt->average_prim_value(2+i)*dprim(n,0);
1040  }
1041  }
1042 
1043  //Now reconstruct the energy
1044  const double gamma = cast_element_pt->gamma();
1045 
1046  for(unsigned n=0;n<n_node;n++)
1047  {
1048  limited_value(n,1) = cast_element_pt->average_value(1)
1049  + (1.0/(gamma-1.0))*dprim(n,1)
1050  + 0.5*dprim(n,0)*(cast_element_pt->average_prim_value(2)*
1051  cast_element_pt->average_prim_value(2) +
1052  cast_element_pt->average_prim_value(3)*
1053  cast_element_pt->average_prim_value(3))
1054  + cast_element_pt->average_prim_value(0)*(
1055  cast_element_pt->average_prim_value(2)*dprim(2,n) +
1056  cast_element_pt->average_prim_value(3)*dprim(3,n));
1057  }
1058 
1059  //Check for negative pressures
1060  bool negative_pressure = false;
1061  for(unsigned n=0;n<n_node;n++)
1062  {
1063  for(unsigned i=0;i<n_flux;i++)
1064  {interpolated_u[i] = limited_value(n,i);}
1065 
1066  //Get the pressure
1067  double p = cast_element_pt->pressure(interpolated_u);
1068  if(p < eps2) {negative_pressure = true; break;}
1069  }
1070 
1071  //Correct negative pressure by limiting energy gradient to zero
1072  if(negative_pressure)
1073  {
1074  std::cout << "Correcting negative pressure\n";
1075  //If the average value is zero, then set the average value from
1076  //the average velocities
1077  double average_E = cast_element_pt->average_value(1);
1078  double rho_u = cast_element_pt->average_value(2);
1079  double rho_v = cast_element_pt->average_value(3);
1080  double rho = cast_element_pt->average_value(0);
1081 
1082  //Find the average kinetic energy
1083  double kin = 0.5*(rho_u*rho_u + rho_v*rho_v)/rho;
1084 
1085  //If the average energy is less than the average kinetic energy
1086  //we will have negative pressures (we don't want this!)
1087  if(average_E < kin)
1088  {
1089  if(average_E < 0)
1090  {
1091  throw OomphLibError("Real problem energy negative\n",
1094  }
1095 
1096  //Keep the ratio of the momentum transport the same
1097  double ratio = rho_u/rho_v;
1098 
1099  //Find the sign of rho_v
1100  int sign = 1;
1101  if(rho_v < 0.0) {sign *= -1;}
1102 
1103  double sum_square_momenta = 2.0*average_E*rho;
1104 
1105  //Reset the values preserving the sign of v
1106  rho_v = sign*sqrt(sum_square_momenta/(1.0 + ratio*ratio));
1107  rho_u = ratio*rho_v;
1108  }
1109 
1110  for(unsigned n=0;n<n_node;n++)
1111  {
1112  //Set consistent averages
1113  limited_value(n,0) = rho;
1114  limited_value(n,1) = average_E;
1115  limited_value(n,2) = rho_u;
1116  limited_value(n,3) = rho_v;
1117  }
1118  }
1119 
1120  //Will have to think about boundary conditions
1121 
1122  //Finally set the limited values
1123  for(unsigned n=0;n<n_node;n++)
1124  {
1125  //Cache the node
1126  Node* nod_pt = cast_element_pt->node_pt(n);
1127  for(unsigned i=0;i<n_flux;i++)
1128  {
1129  //Only limit if it's not pinned!
1130  if(!nod_pt->is_pinned(i))
1131  {
1132  /*std::cout << "Limiting " <<
1133  nod_pt->value(i) << " to " <<
1134  limited_value(n,i) << "\n";*/
1135  //Do it
1136  nod_pt->set_value(i,limited_value(n,i));
1137  }
1138  }
1139  }
1140  }
1141 
1142  }

References abs(), oomph::FaceElement::bulk_element_pt(), e(), CRBond_Bessel::eps, f(), oomph::FaceElement::face_index(), mathsFunc::gamma(), oomph::FaceElement::get_local_coordinate_in_bulk(), i, oomph::DGFaceElement::interpolated_u(), oomph::FaceElement::interpolated_x(), oomph::Data::is_pinned(), j, oomph::FiniteElement::local_coordinate_of_node(), min, n, oomph::FiniteElement::nnode(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, p, Eigen::bfloat16_impl::pow(), s, oomph::Data::set_value(), SYCL::sign(), size, sqrt(), w, plotDoE::x, and oomph::Node::x().

◆ mesh_pt() [1/5]

template<class ELEMENT >
TwoDDGMesh<ELEMENT>* TwoDDGProblem< ELEMENT >::mesh_pt ( )
inline
240  {return dynamic_cast<TwoDDGMesh<ELEMENT>*>(Problem::mesh_pt());}

References oomph::Problem::mesh_pt().

◆ mesh_pt() [2/5]

template<class ELEMENT >
TwoDDGMesh<ELEMENT>* TwoDDGProblem< ELEMENT >::mesh_pt ( )
inline
377  {return dynamic_cast<TwoDDGMesh<ELEMENT>*>(Problem::mesh_pt());}

References oomph::Problem::mesh_pt().

◆ mesh_pt() [3/5]

template<class ELEMENT >
TwoDDGMesh<ELEMENT>* TwoDDGProblem< ELEMENT >::mesh_pt ( )
inline
845  {return dynamic_cast<TwoDDGMesh<ELEMENT>*>(Problem::mesh_pt());}

References oomph::Problem::mesh_pt().

◆ mesh_pt() [4/5]

template<class ELEMENT >
TwoDDGMesh<ELEMENT>* TwoDDGProblem< ELEMENT >::mesh_pt ( )
inline
482  {return dynamic_cast<TwoDDGMesh<ELEMENT>*>(Problem::mesh_pt());}

References oomph::Problem::mesh_pt().

◆ mesh_pt() [5/5]

template<class ELEMENT >
TwoDDGMesh<ELEMENT>* TwoDDGProblem< ELEMENT >::mesh_pt ( )
inline
406  {return dynamic_cast<TwoDDGMesh<ELEMENT>*>(Problem::mesh_pt());}

References oomph::Problem::mesh_pt().

◆ parameter_study() [1/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::parameter_study ( std::ostream &  trace,
const bool disc 
)
inline
307  {
308  this->enable_mass_matrix_reuse();
309  double dt = 0.001;
311 
312  Vector<double> error(1,0.0);
313  char filename[100];
314 
315  unsigned count=1;
316  for(unsigned t=0;t<500;t++)
317  {
318  explicit_timestep(dt);
319  if(count==250)
320  {
321  if(disc)
322  {
323  sprintf(filename,"disc_%li_time%g.dat",mesh_pt()->nelement(),time());
324  }
325  else
326  {
327  sprintf(filename,"cont_%li_time%g.dat",mesh_pt()->nelement(),time());
328  }
329  std::ofstream outfile(filename);
330  mesh_pt()->output(outfile);
331  count=0;
332  }
333 
334  compute_error(this->time(),error);
335  trace << mesh_pt()->nelement() << " "
336  << this->time() << " " << sqrt(error[0]) << std::endl;
337  ++count;
338  }
339  }
void apply_initial_conditions()
Definition: two_d_advection.cc:287
void explicit_timestep(const double &dt, const bool &shift_values=true)
Take an explicit timestep of size dt.
Definition: problem.cc:10918
void enable_mass_matrix_reuse()
Definition: problem.cc:11807
string filename
Definition: MergeRestartFiles.py:39

References oomph::compute_error(), calibrate::error, MergeRestartFiles::filename, sqrt(), and plotPSD::t.

◆ parameter_study() [2/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::parameter_study ( std::ostream &  trace,
const bool disc 
)
inline
477  {
478  this->enable_mass_matrix_reuse();
479  double dt = 0.001;
481 
482  Vector<double> error(4,0.0);
483  char filename[100];
484 
485  unsigned count=1;
486  for(unsigned t=0;t<200;t++)
487  {
488  explicit_timestep(dt);
489  if(count==50)
490  {
491  if(disc)
492  {
493  sprintf(filename,"disc_%li_time%g.dat",mesh_pt()->nelement(),time());
494  }
495  else
496  {
497  sprintf(filename,"cont_%li_time%g.dat",mesh_pt()->nelement(),time());
498  }
499  std::ofstream outfile(filename);
500  mesh_pt()->output(outfile);
501  count=0;
502  }
503 
504  compute_error(this->time(),error);
505  trace << mesh_pt()->nelement() << " "
506  << this->time() << " " << sqrt(error[0]) <<
507  " " << sqrt(error[1]) << " " << sqrt(error[2])
508  << " " << sqrt(error[3]) << std::endl;
509  ++count;
510  }
511  }

References oomph::compute_error(), calibrate::error, MergeRestartFiles::filename, sqrt(), and plotPSD::t.

◆ parameter_study() [3/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::parameter_study ( std::ostream &  trace,
const bool disc 
)
inline
1508  {
1509  this->enable_mass_matrix_reuse();
1510  double dt = 0.001;
1512 
1513  Vector<double> error(4,0.0);
1514  char filename[100];
1515 
1516  unsigned count=1;
1517  for(unsigned t=0;t<5000;t++)
1518  {
1519  std::cout << "Taking timestep " << t << "\n";
1520  explicit_timestep(dt);
1521  //Now limit
1522  limit();
1523  if(count==50)
1524  {
1525  if(disc)
1526  {
1527  sprintf(filename,"disc_%li_time%g.dat",mesh_pt()->nelement(),time());
1528  }
1529  else
1530  {
1531  sprintf(filename,"cont_%li_time%g.dat",mesh_pt()->nelement(),time());
1532  }
1533  std::ofstream outfile(filename);
1534  mesh_pt()->output(outfile);
1535  count=0;
1536  }
1537  trace << mesh_pt()->nelement() << " "
1538  << this->time() << std::endl;
1539  ++count;
1540  }
1541  }
void limit()
Definition: ff_step.cc:909

References calibrate::error, MergeRestartFiles::filename, and plotPSD::t.

◆ parameter_study() [4/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::parameter_study ( std::ostream &  trace,
const bool disc 
)
inline
1147  {
1148  this->enable_mass_matrix_reuse();
1149  double dt = 0.0001;
1151 
1152  Vector<double> error(4,0.0);
1153  char filename[100];
1154 
1155  unsigned count=1;
1156  for(unsigned t=0;t<5000;t++)
1157  {
1158  explicit_timestep(dt);
1159  //Now limit
1160  //limit();
1161  if(count==50)
1162  {
1163  if(disc)
1164  {
1165  sprintf(filename,"disc_%li_time%g.dat",mesh_pt()->nelement(),time());
1166  }
1167  else
1168  {
1169  sprintf(filename,"cont_%li_time%g.dat",mesh_pt()->nelement(),time());
1170  }
1171  std::ofstream outfile(filename);
1172  mesh_pt()->output(outfile);
1173  count=0;
1174  }
1175 
1176  trace << mesh_pt()->nelement() << " "
1177  << this->time() << std::endl;
1178  ++count;
1179  }
1180  }

References calibrate::error, MergeRestartFiles::filename, and plotPSD::t.

◆ parameter_study() [5/5]

template<class ELEMENT >
void TwoDDGProblem< ELEMENT >::parameter_study ( std::ostream &  trace,
const bool disc 
)
inline
534  {
535  this->enable_mass_matrix_reuse();
536  double dt = 0.001;
538 
539  Vector<double> error(4,0.0);
540  char filename[100];
541 
542  unsigned count=1;
543  for(unsigned t=0;t<50;t++)
544  {
545  explicit_timestep(dt);
546  if(count==50)
547  {
548  if(disc)
549  {
550  sprintf(filename,"disc_%li_time%g.dat",mesh_pt()->nelement(),time());
551  }
552  else
553  {
554  sprintf(filename,"cont_%li_time%g.dat",mesh_pt()->nelement(),time());
555  }
556  std::ofstream outfile(filename);
557  mesh_pt()->output(outfile);
558  count=0;
559  }
560 
561  compute_error(this->time(),error);
562  trace << mesh_pt()->nelement() << " "
563  << this->time() << " " << sqrt(error[0]) <<
564  " " << sqrt(error[1]) << " " << sqrt(error[2])
565  << " " << sqrt(error[3]) << std::endl;
566  ++count;
567  }
568  }

References oomph::compute_error(), calibrate::error, MergeRestartFiles::filename, sqrt(), and plotPSD::t.


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