33 template <
typename _Type>
41 p_EQUATION(ptr_to_equation),
42 p_LEFT_RESIDUAL(ptr_to_left_residual),
43 p_RIGHT_RESIDUAL(ptr_to_right_residual) {
47 p_EQUATION ->
coord(1) = T;
48 if(p_EQUATION -> get_order() - p_LEFT_RESIDUAL -> get_order() - p_RIGHT_RESIDUAL -> get_order() != 0) {
49 std::string problem(
"\n The PDE_IBVP class has been constructed, but the order of the \n");
50 problem +=
"system does not match the number of boundary conditions.\n";
55 T_ASSEMBLE =
Timer(
"Assembling of the matrix (incl. equation updates):");
56 T_SOLVE =
Timer(
"Solving of the matrix:");
60 template <
typename _Type>
71 template <
typename _Type>
74 unsigned order(p_EQUATION -> get_order());
77 unsigned ny(SOLN.get_nnodes());
79 double max_residual(1.0);
106 assemble_matrix_problem(a, b, dt);
109 std::cout <<
" PDE_IBVP.solve : Residual_max = " << max_residual <<
" tol = " << TOL <<
"\n";
118 for(std::size_t var = 0; var < order; ++var) {
119 for(std::size_t i = 0; i < ny; ++i) {
120 SOLN(i, var) += b[ i * order + var ];
126 }
while((max_residual > TOL) && (counter < MAX_ITERATIONS));
127 if(max_residual > TOL) {
130 std::string problem(
"\n The PDE_IBVP.step2 method took too many iterations.\n");
131 problem +=
"Solution has been restored to the previous accurate state.\n";
135 std::cout <<
"[DEBUG] time-like variable = " << T <<
"\n";
142 template <
typename _Type>
147 const double inv_dt(1. / dt);
149 const unsigned order(p_EQUATION -> get_order());
151 const unsigned ny(SOLN.get_nnodes());
164 p_LEFT_RESIDUAL -> coord(0) = T + dt;
166 p_LEFT_RESIDUAL -> update(SOLN.get_nodes_vars(0));
168 for(
unsigned i = 0; i < p_LEFT_RESIDUAL -> get_order(); ++i) {
170 for(
unsigned var = 0; var < order; ++var) {
171 a(row, var) = p_LEFT_RESIDUAL -> jacobian()(i, var);
173 b[ row ] = - p_LEFT_RESIDUAL -> residual()[ i ];
177 for(std::size_t node = 0; node <= ny - 2; ++node) {
178 const std::size_t l_node = node;
179 const std::size_t r_node = node + 1;
181 const double inv_dy = 1. / (SOLN.coord(r_node) - SOLN.coord(l_node));
183 for(
unsigned var = 0; var < order; ++var) {
184 const _Type F_midpt = (SOLN(l_node, var) + SOLN(r_node, var)) / 2.;
185 const _Type O_midpt = (PREV_SOLN(l_node, var) + PREV_SOLN(r_node, var)) / 2.;
186 state_dy[ var ] = (SOLN(r_node, var) - SOLN(l_node, var)
187 + PREV_SOLN(r_node, var) - PREV_SOLN(l_node, var)) * inv_dy / 2.;
188 state[ var ] = (F_midpt + O_midpt) / 2.;
189 state_dt[ var ] = (F_midpt - O_midpt) * inv_dt;
193 p_EQUATION -> coord(0) = 0.5 * (SOLN.coord(l_node) + SOLN.coord(r_node));
195 p_EQUATION -> coord(1) = T + dt / 2;
197 p_EQUATION -> update(state);
199 p_EQUATION -> get_jacobian_of_matrix0_mult_vector(state, state_dy, h0);
201 p_EQUATION -> get_jacobian_of_matrix1_mult_vector(state, state_dt, h1);
212 for(
unsigned var = 0; var < order; ++var) {
214 for(
unsigned i = 0; i < order; ++i) {
217 const std::size_t offset(i * a.
noffdiag() * 3 + row);
221 *left -= p_EQUATION -> jacobian()(var, i) * 0.5;
223 *right -= p_EQUATION -> jacobian()(var, i) * 0.5;
226 *left += h0(var, i) * 0.5;
228 *right += h0(var, i) * 0.5;
231 *left += h1(var, i) * 0.5;
233 *right += h1(var, i) * 0.5;
236 *left -= p_EQUATION -> matrix0()(var, i) * inv_dy;
238 *right += p_EQUATION -> matrix0()(var, i) * inv_dy;
240 *left += p_EQUATION -> matrix1()(var, i) * inv_dt;
242 *right += p_EQUATION -> matrix1()(var, i) * inv_dt;
245 b[ row ] = p_EQUATION -> residual()[ var ];
246 b[ row ] -=
Utility::dot(p_EQUATION -> matrix0()[ var ], state_dy);
247 b[ row ] -=
Utility::dot(p_EQUATION -> matrix1()[ var ], state_dt);
255 p_RIGHT_RESIDUAL -> coord(0) = T + dt;
257 p_RIGHT_RESIDUAL -> update(SOLN.get_nodes_vars(ny - 1));
259 for(
unsigned i = 0; i < p_RIGHT_RESIDUAL -> get_order(); ++i) {
261 for(
unsigned var = 0; var < order; ++var) {
262 a(row, order * (ny - 1) + var) = p_RIGHT_RESIDUAL -> jacobian()(i, var);
264 b[ row ] = - p_RIGHT_RESIDUAL -> residual()[ i ];
268 if(row != ny * order) {
269 std::string problem(
"\n The ODE_BVP has an incorrect number of boundary conditions. \n");
Specification of the linear system class.
A templated class for equations that can be inherited from to allow instantiation of PDE_double_IBVP ...
The collection of CppNoddy exceptions.
A specification of a class for an -order IBVP of the form.
A specification of a (double/complex) residual class that not only defines a vector residual of a vec...
A spec for the CppNoddy Timer object.
A spec for a collection of utility functions.
A linear system class for vector right-hand sides.
void solve()
Solve the banded system.
A matrix class that constructs a BANDED matrix.
std::size_t noffdiag() const
Get the number of off-diagonal elements where the total INPUT band width is 2*noffdiag+1 since the ba...
void assign(_Type elt)
Assign a value the matrix so that it has the same geometry, but zero entries in all locations includi...
DenseVector< _Type >::elt_iter elt_iter
elt_iter get_elt_iter(std::size_t row, std::size_t col)
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
An DenseVector class – a dense vector object.
double inf_norm() const
Infinity norm.
An equation object base class used in the PDE_double_IBVP class.
An exception class that is thrown if too many Newton steps are taken in either the scalar or vector N...
A generic runtime exception.
A one dimensional mesh utility object.
A templated object for real/complex vector system of unsteady equations.
void step2(const double &dt)
A Crank-Nicolson 'time' stepper.
double & coord()
Return a reference to the current value of the 'timelike/parabolic' coordinate.
void assemble_matrix_problem(BandedMatrix< _Type > &a, DenseVector< _Type > &b, const double &dt)
Assembles the matrix problem for a BVP solve at the current time level.
PDE_IBVP(Equation_2matrix< _Type > *equation_ptr, const DenseVector< double > &nodes, Residual_with_coords< _Type > *ptr_to_left_residual, Residual_with_coords< _Type > *ptr_to_right_residual)
The class is defined by a vector function for the system.
A base class to be inherited by objects that define residuals.
A simple CPU-clock-tick timer for timing metods.
_Type dot(const DenseVector< _Type > &X, const DenseVector< _Type > &Y)
Templated dot product.
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...