1
// Copyright (C) 2005-2006 Anders Logg.
2
// Licensed under the GNU LGPL Version 2.1.
4
// First added: 2005-10-14
5
// Last changed: 2006-08-22
9
using namespace dolfin;
11
/// Test problem taken from "Multirate time stepping for parabolic PDEs"
12
/// by Savcenco, Hundsdorfer and Verwer:
14
/// u' - epsilon u'' = gamma u^2 (1 - u) in (0, L) x (0, T).
16
/// The solution is a reaction front sweeping across the domain.
18
class Reaction : public ODE
23
Reaction(unsigned int N, real T, real L, real epsilon, real gamma)
24
: ODE(N, T), L(L), epsilon(epsilon), gamma(gamma)
27
h = L / static_cast<real>(N - 1);
28
lambda = 0.5*sqrt(2.0*gamma/epsilon);
29
v = 0.5*sqrt(2.0*gamma*epsilon);
31
// Set sparse dependency pattern
32
for (unsigned int i = 0; i < N; i++)
34
dependencies.setsize(i, 3);
35
if ( i > 0 ) dependencies.set(i, i - 1);
36
dependencies.set(i, i);
37
if ( i < (N - 1) ) dependencies.set(i, i + 1);
42
void u0(uBlasVector& u)
44
for (unsigned int i = 0; i < N; i++)
46
const real x = static_cast<real>(i)*h;
47
u(i) = 1.0 / (1.0 + exp(lambda*(x - 1.0)));
51
/// Right-hand side, mono-adaptive version
52
void f(const uBlasVector& u, real t, uBlasVector& y)
55
for (unsigned int i = 0; i < N; i++)
62
else if ( i == (N - 1) )
65
sum = u(i + 1) - 2.0*ui + u(i - 1);
67
y(i) = epsilon * sum / (h*h) + gamma * ui*ui * (1.0 - ui);
71
/// Right-hand side, multi-adaptive version
72
real f(const uBlasVector& u, real t, unsigned int i)
80
else if ( i == (N - 1) )
83
sum = u(i + 1) - 2.0*ui + u(i - 1);
85
return epsilon * sum / (h*h) + gamma * ui*ui * (1.0 - ui);
90
real L; // Length of domain
91
real epsilon; // Diffusivity
92
real gamma; // Reaction rate
94
real lambda; // Parameter for initial data
95
real v; // Speed of reaction front
99
int main(int argc, char* argv[])
101
// Parse command line arguments
104
message("Usage: dolfin-ode-reaction method solver tol kmax N L params");
106
message("method - 'cg' or 'mcg'");
107
message("solver - 'fixed-point' or 'newton'");
108
message("tol - tolerance");
109
message("N - number of components");
110
message("L - length of domain");
111
message("params - name of parameter file");
114
const char* method = argv[1];
115
const char* solver = argv[2];
116
const real tol = static_cast<real>(atof(argv[3]));
117
const unsigned int N = static_cast<unsigned int>(atoi(argv[4]));
118
const real L = static_cast<unsigned int>(atof(argv[5]));
119
const char* params = argv[6];
121
// Load solver parameters from file
123
file >> ParameterSystem::parameters;
125
// Set remaining solver parameters from command-line arguments
126
set("ODE method", method);
127
set("ODE nonlinear solver", solver);
128
set("ODE tolerance", tol);
130
// Set fixed parameters for test problem
132
const real epsilon = 0.01;
133
const real gamma = 1000.0;
135
// Solve system of ODEs
136
Reaction ode(N, T, L, epsilon, gamma);