1
// Copyright (C) 2004-2005 Anders Logg.
2
// Licensed under the GNU LGPL Version 2.1.
4
// First added: 2004-04-04
5
// Last changed: 2005-12-19
12
#include <dolfin/parameter/parameters.h>
13
#include "ReducedModel.h"
15
using namespace dolfin;
17
//-----------------------------------------------------------------------------
18
ReducedModel::ReducedModel(ODE& ode)
19
: ODE(ode.size(), ode.endtime()), ode(ode), g(ode.size()), reduced(false)
21
warning("Automatic modeling is EXPERIMENTAL.");
23
tau = get("ODE average length");
24
samples = get("ODE average samples");
25
tol = get("ODE average tolerance");
28
//sparsity = ode.sparsity;
30
// Adjust the maximum allowed time step to the initial time step
31
real kmax = get("ODE initial time step");
32
set("ODE maximum time step", kmax);
34
//-----------------------------------------------------------------------------
35
ReducedModel::~ReducedModel()
39
//-----------------------------------------------------------------------------
40
real ReducedModel::f(const Vector& u, real t, unsigned int i)
43
return ode.f(u, t, i) + g[i]();
49
//-----------------------------------------------------------------------------
50
real ReducedModel::u0(unsigned int i)
54
//-----------------------------------------------------------------------------
55
void ReducedModel::update(RHS& f, Function& u, real t)
57
// Update for the given model if used
60
// Create the reduced model only one time
64
// Check if we have reached the beyond twice the average length
69
message("Creating reduced model at t = %.1e.", 2*tau);
71
// Compute averages of u and f
72
computeAverages(f, u, fbar, ubar);
74
// Compute reduced model
75
for (unsigned int i = 0; i < ode.size(); i++)
76
g[i].computeModel(ubar, fbar, i, tau, ode);
78
//-----------------------------------------------------------------------------
79
void ReducedModel::update(Solution& u, Adaptivity& adaptivity, real t)
81
// Update for the given model if used
82
ode.update(u, adaptivity, t);
84
// Check if we have reached the beyond twice the average length
88
// Create the reduced model only one time
92
// FIXME: Choose better maximum time step
93
// Adjust (increase) maximum allowed time step
94
adaptivity.adjustMaximumTimeStep(0.1);
96
// Adjust end values for inactive components
97
for (unsigned int i = 0; i < ode.size(); i++)
99
u.setlast(i, ubar(i));
105
// Remember that we have created the model
108
//-----------------------------------------------------------------------------
109
void ReducedModel::save(Sample& sample)
113
//-----------------------------------------------------------------------------
114
void ReducedModel::computeAverages(RHS& f, Function& u,
115
Vector& fbar, Vector& ubar)
117
error("This function needs to be updated to the new format.");
120
real k = tau / static_cast<real>(samples);
122
// Weight for each sample
123
real w = 1.0 / static_cast<real>(samples);
125
// Initialize averages
126
ubar.init(ode.size()); // Average on first half (and then both...)
127
fbar.init(ode.size()); // Average on both intervals
131
// Minimum and maximum values
132
Vector umin(ode.size());
133
Vector umax(ode.size());
137
// Additional average on second interval for u
138
Vector ubar2(ode.size());
141
Progress p("Computing averages", 2*samples);
143
// Compute average values on first half of the averaging interval
144
for (unsigned int j = 0; j < samples; j++)
146
for (unsigned int i = 0; i < ode.size(); i++)
149
real t = 0.5*k + static_cast<real>(j)*k;
155
// Compute average values of u and f
157
fbar(i) += 0.5 * w * ff;
159
// Compute minimum and maximum values of u and f
167
umin(i) = std::min(umin(i), uu);
168
umax(i) = std::max(umax(i), uu);
175
// Compute average values on second half of the averaging interval
176
for (unsigned int j = 0; j < samples; j++)
178
for (unsigned int i = 0; i < ode.size(); i++)
181
real t = tau + 0.5*k + static_cast<real>(j)*k;
187
// Compute average values of u and f
189
fbar(i) += 0.5 * w * ff;
191
// Compute minimum and maximum values of u and f
192
umin(i) = std::min(umin(i), uu);
193
umax(i) = std::max(umax(i), uu);
199
// Compute relative changes in u
200
for (unsigned int i = 0; i < ode.size(); i++)
202
real du = fabs(ubar(i) - ubar2(i)) / (umax(i) - umin(i) + DOLFIN_EPS);
204
cout << "Component " << i << ":" << endl;
205
cout << " ubar1 = " << ubar(i) << endl;
206
cout << " ubar2 = " << ubar2(i) << endl;
207
cout << " fbar = " << fbar(i) << endl;
208
cout << " du/u = " << du << endl;
210
// Inactivate components whose average is constant
213
cout << "Inactivating component " << i << endl;
218
ubar(i) = 0.5*(ubar(i) + ubar2(i));
222
//-----------------------------------------------------------------------------
223
// ReducedModel::Model
224
//-----------------------------------------------------------------------------
225
ReducedModel::Model::Model() : g(0), _active(true)
229
//-----------------------------------------------------------------------------
230
ReducedModel::Model::~Model()
234
//-----------------------------------------------------------------------------
235
real ReducedModel::Model::operator() () const
239
//-----------------------------------------------------------------------------
240
bool ReducedModel::Model::active() const
244
//-----------------------------------------------------------------------------
245
void ReducedModel::Model::inactivate()
249
//-----------------------------------------------------------------------------
250
void ReducedModel::Model::computeModel(Vector& ubar, Vector& fbar,
251
unsigned int i, real tau, ODE& ode)
254
//g = fbar(i) - ode.f(ubar, tau, i);
256
cout << "Modeling term for component " << i << ": " << g << endl;
258
//-----------------------------------------------------------------------------