oomph::PitchForkHandler Class Reference

#include <assembly_handler.h>

+ Inheritance diagram for oomph::PitchForkHandler:

Public Member Functions

 PitchForkHandler (Problem *const &problem_pt, AssemblyHandler *const &assembly_handler_pt, double *const &parameter_pt, const DoubleVector &symmetry_vector)
 Constructor, initialise the systems. More...
 
 ~PitchForkHandler ()
 Destructor return the problem to its original (non-augmented) state. More...
 
unsigned ndof (GeneralisedElement *const &elem_pt)
 Get the number of elemental degrees of freedom. More...
 
unsigned long eqn_number (GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
 Get the global equation number of the local unknown. More...
 
void get_residuals (GeneralisedElement *const &elem_pt, Vector< double > &residuals)
 Get the residuals. More...
 
void get_jacobian (GeneralisedElement *const &elem_pt, Vector< double > &residuals, DenseMatrix< double > &jacobian)
 
void get_dresiduals_dparameter (GeneralisedElement *const &elem_pt, double *const &parameter_pt, Vector< double > &dres_dparam)
 Get the derivatives of the residuals with respect to a parameter. More...
 
void get_djacobian_dparameter (GeneralisedElement *const &elem_pt, double *const &parameter_pt, Vector< double > &dres_dparam, DenseMatrix< double > &djac_dparam)
 
void get_hessian_vector_products (GeneralisedElement *const &elem_pt, Vector< double > const &Y, DenseMatrix< double > const &C, DenseMatrix< double > &product)
 
int bifurcation_type () const
 
doublebifurcation_parameter_pt () const
 
void get_eigenfunction (Vector< DoubleVector > &eigenfunction)
 
void solve_augmented_block_system ()
 Set to solve the augmented block system. More...
 
void solve_block_system ()
 Set to solve the block system. More...
 
void solve_full_system ()
 Solve non-block system. More...
 
- Public Member Functions inherited from oomph::AssemblyHandler
 AssemblyHandler ()
 Empty constructor. More...
 
virtual void dof_vector (GeneralisedElement *const &elem_pt, const unsigned &t, Vector< double > &dof)
 Return vector of dofs at time level t in the element elem_pt. More...
 
virtual void dof_pt_vector (GeneralisedElement *const &elem_pt, Vector< double * > &dof_pt)
 Return vector of pointers to dofs in the element elem_pt. More...
 
virtual doublelocal_problem_dof (Problem *const &problem_pt, const unsigned &t, const unsigned &i)
 
virtual void get_all_vectors_and_matrices (GeneralisedElement *const &elem_pt, Vector< Vector< double >> &vec, Vector< DenseMatrix< double >> &matrix)
 
virtual void get_inner_products (GeneralisedElement *const &elem_pt, Vector< std::pair< unsigned, unsigned >> const &history_index, Vector< double > &inner_product)
 
virtual void get_inner_product_vectors (GeneralisedElement *const &elem_pt, Vector< unsigned > const &history_index, Vector< Vector< double >> &inner_product_vector)
 
virtual ~AssemblyHandler ()
 Empty virtual destructor. More...
 

Private Types

enum  { Full_augmented , Block_J , Block_augmented_J }
 

Private Member Functions

unsigned global_eqn_number (const unsigned &i)
 

Private Attributes

unsigned Solve_which_system
 
ProblemProblem_pt
 Pointer to the problem. More...
 
AssemblyHandlerAssembly_handler_pt
 Pointer to the underlying (original) assembly handler. More...
 
unsigned Ndof
 
LinearAlgebraDistributionDof_distribution_pt
 Store the original dof distribution. More...
 
LinearAlgebraDistributionAugmented_dof_distribution_pt
 The augmented distribution. More...
 
double Sigma
 
DoubleVectorWithHaloEntries Y
 Storage for the null vector. More...
 
DoubleVectorWithHaloEntries Psi
 A constant vector that is specifies the symmetry being broken. More...
 
DoubleVectorWithHaloEntries C
 
DoubleVectorWithHaloEntries Count
 
Vector< unsignedGlobal_eqn_number
 
doubleParameter_pt
 Storage for the pointer to the parameter. More...
 
unsigned Nelement
 

Friends

class BlockPitchForkLinearSolver
 
class AugmentedBlockPitchForkLinearSolver
 

Detailed Description

A class that is used to assemble the augmented system that defines a pitchfork (symmetry-breaking) bifurcation. The "standard" problem must be a function of a global parameter \( \lambda \) and a solution is \(R(u,\lambda) = 0\), where \(u\) are the unknowns in the problem. A pitchfork bifurcation may be specified by the augmented system of size \(2N+2\).

\[ R(u,\lambda) + \sigma \psi = 0,\]

\[ Jy = 0,\]

\[ \langle u, \phi \rangle = 0, \]

\[ \phi \cdot y = 1.\]

In the abovem \(J\) is the usual Jacobian matrix, \(dR/du\) and \(\phi\) is a constant vector that is chosen to ensure that the null vector, \(y\), is not trivial. Here \(\sigma \) is a slack variable that is used to enforce the constraint \( \langle u, \phi \rangle = 0 \) — the inner product of the solution with the chosen symmetry vector is zero. At the bifurcation \( \sigma \) should be very close to zero. Note that this formulation means that any odd symmetry in the problem must be about zero. Moreover, we use the dot product of two vectors to calculate the inner product, rather than an integral over the domain and so the mesh must be symmetric in the appropriate directions.

Member Enumeration Documentation

◆ anonymous enum

anonymous enum
private

A little private enum to determine whether we are solving the block system or not

Enumerator
Full_augmented 
Block_J 
Block_augmented_J 
780  {
782  Block_J,
784  };
@ Full_augmented
Definition: assembly_handler.h:781
@ Block_augmented_J
Definition: assembly_handler.h:783
@ Block_J
Definition: assembly_handler.h:782

Constructor & Destructor Documentation

◆ PitchForkHandler()

oomph::PitchForkHandler::PitchForkHandler ( Problem *const &  problem_pt,
AssemblyHandler *const &  assembly_handler_pt,
double *const &  parameter_pt,
const DoubleVector symmetry_vector 
)

Constructor, initialise the systems.

Constructor: Initialise the PitchForkHandler by setting intial guesses for Sigma, Y, specifying C and Psi and calculating count.

2682  : Solve_which_system(Full_augmented), Sigma(0.0), Parameter_pt(parameter_pt)
2683  {
2684  // Set the problem pointer
2685  Problem_pt = problem_pt;
2686  // Set the assembly handler
2687  Assembly_handler_pt = assembly_handler_pt;
2688  // Set the number of degrees of freedom
2689  Ndof = Problem_pt->ndof();
2690  // Backup the distribution
2692 #ifdef OOMPH_HAS_MPI
2693  // Set the distribution flag
2694  Distributed = Problem_pt->distributed();
2695 #endif
2696 
2697  // Find the elements in the problem
2698  unsigned n_element = Problem_pt->mesh_pt()->nelement();
2699 
2700 #ifdef OOMPH_HAS_MPI
2701 
2702  // Work out all the global equations to which this processor
2703  // contributes and store the halo data in the problem
2704  Problem_pt->setup_dof_halo_scheme();
2705 
2706 #endif
2707 
2708 
2709  // Now use the dof distribution for all double vectors
2712  C.build(Dof_distribution_pt);
2714 #ifdef OOMPH_HAS_MPI
2715  Count.build_halo_scheme(Problem_pt->Halo_scheme_pt);
2716 #endif
2717 
2718  // Loop over the elements and count the entries
2719  // and number of (non-halo) elements
2720  unsigned n_non_halo_element_local = 0;
2721  for (unsigned e = 0; e < n_element; e++)
2722  {
2723  GeneralisedElement* elem_pt = Problem_pt->mesh_pt()->element_pt(e);
2724 #ifdef OOMPH_HAS_MPI
2725  // Ignore halo elements
2726  if (!elem_pt->is_halo())
2727  {
2728 #endif
2729  // Increment the number of non halo elements
2730  ++n_non_halo_element_local;
2731  // Now count the number of times the element contributes to a value
2732  unsigned n_var = assembly_handler_pt->ndof(elem_pt);
2733  for (unsigned n = 0; n < n_var; n++)
2734  {
2735  ++Count.global_value(assembly_handler_pt->eqn_number(elem_pt, n));
2736  }
2737 #ifdef OOMPH_HAS_MPI
2738  }
2739 #endif
2740  }
2741 
2742  // Add together all the counts
2743 #ifdef OOMPH_HAS_MPI
2745 
2746  // If distributed, find the total number of elements in the problem
2747  if (Distributed)
2748  {
2749  // Need to gather the total number of non halo elements
2750  MPI_Allreduce(&n_non_halo_element_local,
2751  &Nelement,
2752  1,
2753  MPI_UNSIGNED,
2754  MPI_SUM,
2755  Problem_pt->communicator_pt()->mpi_comm());
2756  }
2757  // Otherwise the total number is the same on each processor
2758  else
2759 #endif
2760  {
2761  Nelement = n_non_halo_element_local;
2762  }
2763 
2764 #ifdef OOMPH_HAS_MPI
2765  // Only add the parameter to the first processor, if distributed
2766  int my_rank = Problem_pt->communicator_pt()->my_rank();
2767  if ((!Distributed) || (my_rank == 0))
2768 #endif
2769  {
2770  // Add the parameter to the problem
2771  Problem_pt->Dof_pt.push_back(parameter_pt);
2772  }
2773 
2774  // Find length of the symmetry vector
2775  double length = symmetry_vector.norm();
2776 
2777  // Add the unknowns for the null vector to the problem
2778  // Normalise the symmetry vector and initialise the null vector to the
2779  // symmetry vector and set the constant vector, c, to the
2780  // normalised symmetry vector.
2781 
2782  // Need to redistribute the symmetry vector into the (natural)
2783  // distribution of the Dofs
2784 #ifdef OOMPH_HAS_MPI
2785  // Check that the symmetry vector has the correct distribution
2786  if (!(*symmetry_vector.distribution_pt() == *Dof_distribution_pt))
2787  {
2788  throw OomphLibError(
2789  "The symmetry vector must have the same distribution as the dofs\n",
2792  }
2793 #endif
2794 
2795  // Only loop over the local unknowns
2796  const unsigned n_dof_local = Dof_distribution_pt->nrow_local();
2797  for (unsigned n = 0; n < n_dof_local; n++)
2798  {
2799  Problem_pt->Dof_pt.push_back(&Y[n]);
2800  // Psi[n] = symmetry_vector[n];
2801  Psi[n] = Y[n] = C[n] = symmetry_vector[n] / length;
2802  }
2803 
2804 
2805 #ifdef OOMPH_HAS_MPI
2806  // Set up the required halo schemes (which also synchronises)
2807  Psi.build_halo_scheme(Problem_pt->Halo_scheme_pt);
2808  Y.build_halo_scheme(Problem_pt->Halo_scheme_pt);
2809  C.build_halo_scheme(Problem_pt->Halo_scheme_pt);
2810 
2811 
2812  if ((!Distributed) || (my_rank == 0))
2813 #endif
2814  // Add the slack parameter to the problem on the first processor
2815  // if distributed
2816  {
2817  Problem_pt->Dof_pt.push_back(&Sigma);
2818  }
2819 
2820 #ifdef OOMPH_HAS_MPI
2821  if (Distributed)
2822  {
2823  unsigned augmented_first_row = 0;
2824  unsigned augmented_n_row_local = 0;
2825 
2826  // Set up the translation scheme on every processor
2827  Global_eqn_number.resize(2 * Ndof + 2);
2828  int n_proc = Problem_pt->communicator_pt()->nproc();
2829  unsigned global_eqn_count = 0;
2830  for (int d = 0; d < n_proc; d++)
2831  {
2832  // Find out the first row of the current processor
2833  if (my_rank == d)
2834  {
2835  augmented_first_row = global_eqn_count;
2836  }
2837 
2838  const unsigned n_row_local = Dof_distribution_pt->nrow_local(d);
2839  const unsigned first_row = Dof_distribution_pt->first_row(d);
2840  // Add the basic equations
2841  for (unsigned n = 0; n < n_row_local; n++)
2842  {
2843  Global_eqn_number[first_row + n] = global_eqn_count;
2844  ++global_eqn_count;
2845  }
2846  // If on the first processor add the pointer to the parameter
2847  if (d == 0)
2848  {
2849  Global_eqn_number[Ndof] = global_eqn_count;
2850  ++global_eqn_count;
2851  }
2852  // Add the eigenfunction
2853  for (unsigned n = 0; n < n_row_local; n++)
2854  {
2855  Global_eqn_number[Ndof + 1 + first_row + n] = global_eqn_count;
2856  ++global_eqn_count;
2857  }
2858  // Finally add the slack parameter
2859  if (d == 0)
2860  {
2861  Global_eqn_number[2 * Ndof + 1] = global_eqn_count;
2862  ++global_eqn_count;
2863  }
2864  // Find out the number of rows of the current processor
2865  if (my_rank == d)
2866  {
2867  augmented_n_row_local = global_eqn_count - augmented_first_row;
2868  }
2869  }
2870 
2871  // Make a new linear algebra distribution
2873  new LinearAlgebraDistribution(Problem_pt->communicator_pt(),
2874  augmented_first_row,
2875  augmented_n_row_local);
2876  }
2877  else
2878 #endif
2879  {
2880  Augmented_dof_distribution_pt = new LinearAlgebraDistribution(
2881  Problem_pt->communicator_pt(), 2 * Ndof + 2, false);
2882  }
2883 
2884  // resize
2885  // Problem_pt->Dof_distribution_pt->build(Problem_pt->communicator_pt(),
2886  // 2*Ndof+2,false);
2887 
2889 
2890  // Remove all previous sparse storage used during Jacobian assembly
2892  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Array< double, 1, 3 > e(1./3., 0.5, 2.)
void build_halo_scheme(DoubleVectorHaloScheme *const &halo_scheme_pt)
Construct the halo scheme and storage for the halo data.
Definition: double_vector_with_halo.cc:379
void sum_all_halo_and_haloed_values()
Definition: double_vector_with_halo.cc:323
double & global_value(const unsigned &i)
Direct access to global entry.
Definition: double_vector_with_halo.h:221
void build(const DoubleVector &old_vector)
Just copys the argument DoubleVector.
Definition: double_vector.cc:35
unsigned first_row() const
Definition: linear_algebra_distribution.h:261
unsigned nrow_local() const
Definition: linear_algebra_distribution.h:193
Definition: matrices.h:74
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
int my_rank() const
my rank
Definition: communicator.h:176
int nproc() const
number of processors
Definition: communicator.h:157
LinearAlgebraDistribution * Dof_distribution_pt
Store the original dof distribution.
Definition: assembly_handler.h:804
Problem * Problem_pt
Pointer to the problem.
Definition: assembly_handler.h:794
DoubleVectorWithHaloEntries Y
Storage for the null vector.
Definition: assembly_handler.h:814
AssemblyHandler * Assembly_handler_pt
Pointer to the underlying (original) assembly handler.
Definition: assembly_handler.h:797
double Sigma
Definition: assembly_handler.h:811
unsigned Solve_which_system
Definition: assembly_handler.h:791
unsigned Ndof
Definition: assembly_handler.h:801
DoubleVectorWithHaloEntries Psi
A constant vector that is specifies the symmetry being broken.
Definition: assembly_handler.h:817
double * Parameter_pt
Storage for the pointer to the parameter.
Definition: assembly_handler.h:835
Vector< unsigned > Global_eqn_number
Definition: assembly_handler.h:832
unsigned Nelement
Definition: assembly_handler.h:838
DoubleVectorWithHaloEntries Count
Definition: assembly_handler.h:828
LinearAlgebraDistribution * Augmented_dof_distribution_pt
The augmented distribution.
Definition: assembly_handler.h:807
unsigned long ndof() const
Return the number of dofs.
Definition: problem.h:1674
Vector< Vector< unsigned > > Sparse_assemble_with_arrays_previous_allocation
Definition: problem.h:667
OomphCommunicator * communicator_pt()
access function to the oomph-lib communicator
Definition: problem.h:1246
Vector< double * > Dof_pt
Vector of pointers to dofs.
Definition: problem.h:554
Mesh *& mesh_pt()
Return a pointer to the global mesh.
Definition: problem.h:1280
LinearAlgebraDistribution * Dof_distribution_pt
Definition: problem.h:460
bool distributed() const
Definition: problem.h:808
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86

References Assembly_handler_pt, Augmented_dof_distribution_pt, oomph::DoubleVector::build(), oomph::DoubleVectorWithHaloEntries::build_halo_scheme(), oomph::Problem::communicator_pt(), Count, oomph::Problem::distributed(), oomph::DistributableLinearAlgebraObject::distribution_pt(), Dof_distribution_pt, oomph::Problem::Dof_distribution_pt, oomph::Problem::Dof_pt, e(), oomph::Mesh::element_pt(), oomph::AssemblyHandler::eqn_number(), oomph::LinearAlgebraDistribution::first_row(), Global_eqn_number, oomph::DoubleVectorWithHaloEntries::global_value(), oomph::Problem::mesh_pt(), oomph::OomphCommunicator::my_rank(), n, Ndof, oomph::Problem::ndof(), oomph::AssemblyHandler::ndof(), Nelement, oomph::Mesh::nelement(), oomph::DoubleVector::norm(), oomph::OomphCommunicator::nproc(), oomph::LinearAlgebraDistribution::nrow_local(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Problem_pt, Psi, Sigma, oomph::Problem::Sparse_assemble_with_arrays_previous_allocation, oomph::DoubleVectorWithHaloEntries::sum_all_halo_and_haloed_values(), and Y.

◆ ~PitchForkHandler()

oomph::PitchForkHandler::~PitchForkHandler ( )

Destructor return the problem to its original (non-augmented) state.

Destructor, return the problem to its original state, before the augmented system was added

2898  {
2899  // If we are using the block solver reset the problem's linear solver
2900  // to the original one
2901  BlockPitchForkLinearSolver* block_pitchfork_solver_pt =
2903 
2904  if (block_pitchfork_solver_pt)
2905  {
2906  // Reset the problem's linear solver
2908  block_pitchfork_solver_pt->linear_solver_pt();
2909  // Delete the block solver
2910  delete block_pitchfork_solver_pt;
2911  }
2912 
2913  // If we are using the augmented
2914  // block solver reset the problem's linear solver
2915  // to the original one
2916  AugmentedBlockPitchForkLinearSolver* augmented_block_pitchfork_solver_pt =
2917  dynamic_cast<AugmentedBlockPitchForkLinearSolver*>(
2919 
2920  if (augmented_block_pitchfork_solver_pt)
2921  {
2922  // Reset the problem's linear solver
2924  augmented_block_pitchfork_solver_pt->linear_solver_pt();
2925  // Delete the block solver
2926  delete augmented_block_pitchfork_solver_pt;
2927  }
2928 
2929  // Now return the problem to its original size
2930  Problem_pt->Dof_pt.resize(this->Dof_distribution_pt->nrow_local());
2931 
2932  // Problem_pt->Dof_pt.resize(Ndof);
2933  // Problem_pt->Dof_distribution_pt->build(Problem_pt->communicator_pt(),
2934  // Ndof,false);
2935 
2937  // Remove all previous sparse storage used during Jacobian assembly
2939  }
friend class AugmentedBlockPitchForkLinearSolver
Definition: assembly_handler.h:775
friend class BlockPitchForkLinearSolver
Definition: assembly_handler.h:774
LinearSolver *& linear_solver_pt()
Return a pointer to the linear solver object.
Definition: problem.h:1466

References Dof_distribution_pt, oomph::Problem::Dof_distribution_pt, oomph::Problem::Dof_pt, oomph::Problem::linear_solver_pt(), oomph::BlockPitchForkLinearSolver::linear_solver_pt(), oomph::AugmentedBlockPitchForkLinearSolver::linear_solver_pt(), oomph::LinearAlgebraDistribution::nrow_local(), Problem_pt, and oomph::Problem::Sparse_assemble_with_arrays_previous_allocation.

Member Function Documentation

◆ bifurcation_parameter_pt()

double* oomph::PitchForkHandler::bifurcation_parameter_pt ( ) const
inlinevirtual

Return a pointer to the bifurcation parameter in bifurcation tracking problems

Reimplemented from oomph::AssemblyHandler.

925  {
926  return Parameter_pt;
927  }

References Parameter_pt.

◆ bifurcation_type()

int oomph::PitchForkHandler::bifurcation_type ( ) const
inlinevirtual

Indicate that we are tracking a pitchfork bifurcation by returning 2

Reimplemented from oomph::AssemblyHandler.

918  {
919  return 2;
920  }

◆ eqn_number()

unsigned long oomph::PitchForkHandler::eqn_number ( GeneralisedElement *const &  elem_pt,
const unsigned ieqn_local 
)
virtual

Get the global equation number of the local unknown.

Reimplemented from oomph::AssemblyHandler.

2976  {
2977  // Get the raw value
2978  unsigned raw_ndof = elem_pt->ndof();
2979  unsigned long global_eqn = 0;
2980 
2981  // Which system are we solving
2982  switch (Solve_which_system)
2983  {
2984  // In the block case, it's just the standard numbering
2985  case Block_J:
2986  global_eqn = elem_pt->eqn_number(ieqn_local);
2987  break;
2988 
2989  // Block augmented not done properly yet
2990  case Block_augmented_J:
2991  // Not done the distributed case
2992 #ifdef OOMPH_HAS_MPI
2993  if (Distributed)
2994  {
2995  throw OomphLibError(
2996  "Block Augmented solver not implemented for distributed case\n",
2999  }
3000 #endif
3001 
3002  // Full case
3003  case Full_augmented:
3004  // The usual equations
3005  if (ieqn_local < raw_ndof)
3006  {
3007  global_eqn = this->global_eqn_number(elem_pt->eqn_number(ieqn_local));
3008  }
3009  // The bifurcation parameter equation
3010  else if (ieqn_local == raw_ndof)
3011  {
3012  global_eqn = this->global_eqn_number(Ndof);
3013  }
3014  // If we are assembling the full system we also have
3015  // The components of the null vector
3016  else if (ieqn_local < (2 * raw_ndof + 1))
3017  {
3018  global_eqn = this->global_eqn_number(
3019  Ndof + 1 + elem_pt->eqn_number(ieqn_local - 1 - raw_ndof));
3020  }
3021  // The slack parameter
3022  else
3023  {
3024  global_eqn = this->global_eqn_number(2 * Ndof + 1);
3025  }
3026  break;
3027  } // End of switch
3028  return global_eqn;
3029  }
unsigned global_eqn_number(const unsigned &i)
Definition: assembly_handler.h:848

References Block_augmented_J, Block_J, oomph::GeneralisedElement::eqn_number(), Full_augmented, global_eqn_number(), Ndof, oomph::GeneralisedElement::ndof(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and Solve_which_system.

Referenced by oomph::AugmentedBlockPitchForkLinearSolver::resolve(), and oomph::AugmentedBlockPitchForkLinearSolver::solve().

◆ get_djacobian_dparameter()

void oomph::PitchForkHandler::get_djacobian_dparameter ( GeneralisedElement *const &  elem_pt,
double *const &  parameter_pt,
Vector< double > &  dres_dparam,
DenseMatrix< double > &  djac_dparam 
)
virtual

Overload the derivative of the residuals and jacobian with respect to a parameter so that it breaks

Overload the derivative of the residuals and jacobian with respect to a parameter so that it breaks because it should not be required

Reimplemented from oomph::AssemblyHandler.

3399  {
3400  std::ostringstream error_stream;
3401  error_stream
3402  << "This function has not been implemented because it is not required\n";
3403  error_stream << "in standard problems.\n";
3404  error_stream
3405  << "If you find that you need it, you will have to implement it!\n\n";
3406 
3407  throw OomphLibError(
3408  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3409  }

References OOMPH_CURRENT_FUNCTION, and OOMPH_EXCEPTION_LOCATION.

◆ get_dresiduals_dparameter()

void oomph::PitchForkHandler::get_dresiduals_dparameter ( GeneralisedElement *const &  elem_pt,
double *const &  parameter_pt,
Vector< double > &  dres_dparam 
)
virtual

Get the derivatives of the residuals with respect to a parameter.

Overload the derivatives of the residuals with respect to a parameter to apply to the augmented system

Reimplemented from oomph::AssemblyHandler.

3320  {
3321  // Need to get raw residuals and jacobian
3322  unsigned raw_ndof = elem_pt->ndof();
3324  // Find out which system we are solving
3325  switch (Solve_which_system)
3326  {
3327  // If we are solving the original system
3328  case Block_J:
3329  {
3330  // get the basic residual derivatives
3331  elem_pt->get_dresiduals_dparameter(parameter_pt, dres_dparam);
3332  // Slack parameter term does not depened explicitly on the parameter
3333  // so is not added
3334  }
3335  break;
3336 
3337  // If we are solving the augmented-by-one system
3338  case Block_augmented_J:
3339  {
3340  // Get the basic residual derivatives
3341  elem_pt->get_dresiduals_dparameter(parameter_pt, dres_dparam);
3342 
3343  // Zero the final residuals derivative
3344  dres_dparam[raw_ndof] = 0.0;
3345 
3346  // Other terms must not depend on the parameter
3347  }
3348  break;
3349 
3350  // Otherwise we are solving the fully augemented system
3351  case Full_augmented:
3352  {
3353  DenseMatrix<double> djac_dparam(raw_ndof);
3354 
3355  // Get the basic residuals and jacobian derivatives
3356  elem_pt->get_djacobian_dparameter(
3357  parameter_pt, dres_dparam, djac_dparam);
3358 
3359  // The "final" residual derivatives do not depend on the parameter
3360  dres_dparam[raw_ndof] = 0.0;
3361  dres_dparam[2 * raw_ndof + 1] = 0.0;
3362 
3363  // Now multiply to fill in the residuals associated
3364  // with the null vector condition
3365  for (unsigned i = 0; i < raw_ndof; i++)
3366  {
3367  dres_dparam[raw_ndof + 1 + i] = 0.0;
3368  for (unsigned j = 0; j < raw_ndof; j++)
3369  {
3370  unsigned local_unknown = elem_pt->eqn_number(j);
3371  dres_dparam[raw_ndof + 1 + i] +=
3372  djac_dparam(i, j) * Y.global_value(local_unknown);
3373  }
3374  }
3375  }
3376  break;
3377 
3378  default:
3379  std::ostringstream error_stream;
3380  error_stream
3381  << "The Solve_which_system flag can only take values 0, 1, 2"
3382  << " not " << Solve_which_system << "\n";
3383  throw OomphLibError(
3384  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3385  }
3386  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
virtual void actions_before_newton_convergence_check()
Definition: problem.h:1048
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References oomph::Problem::actions_before_newton_convergence_check(), Block_augmented_J, Block_J, oomph::GeneralisedElement::eqn_number(), Full_augmented, oomph::GeneralisedElement::get_djacobian_dparameter(), oomph::GeneralisedElement::get_dresiduals_dparameter(), oomph::DoubleVectorWithHaloEntries::global_value(), i, j, oomph::GeneralisedElement::ndof(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Problem_pt, Solve_which_system, and Y.

◆ get_eigenfunction()

void oomph::PitchForkHandler::get_eigenfunction ( Vector< DoubleVector > &  eigenfunction)
virtual

Return the eigenfunction(s) associated with the bifurcation that has been detected in bifurcation tracking problems

Reimplemented from oomph::AssemblyHandler.

3431  {
3432  // There is only one (real) null vector
3433  eigenfunction.resize(1);
3434  // Rebuild the vector
3435  eigenfunction[0].build(this->Dof_distribution_pt, 0.0);
3436  // Set the value to be the null vector
3437  const unsigned n_row_local = eigenfunction[0].nrow_local();
3438  for (unsigned n = 0; n < n_row_local; n++)
3439  {
3440  eigenfunction[0][n] = Y[n];
3441  }
3442  }

References Dof_distribution_pt, n, and Y.

◆ get_hessian_vector_products()

void oomph::PitchForkHandler::get_hessian_vector_products ( GeneralisedElement *const &  elem_pt,
Vector< double > const &  Y,
DenseMatrix< double > const &  C,
DenseMatrix< double > &  product 
)
virtual

Overload the hessian vector product function so that it breaks

Overload the hessian vector product function so that it calls the underlying element's hessian function.

Reimplemented from oomph::AssemblyHandler.

3421  {
3422  elem_pt->get_hessian_vector_products(Y, C, product);
3423  }
void product(const MatrixType &m)
Definition: product.h:42

References oomph::GeneralisedElement::get_hessian_vector_products(), product(), and Y.

◆ get_jacobian()

void oomph::PitchForkHandler::get_jacobian ( GeneralisedElement *const &  elem_pt,
Vector< double > &  residuals,
DenseMatrix< double > &  jacobian 
)
virtual

Calculate the elemental Jacobian matrix "d equation / d variable".

ALICE:

ALICE

Reimplemented from oomph::AssemblyHandler.

3140  {
3141  unsigned augmented_ndof = ndof(elem_pt);
3142  unsigned raw_ndof = elem_pt->ndof();
3143 
3144  // Which system are we solving
3145  switch (Solve_which_system)
3146  {
3147  // If we are solving the original system
3148  case Block_J:
3149  {
3150  // get the raw residuals and jacobian
3151  elem_pt->get_jacobian(residuals, jacobian);
3152 
3153  // Now multiply to fill in the residuals for the final term
3154  for (unsigned i = 0; i < raw_ndof; i++)
3155  {
3156  unsigned local_eqn = elem_pt->eqn_number(i);
3157  // Add the slack parameter to the final residuals
3158  residuals[i] +=
3159  Sigma * Psi.global_value(local_eqn) / Count.global_value(local_eqn);
3160  }
3161  }
3162  break;
3163 
3164  // If we are solving the augmented-by-one system
3165  case Block_augmented_J:
3166  {
3167  // Get the full residuals, we need them
3168  get_residuals(elem_pt, residuals);
3169 
3170  // Need to get the raw jacobian (and raw residuals)
3171  Vector<double> newres(augmented_ndof);
3172  elem_pt->get_jacobian(newres, jacobian);
3173 
3174  // Now do finite differencing stuff
3175  const double FD_step = 1.0e-8;
3176  // Fill in the first lot of finite differences
3177  {
3178  // increase the global parameter
3179  double* unknown_pt = Parameter_pt;
3180  double init = *unknown_pt;
3181  *unknown_pt += FD_step;
3182 
3183  // Not do any possible updates
3185 
3186  // Get the new (modified) residuals
3187  get_residuals(elem_pt, newres);
3188 
3189  // The final column is given by the difference
3190  // between the residuals
3191  for (unsigned n = 0; n < raw_ndof; n++)
3192  {
3193  jacobian(n, augmented_ndof - 1) =
3194  (newres[n] - residuals[n]) / FD_step;
3195  }
3196  // Reset the global parameter
3197  *unknown_pt = init;
3198 
3199  // Now do any possible updates
3201  }
3202 
3203  // Fill in the bottom row
3204  for (unsigned n = 0; n < raw_ndof; n++)
3205  {
3206  unsigned local_eqn = elem_pt->eqn_number(n);
3207  jacobian(augmented_ndof - 1, n) =
3208  Psi.global_value(local_eqn) / Count.global_value(local_eqn);
3209  }
3210  }
3211  break;
3212 
3213  // Otherwise solving the full system
3214  case Full_augmented:
3215  {
3218  // Get the basic jacobian and residuals
3219  elem_pt->get_jacobian(residuals, jacobian);
3220  // get the proper residuals
3221  get_residuals(elem_pt, residuals);
3222 
3223  // Now fill in the next diagonal jacobian entry
3224  for (unsigned n = 0; n < raw_ndof; n++)
3225  {
3226  for (unsigned m = 0; m < raw_ndof; m++)
3227  {
3228  jacobian(raw_ndof + 1 + n, raw_ndof + 1 + m) = jacobian(n, m);
3229  }
3230  unsigned local_eqn = elem_pt->eqn_number(n);
3231  // Add in the sigma contribution
3232  jacobian(n, 2 * raw_ndof + 1) =
3233  Psi.global_value(local_eqn) / Count.global_value(local_eqn);
3234  // Symmetry constraint
3235  jacobian(raw_ndof, n) =
3236  Psi.global_value(local_eqn) / Count.global_value(local_eqn);
3237  // Non-zero constraint
3238  jacobian(2 * raw_ndof + 1, raw_ndof + 1 + n) =
3239  C.global_value(local_eqn) / Count.global_value(local_eqn);
3240  }
3241 
3242  // Finite difference the remaining blocks
3243  const double FD_step = 1.0e-8;
3244 
3245  Vector<double> newres_p(augmented_ndof);
3246 
3247  // Loop over the ndofs only
3248  for (unsigned n = 0; n < raw_ndof; ++n)
3249  {
3250  // Get the original (unaugmented) global equation number
3251  unsigned long global_eqn =
3252  Assembly_handler_pt->eqn_number(elem_pt, n);
3253  double* unknown_pt = Problem_pt->global_dof_pt(global_eqn);
3254  double init = *unknown_pt;
3255  *unknown_pt += FD_step;
3257  // Get the new residuals
3258  get_residuals(elem_pt, newres_p);
3259  // Fill in the entries in the block d(Jy)/dx
3260  for (unsigned m = 0; m < raw_ndof; m++)
3261  {
3262  jacobian(raw_ndof + 1 + m, n) =
3263  (newres_p[raw_ndof + 1 + m] - residuals[raw_ndof + 1 + m]) /
3264  (FD_step);
3265  }
3266 
3267  // Reset the unknown
3268  *unknown_pt = init;
3270  }
3271 
3272  {
3273  // Now increase the global parameter
3274  double* unknown_pt = Parameter_pt;
3275  double init = *unknown_pt;
3276  *unknown_pt += FD_step;
3277 
3279  // Get the new residuals
3280  get_residuals(elem_pt, newres_p);
3281 
3282  // Add in the first block d/dx
3283  for (unsigned m = 0; m < raw_ndof; m++)
3284  {
3285  jacobian(m, raw_ndof) = (newres_p[m] - residuals[m]) / FD_step;
3286  }
3287  // Add in the second block d/dy
3288  for (unsigned m = raw_ndof + 1; m < augmented_ndof - 1; m++)
3289  {
3290  jacobian(m, raw_ndof) = (newres_p[m] - residuals[m]) / FD_step;
3291  }
3292 
3293  // Reset the unknown
3294  *unknown_pt = init;
3296  }
3297  }
3298  break;
3299 
3300  default:
3301  std::ostringstream error_stream;
3302  error_stream
3303  << "The Solve_which_system flag can only take values 0, 1, 2"
3304  << " not " << Solve_which_system << "\n";
3305  throw OomphLibError(
3306  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3307  }
3310  }
virtual unsigned long eqn_number(GeneralisedElement *const &elem_pt, const unsigned &ieqn_local)
Definition: assembly_handler.cc:82
void get_residuals(GeneralisedElement *const &elem_pt, Vector< double > &residuals)
Get the residuals.
Definition: assembly_handler.cc:3034
unsigned ndof(GeneralisedElement *const &elem_pt)
Get the number of elemental degrees of freedom.
Definition: assembly_handler.cc:2944
double * global_dof_pt(const unsigned &i)
Definition: problem.h:1764
virtual void actions_after_change_in_bifurcation_parameter()
Definition: problem.h:1151
int * m
Definition: level2_cplx_impl.h:294
double FD_step
FD step.
Definition: black_box_newton_solver.cc:54
Definition: TutorialInplaceLU.cpp:2

References oomph::Problem::actions_after_change_in_bifurcation_parameter(), oomph::Problem::actions_before_newton_convergence_check(), Assembly_handler_pt, Block_augmented_J, Block_J, Count, oomph::GeneralisedElement::eqn_number(), oomph::AssemblyHandler::eqn_number(), oomph::BlackBoxFDNewtonSolver::FD_step, Full_augmented, oomph::GeneralisedElement::get_jacobian(), get_residuals(), oomph::Problem::global_dof_pt(), oomph::DoubleVectorWithHaloEntries::global_value(), i, m, n, oomph::GeneralisedElement::ndof(), ndof(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Parameter_pt, Problem_pt, Psi, Sigma, and Solve_which_system.

Referenced by oomph::AugmentedBlockPitchForkLinearSolver::resolve(), and oomph::AugmentedBlockPitchForkLinearSolver::solve().

◆ get_residuals()

void oomph::PitchForkHandler::get_residuals ( GeneralisedElement *const &  elem_pt,
Vector< double > &  residuals 
)
virtual

Get the residuals.

Reimplemented from oomph::AssemblyHandler.

3036  {
3037  // Need to get raw residuals and jacobian
3038  unsigned raw_ndof = elem_pt->ndof();
3039 
3040  // Find out which system we are solving
3041  switch (Solve_which_system)
3042  {
3043  // If we are solving the original system
3044  case Block_J:
3045  {
3046  // get the basic residuals
3047  elem_pt->get_residuals(residuals);
3048  // Now multiply to fill in the residuals for the final term
3049  for (unsigned i = 0; i < raw_ndof; i++)
3050  {
3051  unsigned local_eqn = elem_pt->eqn_number(i);
3052  // Add the slack parameter to the final residuals
3053  residuals[i] +=
3054  Sigma * Psi.global_value(local_eqn) / Count.global_value(local_eqn);
3055  }
3056  }
3057  break;
3058 
3059  // If we are solving the augmented-by-one system
3060  case Block_augmented_J:
3061  {
3062  // Get the basic residuals
3063  elem_pt->get_residuals(residuals);
3064 
3065  // Zero the final residual
3066  residuals[raw_ndof] = 0.0;
3067  // Now multiply to fill in the residuals for the final term
3068  for (unsigned i = 0; i < raw_ndof; i++)
3069  {
3070  unsigned local_eqn = elem_pt->eqn_number(i);
3071  // Add the slack parameter to the final residuals
3072  residuals[i] +=
3073  Sigma * Psi.global_value(local_eqn) / Count.global_value(local_eqn);
3074  // Final term that specifies the symmetry
3075  residuals[raw_ndof] += ((*Problem_pt->global_dof_pt(local_eqn)) *
3076  Psi.global_value(local_eqn)) /
3077  Count.global_value(local_eqn);
3078  }
3079  }
3080  break;
3081 
3082  // Otherwise we are solving the fully augemented system
3083  case Full_augmented:
3084  {
3085  DenseMatrix<double> jacobian(raw_ndof);
3086 
3087  // Get the basic residuals and jacobian
3088  elem_pt->get_jacobian(residuals, jacobian);
3089 
3090  // Initialise the final residuals
3091  residuals[raw_ndof] = 0.0;
3092  residuals[2 * raw_ndof + 1] = -1.0 / Nelement;
3093 
3094  // Now multiply to fill in the residuals associated
3095  // with the null vector condition
3096  for (unsigned i = 0; i < raw_ndof; i++)
3097  {
3098  unsigned local_eqn = elem_pt->eqn_number(i);
3099  residuals[raw_ndof + 1 + i] = 0.0;
3100  for (unsigned j = 0; j < raw_ndof; j++)
3101  {
3102  unsigned local_unknown = elem_pt->eqn_number(j);
3103  residuals[raw_ndof + 1 + i] +=
3104  jacobian(i, j) * Y.global_value(local_unknown);
3105  }
3106 
3107  // Add the slack parameter to the governing equations
3108  residuals[i] +=
3109  Sigma * Psi.global_value(local_eqn) / Count.global_value(local_eqn);
3110 
3111  // Specify the symmetry
3112  residuals[raw_ndof] += ((*Problem_pt->global_dof_pt(local_eqn)) *
3113  Psi.global_value(local_eqn)) /
3114  Count.global_value(local_eqn);
3115  // Specify the normalisation
3116  residuals[2 * raw_ndof + 1] +=
3117  (Y.global_value(local_eqn) * C.global_value(local_eqn)) /
3118  Count.global_value(local_eqn);
3119  }
3120  }
3121  break;
3122 
3123  default:
3124  std::ostringstream error_stream;
3125  error_stream
3126  << "The Solve_which_system flag can only take values 0, 1, 2"
3127  << " not " << Solve_which_system << "\n";
3128  throw OomphLibError(
3129  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
3130  }
3131  }

References Block_augmented_J, Block_J, Count, oomph::GeneralisedElement::eqn_number(), Full_augmented, oomph::GeneralisedElement::get_jacobian(), oomph::GeneralisedElement::get_residuals(), oomph::Problem::global_dof_pt(), oomph::DoubleVectorWithHaloEntries::global_value(), i, j, oomph::GeneralisedElement::ndof(), Nelement, OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, Problem_pt, Psi, Sigma, Solve_which_system, and Y.

Referenced by get_jacobian().

◆ global_eqn_number()

unsigned oomph::PitchForkHandler::global_eqn_number ( const unsigned i)
inlineprivate

Function that is used to return map the global equations using the simplistic numbering scheme into the actual distributed scheme

849  {
850 #ifdef OOMPH_HAS_MPI
851  // If the problem is distributed I have to do something
852  if (Distributed)
853  {
854  return Global_eqn_number[i];
855  }
856  // Otherwise it's just i
857  else
858 #endif
859  {
860  return i;
861  }
862  }

References Global_eqn_number, and i.

Referenced by eqn_number().

◆ ndof()

unsigned oomph::PitchForkHandler::ndof ( GeneralisedElement *const &  elem_pt)
virtual

Get the number of elemental degrees of freedom.

Reimplemented from oomph::AssemblyHandler.

2945  {
2946  unsigned raw_ndof = elem_pt->ndof();
2947 
2948  // Return different values depending on the type of block decomposition
2949  switch (Solve_which_system)
2950  {
2951  case Full_augmented:
2952  return (2 * raw_ndof + 2);
2953  break;
2954 
2955  case Block_augmented_J:
2956  return (raw_ndof + 1);
2957  break;
2958 
2959  case Block_J:
2960  return raw_ndof;
2961  break;
2962 
2963  default:
2964  std::ostringstream error_stream;
2965  error_stream
2966  << "The Solve_which_system flag can only take values 0, 1, 2"
2967  << " not " << Solve_which_system << "\n";
2968  throw OomphLibError(
2969  error_stream.str(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION);
2970  }
2971  }

References Block_augmented_J, Block_J, Full_augmented, oomph::GeneralisedElement::ndof(), OOMPH_CURRENT_FUNCTION, OOMPH_EXCEPTION_LOCATION, and Solve_which_system.

Referenced by get_jacobian(), oomph::AugmentedBlockPitchForkLinearSolver::resolve(), and oomph::AugmentedBlockPitchForkLinearSolver::solve().

◆ solve_augmented_block_system()

void oomph::PitchForkHandler::solve_augmented_block_system ( )

Set to solve the augmented block system.

Set to solve the augmented-by-one block system.

3477  {
3478  // Only bother to do anything if we haven't already set the flag
3480  {
3481  // If we were solving the system with the original jacobian add the
3482  // parameter back
3483  if (Solve_which_system == Block_J)
3484  {
3485  Problem_pt->Dof_pt.push_back(Parameter_pt);
3486  }
3487 
3488  // Restrict the problem to the standard variables and
3489  // the bifurcation parameter only
3490  Problem_pt->Dof_distribution_pt = new LinearAlgebraDistribution(
3491  Problem_pt->communicator_pt(), Ndof + 1, false);
3492  Problem_pt->Dof_pt.resize(Ndof + 1);
3493 
3494  // Problem_pt->Dof_pt.resize(Ndof+1);
3495  // Problem_pt->Dof_distribution_pt->build(Problem_pt->communicator_pt(),
3496  // Ndof+1,false);
3497 
3498  // Remove all previous sparse storage used during Jacobian assembly
3500 
3501  // Set the solve flag
3503  }
3504  }

References Block_augmented_J, Block_J, oomph::Problem::communicator_pt(), oomph::Problem::Dof_distribution_pt, oomph::Problem::Dof_pt, Ndof, Parameter_pt, Problem_pt, Solve_which_system, and oomph::Problem::Sparse_assemble_with_arrays_previous_allocation.

Referenced by oomph::AugmentedBlockPitchForkLinearSolver::resolve(), and oomph::AugmentedBlockPitchForkLinearSolver::solve().

◆ solve_block_system()

void oomph::PitchForkHandler::solve_block_system ( )

Set to solve the block system.

Set to solve the block system. The boolean flag is used to specify whether the block decomposition should use exactly the same jacobian as the original system.

3513  {
3514  // Only bother to do anything if we haven't already set the flag
3515  if (Solve_which_system != Block_J)
3516  {
3517  // Restrict the problem to the standard variables
3518  Problem_pt->Dof_pt.resize(this->Dof_distribution_pt->nrow_local());
3520 
3521  // Problem_pt->Dof_distribution_pt->build(Problem_pt->communicator_pt(),
3522  // Ndof,false);
3523 
3524  // Remove all previous sparse storage used during Jacobian assembly
3526 
3527  // Set the solve flag
3529  }
3530  }

References Block_J, Dof_distribution_pt, oomph::Problem::Dof_distribution_pt, oomph::Problem::Dof_pt, oomph::LinearAlgebraDistribution::nrow_local(), Problem_pt, Solve_which_system, and oomph::Problem::Sparse_assemble_with_arrays_previous_allocation.

Referenced by oomph::BlockPitchForkLinearSolver::resolve(), and oomph::BlockPitchForkLinearSolver::solve().

◆ solve_full_system()

void oomph::PitchForkHandler::solve_full_system ( )

Solve non-block system.

3536  {
3537  // Only do something if we are not solving the full system
3539  {
3540 #ifdef OOMPH_HAS_MPI
3541  int my_rank = Problem_pt->communicator_pt()->my_rank();
3542 #endif
3543  // If we were solving the problem without any augementation
3544  // add the parameter again
3545  if (Solve_which_system == Block_J)
3546  {
3547 #ifdef OOMPH_HAS_MPI
3548 
3549  if ((!Distributed) || (my_rank == 0))
3550 #endif
3551  {
3552  Problem_pt->Dof_pt.push_back(Parameter_pt);
3553  }
3554  }
3555 
3556  // Always add the additional unknowns back into the problem
3557  const unsigned n_dof_local = Dof_distribution_pt->nrow_local();
3558  for (unsigned n = 0; n < n_dof_local; n++)
3559  {
3560  Problem_pt->Dof_pt.push_back(&Y[n]);
3561  }
3562 
3563 
3564 #ifdef OOMPH_HAS_MPI
3565  if ((!Distributed) || (my_rank == 0))
3566 #endif
3567  // Add the slack parameter to the problem on the first processor
3568  // if distributed
3569  {
3570  Problem_pt->Dof_pt.push_back(&Sigma);
3571  }
3572 
3573 
3574  // Delete the distribtion created in the augmented block solve
3575  if (Problem_pt->Dof_distribution_pt != this->Dof_distribution_pt)
3576  {
3578  }
3579 
3580  // update the Dof distribution
3582  // Problem_pt->Dof_distribution_pt->build(Problem_pt->communicator_pt(),
3583  // Ndof*2+2,false);
3584  // Remove all previous sparse storage used during Jacobian assembly
3586 
3587  // Set the solve flag
3589  }
3590  }

References Augmented_dof_distribution_pt, Block_J, oomph::Problem::communicator_pt(), Dof_distribution_pt, oomph::Problem::Dof_distribution_pt, oomph::Problem::Dof_pt, Full_augmented, oomph::OomphCommunicator::my_rank(), n, oomph::LinearAlgebraDistribution::nrow_local(), Parameter_pt, Problem_pt, Sigma, Solve_which_system, oomph::Problem::Sparse_assemble_with_arrays_previous_allocation, and Y.

Referenced by oomph::BlockPitchForkLinearSolver::resolve(), oomph::AugmentedBlockPitchForkLinearSolver::resolve(), oomph::BlockPitchForkLinearSolver::solve(), and oomph::AugmentedBlockPitchForkLinearSolver::solve().

Friends And Related Function Documentation

◆ AugmentedBlockPitchForkLinearSolver

◆ BlockPitchForkLinearSolver

friend class BlockPitchForkLinearSolver
friend

Member Data Documentation

◆ Assembly_handler_pt

AssemblyHandler* oomph::PitchForkHandler::Assembly_handler_pt
private

Pointer to the underlying (original) assembly handler.

Referenced by get_jacobian(), and PitchForkHandler().

◆ Augmented_dof_distribution_pt

LinearAlgebraDistribution* oomph::PitchForkHandler::Augmented_dof_distribution_pt
private

◆ C

DoubleVectorWithHaloEntries oomph::PitchForkHandler::C
private

A constant vector used to ensure that the null vector is not trivial

◆ Count

DoubleVectorWithHaloEntries oomph::PitchForkHandler::Count
private

A vector that is used to determine how many elements contribute to a particular equation. It is used to ensure that the global system is correctly formulated. This should really be an integer, but its double so that the distribution can be used

Referenced by get_jacobian(), get_residuals(), and PitchForkHandler().

◆ Dof_distribution_pt

◆ Global_eqn_number

Vector<unsigned> oomph::PitchForkHandler::Global_eqn_number
private

A vector that is used to map the global equations to their actual location in a distributed problem

Referenced by global_eqn_number(), and PitchForkHandler().

◆ Ndof

unsigned oomph::PitchForkHandler::Ndof
private

Store the number of degrees of freedom in the non-augmented problem

Referenced by eqn_number(), PitchForkHandler(), and solve_augmented_block_system().

◆ Nelement

unsigned oomph::PitchForkHandler::Nelement
private

Referenced by get_residuals(), and PitchForkHandler().

◆ Parameter_pt

double* oomph::PitchForkHandler::Parameter_pt
private

◆ Problem_pt

◆ Psi

◆ Sigma

double oomph::PitchForkHandler::Sigma
private

A slack variable used to specify the amount of antisymmetry in the solution.

Referenced by get_jacobian(), get_residuals(), PitchForkHandler(), and solve_full_system().

◆ Solve_which_system

unsigned oomph::PitchForkHandler::Solve_which_system
private

Integer flag to indicate which system should be assembled. There are three possibilities. The full augmented system (0), the non-augmented jacobian system (1), a system in which the jacobian is augmented by 1 row and column to ensure that it is non-singular (2). See the enum above

Referenced by eqn_number(), get_dresiduals_dparameter(), get_jacobian(), get_residuals(), ndof(), solve_augmented_block_system(), solve_block_system(), and solve_full_system().

◆ Y


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