Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
cantera/samples/cxx/bvp/blasius.cpp
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
132 lines (121 sloc)
4.01 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* @file blasius.cpp | |
* | |
* Blasius BVP Solver | |
* | |
* This example solves the Blasius boundary value problem for the velocity | |
* profile of a laminar boundary layer over a flat plate. It defines class | |
* BoundaryValueProblem, which provides a simplified interface to the boundary | |
* value problem capabilities of Cantera. | |
* | |
* Keywords: user-defined model | |
*/ | |
// This file is part of Cantera. See License.txt in the top-level directory or | |
// at https://cantera.org/license.txt for license and copyright information. | |
#include "BoundaryValueProblem.h" | |
using Cantera::npos; | |
/** | |
* This class solves the Blasius boundary value problem on the domain (0,L): | |
* \f[ | |
* \frac{d\zeta}{dz} = u. | |
* \f] | |
* \f[ | |
* \frac{d^2u}{dz^2} + 0.5\zeta \frac{du}{dz} = 0. | |
* \f] | |
* with boundary conditions | |
* \f[ | |
* \zeta(0) = 0, u(0) = 0, u(L) = 1. | |
* \f] | |
* Note that this is formulated as a system of two equations, with maximum | |
* order of 2, rather than as a single third-order boundary value problem. | |
* For reasons having to do with the band structure of the Jacobian, no | |
* equation in the system should have order greater than 2. | |
*/ | |
class Blasius : public BVP::BoundaryValueProblem | |
{ | |
public: | |
// This problem has two components (zeta and u) | |
Blasius(int np, double L) : BVP::BoundaryValueProblem(2, np, 0.0, L) { | |
// specify the component bounds, error tolerances, and names. | |
BVP::Component A; | |
A.lower = -200.0; | |
A.upper = 200.0; | |
A.rtol = 1.0e-12; | |
A.atol = 1.0e-15; | |
A.name = "zeta"; | |
setComponent(0, A); // zeta will be component 0 | |
BVP::Component B; | |
B.lower = -200.0; | |
B.upper = 200.0; | |
B.rtol = 1.0e-12; | |
B.atol = 1.0e-15; | |
B.name = "u"; | |
setComponent(1, B); // u will be component 1 | |
} | |
// destructor | |
virtual ~Blasius() {} | |
// specify guesses for the initial values. These can be anything | |
// that leads to a converged solution. | |
virtual double initialValue(size_t n, size_t j) { | |
switch (n) { | |
case 0: | |
return 0.1*z(j); | |
case 1: | |
return 0.5*z(j); | |
default: | |
return 0.0; | |
} | |
} | |
// Specify the residual function. This is where the ODE system and boundary | |
// conditions are specified. The solver will attempt to find a solution | |
// x so that rsd is zero. | |
void eval(size_t jg, double* x, double* rsd, int* diag, double rdt) { | |
size_t jpt = jg - firstPoint(); | |
size_t jmin, jmax; | |
if (jg == npos) { // evaluate all points | |
jmin = 0; | |
jmax = m_points - 1; | |
} else { // evaluate points for Jacobian | |
jmin = std::max<size_t>(jpt, 1) - 1; | |
jmax = std::min(jpt+1,m_points-1); | |
} | |
for (size_t j = jmin; j <= jmax; j++) { | |
if (j == 0) { | |
rsd[index(0,j)] = zeta(x,j); | |
rsd[index(1,j)] = u(x,j); | |
} else if (j == m_points - 1) { | |
rsd[index(0,j)] = leftFirstDeriv(x,0,j) - u(x,j); | |
rsd[index(1,j)] = u(x,j) - 1.0; | |
} else { | |
rsd[index(0,j)] = leftFirstDeriv(x,0,j) - u(x,j); | |
rsd[index(1,j)] = cdif2(x,1,j) + 0.5*zeta(x,j)*centralFirstDeriv(x,1,j) | |
- rdt*(value(x,1,j) - prevSoln(1,j)); | |
diag[index(1,j)] = 1; | |
} | |
} | |
} | |
private: | |
// for convenience only. Note that the compiler will inline these. | |
double zeta(double* x, int j) { | |
return value(x,0,j); | |
} | |
double u(double* x, int j) { | |
return value(x,1,j); | |
} | |
}; | |
int main() | |
{ | |
try { | |
// Specify a problem on (0,10), with an initial uniform grid of | |
// 6 points. | |
Blasius eqs(6, 10.0); | |
// Solve the equations, refining the grid as needed | |
eqs.solve(1); | |
// write the solution to a CSV file. | |
eqs.writeCSV("blasius.csv"); | |
return 0; | |
} catch (Cantera::CanteraError& err) { | |
std::cerr << err.what() << std::endl; | |
return -1; | |
} | |
} |