Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 86bb724

Browse files
committed
Add example of Observer function usage. Close #1.
1 parent 0a43390 commit 86bb724

8 files changed

+71
-19
lines changed

examples/perovskite/perovskite.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "perovskite_Mass.h" // Mass Matrix definition
3232
#include "perovskite_Jacobian.h" // Jacobian of the problem
3333
#include "perovskite_parameters.h" // Parameter container of the problem
34+
#include "perovskite_observer.h" // Observer (optional)
3435

3536
namespace dae = daecpp; // A shortcut to dae-cpp library namespace
3637

@@ -110,15 +111,23 @@ int main()
110111
// of Jacobian and the matrix factorisation)
111112

112113
// Create an instance of the solver with particular RHS, Mass matrix,
113-
// Jacobian and solver options
114+
// Jacobian and solver options.
114115
dae::Solver solve(rhs, jac, mass, opt);
115116

117+
// In order to get access to the intermediate solution after every time
118+
// step, we can override observer function in Solver class and, for example,
119+
// print out some results while the solver solves the system.
120+
// See perovskite_observer.h as an example.
121+
// Instanse of the solver with the user-defined observer:
122+
// MySolver solve_observer(rhs, jac, mass, opt);
123+
116124
// Now we are ready to solve the set of DAEs
117125
std::cout << "\nStarting DAE solver...\n";
118126

119127
{
120128
auto tic0 = clock::now();
121-
solve(x1, p.t1);
129+
solve(x1, p.t1); // Solve the system without observer
130+
// solve_observer(x1, p.t1); // Use observer
122131
auto tic1 = clock::now();
123132

124133
// If we need to produce intermediate results, for example, for

examples/perovskite/perovskite_Jacobian.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ void MyJacobian::operator()(daecpp::sparse_matrix_holder &J,
1616

1717
MKL_INT c = 0;
1818

19-
// clang-format off
19+
// clang-format off
2020
for(MKL_INT i = 0; i < size; i++)
2121
{
2222
J.ia.push_back(c);
@@ -106,7 +106,7 @@ void MyJacobian::operator()(daecpp::sparse_matrix_holder &J,
106106
c += 1;
107107
}
108108
}
109-
// clang-format on
109+
// clang-format on
110110

111111
J.ia.push_back(c);
112112
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* User-defined observer for perovskite problem.
3+
* Just prints out current time t and potential phi on the right boundary.
4+
* According to the boundary conditions, phi on the right boundary should be
5+
* equal to the current time exactly. This is what we check every time step.
6+
*/
7+
8+
#pragma once
9+
10+
#include <iostream>
11+
12+
#include "../../src/solver.h"
13+
14+
class MySolver : public daecpp::Solver
15+
{
16+
public:
17+
MySolver(daecpp::RHS &rhs, daecpp::Jacobian &jac, daecpp::MassMatrix &mass,
18+
daecpp::SolverOptions &opt)
19+
: daecpp::Solver(rhs, jac, mass, opt)
20+
{
21+
}
22+
23+
/*
24+
* Overloaded observer.
25+
* Receives current solution vector and the current time every time step.
26+
* Prints current time t and potential phi on the right boundary.
27+
*/
28+
void observer(daecpp::state_type &x, const double t)
29+
{
30+
const MKL_INT size = (MKL_INT)(x.size());
31+
std::cout << " | t = " << t << " == phi(x=1) = " << x[size - 1];
32+
}
33+
};

src/jacobian.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void Jacobian::operator()(sparse_matrix_holder &J, const state_type &x,
7272
std::vector<std::vector<float_type>> values_local(
7373
size, std::vector<float_type>(0));
7474
std::vector<std::vector<MKL_INT>> rows_local(size,
75-
std::vector<MKL_INT>(0));
75+
std::vector<MKL_INT>(0));
7676

7777
#if JACOBIAN_SCHEME == 1
7878
m_rhs(x1, f0, t);
@@ -189,6 +189,7 @@ void Jacobian::print(const state_type &x, const double t)
189189
}
190190

191191
sparse_matrix_holder J;
192+
192193
this->operator()(J, x, t);
193194

194195
std::cout << std::right;
@@ -206,8 +207,8 @@ void Jacobian::print(const state_type &x, const double t)
206207
if(i < J.ja.size())
207208
std::cout << std::setw(7) << J.ja[i] << " | ";
208209
else
209-
std::cout << std::setw(7) << "???" << " | "; // Error in Jacobian
210-
// matrix structure
210+
std::cout << std::setw(7) << "???"
211+
<< " | "; // Error in Jacobian matrix structure
211212
if(i < J.ia.size())
212213
std::cout << std::setw(7) << J.ia[i];
213214
std::cout << std::endl;

src/matrix_checker.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ int TimeIntegrator::matrix_checker(sparse_matrix_holder &A, MKL_INT size)
2121

2222
sparse_matrix_checker_init(&pt);
2323

24-
pt.n = size;
25-
pt.csr_ia = A.ia.data();
26-
pt.csr_ja = A.ja.data();
24+
pt.n = size;
25+
pt.csr_ia = A.ia.data();
26+
pt.csr_ja = A.ja.data();
2727
#ifdef DAE_FORTRAN_STYLE
28-
pt.indexing = MKL_ONE_BASED;
28+
pt.indexing = MKL_ONE_BASED;
2929
#else
30-
pt.indexing = MKL_ZERO_BASED;
30+
pt.indexing = MKL_ZERO_BASED;
3131
#endif
3232
pt.matrix_structure = MKL_GENERAL_STRUCTURE;
3333
pt.matrix_format = MKL_CSR;

src/solver.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,8 @@ void Solver::operator()(state_type &x, const double t1)
3333
}
3434

3535
// Check the initial time step
36-
m_opt.dt_init = (m_opt.dt_init > (t1 - m_opt.t0)) ? (t1 - m_opt.t0) : m_opt.dt_init;
36+
m_opt.dt_init =
37+
(m_opt.dt_init > (t1 - m_opt.t0)) ? (t1 - m_opt.t0) : m_opt.dt_init;
3738

3839
// Initial time
3940
double t = m_opt.t0;
@@ -142,12 +143,13 @@ void Solver::operator()(state_type &x, const double t1)
142143
while(t < (t1 + dt[0] * 0.5))
143144
{
144145
step_counter++;
146+
m_steps++;
145147

146148
if(m_opt.verbosity > 0)
147149
{
148150
std::cout << std::left;
149-
std::cout << "\nStep " << std::setw(7) << step_counter << " :: t = "
150-
<< std::setw(12) << t << " :: ";
151+
std::cout << "\nStep " << std::setw(7) << m_steps
152+
<< " :: t = " << std::setw(12) << t << " :: ";
151153
std::cout.flush();
152154
}
153155

@@ -176,8 +178,8 @@ void Solver::operator()(state_type &x, const double t1)
176178
// Jacobian can change its size and can be re-allocated.
177179
// Catch up new array addresses.
178180
mkl_a = J.A.data();
179-
ia = J.ia.data();
180-
ja = J.ja.data();
181+
ia = J.ia.data();
182+
ja = J.ja.data();
181183

182184
// PHASE 1.
183185
// Reordering and Symbolic Factorization. This step also
@@ -258,6 +260,7 @@ void Solver::operator()(state_type &x, const double t1)
258260
}
259261

260262
calls++;
263+
m_calls++;
261264

262265
double tol = 0.0;
263266

@@ -303,6 +306,7 @@ void Solver::operator()(state_type &x, const double t1)
303306
// carry out it again.
304307
t -= dt[0];
305308
step_counter--;
309+
m_steps--;
306310
final_time_step = false;
307311
dt[0] /= m_opt.dt_decrease_factor;
308312
current_scheme = 1; // Fall back to BDF-1 for better stability
@@ -394,6 +398,7 @@ void Solver::operator()(state_type &x, const double t1)
394398

395399
t -= dt[0];
396400
step_counter--;
401+
m_steps--;
397402
final_time_step = false;
398403
dt[0] /= m_opt.dt_decrease_factor;
399404
if(step_counter && m_opt.bdf_order == 2)
@@ -459,7 +464,8 @@ void Solver::operator()(state_type &x, const double t1)
459464
m_opt.dt_init = dt[1];
460465

461466
if(m_opt.verbosity > 0)
462-
std::cout << "\nLinear algebra solver calls: " << calls << '\n';
467+
std::cout << "\nLinear algebra solver calls: " << calls
468+
<< " (total: " << m_calls << ")\n";
463469

464470
// Termination and release of memory
465471
phase = -1;

src/solver.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ class Solver
2424

2525
SolverOptions &m_opt; // Solver options
2626

27+
size_t m_steps = 0; // Internal time iteration counter
28+
size_t m_calls = 0; // Internal solver calls counter
29+
2730
void check_pardiso_error(MKL_INT err);
2831

2932
public:

src/time_integrator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ void TimeIntegrator::operator()(sparse_matrix_holder &Jt, state_type &b,
142142

143143
if(Jt.A.size() != nzmax)
144144
Jt.A.resize(nzmax);
145-
if(Jt.ia.size() != (size_t)(size)+1)
145+
if(Jt.ia.size() != (size_t)(size) + 1)
146146
Jt.ia.resize(size + 1);
147147
if(Jt.ja.size() != nzmax)
148148
Jt.ja.resize(nzmax);

0 commit comments

Comments
 (0)