CppNoddy  0.92
Loading...
Searching...
No Matches
ODE_EVP.h
Go to the documentation of this file.
1/// \file ODE_EVP.h
2/// A specification of a class for an \f$ n^{th} \f$-order ODE LINEAR EVP defined by
3/// \f[ \lambda M_1({\underline f}(x),x ) \cdot {\underline f } + M_0({\underline f}(x),x ) \cdot {\underline f}^\prime (x) = {\underline R}( {\underline f}(x), x )\,, \f]
4/// subject to \f$ n \f$ zero Dirichlet conditions defined at \f$ x = x_{left} \f$ or
5/// \f$ x_{right} \f$ for some components of \f$ {\underline f}(x) \f$. The routine
6/// constructs a banded 2nd order finite-difference (banded) representation of the EVP
7/// in the form \f[ A_{M\times M} {\underline x} = \lambda B_{M\times M} {\underline x} \f]
8/// which can then be solved via the LinearEigenSystem class where
9/// \f$ M = N \times O \f$ for an order O equation and N (uniformly spaced) mesh points. The default
10/// configuration uses the DenseLinearEigenSystem class for solution via LAPACK
11/// although ARPACK can be used if you really know the resulting system has the
12/// correct mass matrix properties (typically it wont!).
13
14#ifndef ODE_EVP_H
15#define ODE_EVP_H
16
17#include <memory>
18#include <algorithm>
19
20#include <DenseVector.h>
21#include <DenseMatrix.h>
22#include <Equation_2matrix.h>
23#include <Exceptions.h>
24#include <Uncopyable.h>
25#include <OneD_Node_Mesh.h>
27#include <Residual.h>
28
29namespace CppNoddy {
30
31 /// A templated object for real/complex vector system
32 /// of first-order ordinary differential equations.
33
34 template <typename _Type>
35 class ODE_EVP : private Uncopyable {
36
37 public:
38
39 /// The class is defined by a vector function for the system.
40 /// \param equation_ptr A pointer to an equation with 2 associated matrices; matrix1 will define the eigenvalue problem.
41 /// \param nodes A vector of nodal points.
42 /// \param ptr_to_left_residual A pointer to a residual object that defines the LHS boundary conditions.
43 /// \param ptr_to_right_residual A pointer to a residual object that defines the RHS boundary conditions.
45 const DenseVector<double> &nodes,
46 Residual<_Type>* ptr_to_left_residual,
47 Residual<_Type>* ptr_to_right_residual);
48
49 /// Destructor
50 ~ODE_EVP();
51
52 /// Formulate and solve the global eigenvalue problem
53 /// for a linear system.
54 void eigensolve();
55
56 /// Allow access to the underlying dense linear eigensystem
57 /// through a pointer to the private member data.
59
61 // clear the existing data if any
62 MESHES.clear();
63 // order of the equation
64 unsigned order = p_EQUATION -> get_order();
65 // get the eigenvalues
66 DenseVector<D_complex> vals(p_SYSTEM -> get_tagged_eigenvalues());
67 // get the eigenvectors
68 DenseMatrix<D_complex> vecs(p_SYSTEM -> get_tagged_eigenvectors());
69 // loop through the eigenvectors
70 for(unsigned ivec = 0; ivec < vals.size(); ++ivec) {
71 // make a mesh with the right node distribution
72 // we'll increase the order by 1 to allow the eigenvalue to be
73 // stored at each nodal point -- this is wasteful but very useful
74 // for feeding this into a BVP for local refinement.
75 OneD_Node_Mesh<D_complex> eigfn(NODES, order + 1);
76 // loop through all nodes
77 for(unsigned node = 0; node < NODES.size(); ++node) {
78 // complex vector of the dof at this node ( + 1 for the eigenvalue)
79 DenseVector<D_complex> vars_at_node(order + 1, 0.0);
80 // get the dof from the eigenvector
81 for(unsigned var = 0; var < order; ++var) {
82 vars_at_node[ var ] = vecs[ ivec ][ node * order + var ];
83 }
84 // the last variable at each node is the corresponding eigenvalue
85 vars_at_node[ order ] = vals[ ivec ];
86 // set the first 'order' dof to be those from the eigenvector
87 eigfn.set_nodes_vars(node, vars_at_node);
88 }
89 //// store the eigenvalue in the mesh at each node ... wasteful, but useful
90 //// a complex vector filled with the same value N times
91 //DenseVector<D_complex> c( NODES.size(), vals[ ivec ] );
92 //// add it to the mesh -- for use in nonlinear local refinement via ODE_BVP
93 //eigfn.push_var( c );
94 // add the eigenfunction to the vector of meshes
95 MESHES.push_back(eigfn);
96 }
97 }
98
99 OneD_Node_Mesh<D_complex> get_mesh(const unsigned& i) const {
100#ifdef PARANOID
101 if(i > MESHES.size()) {
102 std::string problem;
103 problem = "You have tried to extract an eigenfunction from the ODE_EVP class\n";
104 problem += "whose index is outside the range of stored meshes.\n";
105 throw ExceptionRange(problem, MESHES.size(), i);
106 }
107#endif
108 return MESHES[ i ];
109 }
110
111 private:
112
113 /// A method that constructs the banded matrix problem
114 void assemble_dense_problem();
115
116 /// The function associated with this instance.
117 Equation_2matrix<_Type > *p_EQUATION;
118 /// Pointer to the residual defining the LHS BC
119 Residual<_Type > *p_LEFT_RESIDUAL;
120 /// Pointer to the residual defining the RHS BC
121 Residual<_Type > *p_RIGHT_RESIDUAL;
122 /// The dense linear eigensystem
123 LinearEigenSystem_base *p_SYSTEM;
124 /// Matrices for the LAPACK QZ routine -- must be DENSE
125 DenseMatrix<_Type>* p_A_DENSE;
126 DenseMatrix<_Type>* p_B_DENSE;
127 /// the nodal distribution
129 /// A vector of uniform meshes that store the eigenfunctions
130 /// and eigenvalue (as the last dof at each nodal point)
131 /// for use in later local refinement via the ODE_BVP class
132 std::vector< OneD_Node_Mesh<D_complex> > MESHES;
133 /// has the eigensystem been constructed/solved?
134 bool CONSTRUCTED;
135
136 }
137 ; // end class
138
139
140} // end namespace
141
142#endif
143
A matrix class that constructs a DENSE matrix as an STL Vector of DenseVectors.
Specification for a templated DenseVector class – a dense, dynamic, vector object.
A templated class for equations that can be inherited from to allow instantiation of PDE_double_IBVP ...
The collection of CppNoddy exceptions.
Specification of the linear eigensystem base class.
A specification for a one dimensional mesh object.
A specification of a (double/complex) VECTOR residual class.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
Definition: DenseMatrix.h:25
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
std::size_t size() const
A pass-thru definition to get the size of the vector.
Definition: DenseVector.h:330
An equation object base class used in the PDE_double_IBVP class.
An exception to indicate that a CppNoddy container has been accessed with index/indices outside the m...
Definition: Exceptions.h:117
A linear Nth-order generalised eigensystem base class.
A templated object for real/complex vector system of first-order ordinary differential equations.
Definition: ODE_EVP.h:35
LinearEigenSystem_base * p_eigensystem()
Allow access to the underlying dense linear eigensystem through a pointer to the private member data.
Definition: ODE_EVP.cpp:53
void add_tagged_to_mesh()
Definition: ODE_EVP.h:60
OneD_Node_Mesh< D_complex > get_mesh(const unsigned &i) const
Definition: ODE_EVP.h:99
void eigensolve()
Formulate and solve the global eigenvalue problem for a linear system.
Definition: ODE_EVP.cpp:58
~ODE_EVP()
Destructor.
Definition: ODE_EVP.cpp:45
A one dimensional mesh utility object.
void set_nodes_vars(const std::size_t node, const DenseVector< _Type > &u)
Set the variables stored at A SPECIFIED node.
A base class to be inherited by objects that define residuals.
Definition: Residual.h:15
An object to block copying.
Definition: Uncopyable.h:8
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt