ode_problem.h
Go to the documentation of this file.
1 //LIC// ====================================================================
2 //LIC// This file forms part of oomph-lib, the object-oriented,
3 //LIC// multi-physics finite-element library, available
4 //LIC// at http://www.oomph-lib.org.
5 //LIC//
6 //LIC// Copyright (C) 2006-2022 Matthias Heil and Andrew Hazel
7 //LIC//
8 //LIC// This library is free software; you can redistribute it and/or
9 //LIC// modify it under the terms of the GNU Lesser General Public
10 //LIC// License as published by the Free Software Foundation; either
11 //LIC// version 2.1 of the License, or (at your option) any later version.
12 //LIC//
13 //LIC// This library is distributed in the hope that it will be useful,
14 //LIC// but WITHOUT ANY WARRANTY; without even the implied warranty of
15 //LIC// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 //LIC// Lesser General Public License for more details.
17 //LIC//
18 //LIC// You should have received a copy of the GNU Lesser General Public
19 //LIC// License along with this library; if not, write to the Free Software
20 //LIC// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 //LIC// 02110-1301 USA.
22 //LIC//
23 //LIC// The authors may be contacted at oomph-lib@maths.man.ac.uk.
24 //LIC//
25 //LIC//====================================================================
26 #ifndef OOMPH_ODE_PROBLEM_H
27 #define OOMPH_ODE_PROBLEM_H
28 
29 
30 #include "generic.h"
31 #include "ode.h"
32 
33 #include "my_problem.h"
34 
35 
36 namespace oomph
37 {
38 
39  namespace VectorHelpers
40  {
41  inline double two_norm(const Vector<double>& a)
42  {
43  return std::sqrt(dot(a,a));
44  }
45 
47  {
49  unsigned ni = a.size();
50  Vector<double> diff(ni, 0.0);
51  for(unsigned i=0; i<ni; i++) {diff[i] = a[i] - b[i];}
52  return diff;
53  }
54  }
55 
56  class ODEProblem : public MyProblem
57  {
58  public:
59 
62  {
63  // Don't output to trace file every step, often too many steps
64  Always_write_trace = false;
65 
66  Use_fd_jacobian = false;
67  }
68 
69  virtual ~ODEProblem() {}
70 
71  virtual void build(Vector<Mesh*>& bulk_mesh_pt)
72  {
73  // Call the underlying build
74  MyProblem::build(bulk_mesh_pt);
75 
76  // Set up the global mesh
78 
80 
81  // assign equation numbers
82  this->assign_eqn_numbers();
83  oomph_info << "Number of equations: " << ndof() << std::endl;
84  }
85 
87  {
88  // Loop over current & previous timesteps
89  const unsigned nprev_values = time_stepper_pt()->nprev_values();
90  for(unsigned t=0; t<nprev_values+1; t++)
91  {
92  double time = time_pt()->time(t);
93 
94  std::cout << "setting IC at time =" << time << std::endl;
95 
96  // Get + set the (only) value
97  Vector<double> dummy(nvalue(), 1.0);
98  Vector<double> values = ic(time, dummy);
99 
100  for(unsigned j=0, nj=nvalue(); j<nj; j++)
101  {
103  ->set_value(t, j, values[j]);
104  }
105  }
106 
108  }
109 
110  virtual void write_additional_trace_headers(std::ofstream& trace_file) const
111  {
112  trace_file << Trace_seperator << "exact";
113  }
114 
115  virtual void write_additional_trace_data(const unsigned& t_hist,
116  std::ofstream& trace_file) const
117  {
118  // Create a temporary vector to store the exact solution
120 
121  // Output the vector
122  unsigned output_vector_length=output_vector.size();
123  if (output_vector_length==0)
124  {
125  trace_file << Trace_seperator << "[]";
126  }
127  else
128  {
129  trace_file << Trace_seperator << "[" << output_vector[0];
130  if (output_vector_length>1)
131  {
132  for (unsigned i=1;i<output_vector_length;i++)
133  {
134  trace_file << ", " << output_vector[i];
135  }
136  }
137  trace_file << "]";
138  }
139  }
140 
141  virtual double get_error_norm(const unsigned& t_hist=0) const
142  {
143  Vector<double> val = trace_values(t_hist);
144  Vector<double> exact = exact_solution(time_pt()->time(t_hist));
145 
147  }
148 
149  Vector<double> exact_solution(const double& time) const
150  {
151  ODEElement* el_pt = checked_dynamic_cast<ODEElement*>
152  (mesh_pt()->element_pt(0));
153  return el_pt->exact_solution(time);
154  }
155 
158  {
159  Data* dat_pt=mesh_pt()->element_pt(0)->internal_data_pt(0);
160 
161  return std::abs(ts_pt()->temporal_error_in_value(dat_pt, 0));
162  }
163 
164  Vector<double> trace_values(const unsigned& t_hist=0) const
165  {
166  return solution(t_hist);
167  }
168 
170  {return checked_dynamic_cast<ODEElement*>(mesh_pt()->element_pt(0));}
171 
172  const ODEElement* element_pt() const
173  {return checked_dynamic_cast<ODEElement*>(mesh_pt()->element_pt(0));}
174 
176  {
178  }
179 
180  unsigned nvalue() const
181  {
182  return element_pt()->nvalue();
183  }
184 
185  // Output solution
186  void output_solution(const unsigned& t, std::ostream& outstream,
187  const unsigned& npoints=2) const
188  {
189  // Create a temporary vector to store the exact solution
191 
192  // Vector length
193  unsigned output_vector_length=output_vector.size();
194 
195  // Output the vector (to the command window)
196  if (output_vector_length==0)
197  {
198  std::cout << Trace_seperator << "[]";
199  }
200  else
201  {
202  std::cout << Trace_seperator << "[" << output_vector[0];
203  if (output_vector_length>1)
204  {
205  for (unsigned i=1;i<output_vector_length;i++)
206  {
207  std::cout << ", " << output_vector[i];
208  }
209  }
210  std::cout << "]";
211  }
212 
213  // Output the vector (to outstream)
214  if (output_vector_length==0)
215  {
216  outstream << Trace_seperator << "[]";
217  }
218  else
219  {
220  outstream << Trace_seperator << "[" << output_vector[0];
221  if (output_vector_length>1)
222  {
223  for (unsigned i=1;i<output_vector_length;i++)
224  {
225  outstream << ", " << output_vector[i];
226  }
227  }
228  outstream << "]";
229  }
230 
231  // npoints is ignored
232  }
233 
234  Vector<double> solution(const unsigned& timestep=0) const
235  {
236  Data* dat_pt=mesh_pt()->element_pt(0)->internal_data_pt(0);
238  dat_pt->value(timestep, solution);
239  return solution;
240  }
241 
243 
244  };
245 
246  namespace Factories
247  {
251  {
252 
253  // Always make timestepper adaptive, we can control adaptivity by
254  // calling adaptive or non adaptive newton solve.
255  bool adaptive_flag = true;
256 
257  if(ts_name == "bdf1")
258  {
259  return new BDF<1>(adaptive_flag);
260  }
261  else if(ts_name == "bdf2")
262  {
263  return new BDF<2>(adaptive_flag);
264  }
265  else if(ts_name == "real-imr")
266  {
267  IMR* mp_pt = new IMR(adaptive_flag);
268  ExplicitTimeStepper* pred_pt = new EBDF3;
269  mp_pt->set_predictor_pt(pred_pt);
270  return mp_pt;
271  }
272  else if(ts_name == "imr")
273  {
274  IMRByBDF* mp_pt = new IMRByBDF(adaptive_flag);
275  ExplicitTimeStepper* pred_pt = new EBDF3;
276  mp_pt->set_predictor_pt(pred_pt);
277  return mp_pt;
278  }
279  else if(ts_name == "steady")
280  {
281  // 2 steps so that we have enough space to do reasonable time
282  // derivative estimates in e.g. energy derivatives.
283  return new Steady<3>;
284  }
285  else if(ts_name == "tr")
286  {
287  // 2 steps so that we have enough space to do reasonable time
288  // derivative estimates in e.g. energy derivatives.
289  return new TR(adaptive_flag);
290  }
291  else
292  {
293  std::string err = "Unrecognised time stepper name";
296  }
297  }
298  }
299 
300 
301 } // End of oomph namespace
302 
303 #endif
AnnoyingScalar abs(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:135
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
Scalar * b
Definition: benchVecAdd.cpp:17
Definition: timesteppers.h:1165
Definition: nodes.h:86
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:238
void set_value(const unsigned &i, const double &value_)
Definition: nodes.h:271
double value(const unsigned &i) const
Definition: nodes.h:293
Definition: explicit_timesteppers.h:240
A Base class for explicit timesteppers.
Definition: explicit_timesteppers.h:132
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
Definition: implicit_midpoint_rule.h:220
Definition: implicit_midpoint_rule.h:167
GeneralisedElement *& element_pt(const unsigned long &e)
Return pointer to element e.
Definition: mesh.h:448
Definition: my_problem.h:131
virtual void build(Vector< Mesh * > &bulk_mesh_pt)
Perform set up of problem.
Definition: my_problem.h:967
virtual void actions_after_set_initial_condition()
Definition: my_problem.h:1113
const std::string Trace_seperator
Definition: my_problem.h:926
bool Always_write_trace
Should we output to trace file every step?
Definition: my_problem.h:885
Element for integrating an initial value ODE.
Definition: ode_elements.h:41
bool Use_fd_jacobian
Definition: ode_elements.h:182
Vector< double > exact_solution(const double &t) const
Exact solution.
Definition: ode_elements.h:151
unsigned nvalue() const
Definition: ode_elements.h:76
Definition: ode_problem.h:57
Vector< double > trace_values(const unsigned &t_hist=0) const
Definition: ode_problem.h:164
virtual double get_error_norm(const unsigned &t_hist=0) const
Error norm calculator.
Definition: ode_problem.h:141
const ODEElement * element_pt() const
Definition: ode_problem.h:172
double global_temporal_error_norm()
Error norm: use abs(error in data).
Definition: ode_problem.h:157
bool Use_fd_jacobian
Definition: ode_problem.h:242
ODEProblem()
constructor
Definition: ode_problem.h:61
Vector< double > exact_solution(const double &time) const
Definition: ode_problem.h:149
Vector< double > solution(const unsigned &timestep=0) const
Definition: ode_problem.h:234
virtual void build(Vector< Mesh * > &bulk_mesh_pt)
Perform set up of problem.
Definition: ode_problem.h:71
ODEElement * element_pt()
Definition: ode_problem.h:169
virtual void write_additional_trace_data(const unsigned &t_hist, std::ofstream &trace_file) const
Definition: ode_problem.h:115
void my_set_initial_condition(const SolutionFunctorBase &ic)
Assign initial conditions from function pointer.
Definition: ode_problem.h:86
virtual void write_additional_trace_headers(std::ofstream &trace_file) const
Definition: ode_problem.h:110
unsigned nvalue() const
Definition: ode_problem.h:180
virtual ~ODEProblem()
Definition: ode_problem.h:69
void output_solution(const unsigned &t, std::ostream &outstream, const unsigned &npoints=2) const
Definition: ode_problem.h:186
TimeStepper * ts_pt() const
Definition: ode_problem.h:175
Definition: oomph_definitions.h:222
unsigned long ndof() const
Return the number of dofs.
Definition: problem.h:1674
Time *& time_pt()
Return a pointer to the global time object.
Definition: problem.h:1504
void build_global_mesh()
Definition: problem.cc:1493
Mesh *& mesh_pt()
Return a pointer to the global mesh.
Definition: problem.h:1280
unsigned long assign_eqn_numbers(const bool &assign_local_eqn_numbers=true)
Definition: problem.cc:1989
TimeStepper *& time_stepper_pt()
Definition: problem.h:1524
double & time()
Return the current value of continuous time.
Definition: problem.cc:11531
Definition: oomph_utilities.h:1109
Definition: timesteppers.h:681
Definition: timesteppers.h:231
virtual unsigned nprev_values() const =0
Number of previous values available: 0 for static, 1 for BDF<1>,...
void set_predictor_pt(ExplicitTimeStepper *_pred_pt)
Definition: timesteppers.h:410
double & time()
Return the current value of the continuous time.
Definition: timesteppers.h:123
#define TR
Definition: common.h:40
void output_vector(const Vector< myType > &given_vector)
Definition: crdoublematrix_copy_constructor.cc:49
const Scalar * a
Definition: level2_cplx_impl.h:32
val
Definition: calibrate.py:119
TimeStepper * time_stepper_factory(const std::string &ts_name)
Definition: ode_problem.h:250
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
double two_norm(const Vector< double > &a)
Definition: ode_problem.h:41
double dot(const Vector< double > &a, const Vector< double > &b)
Definition: oomph-lib/src/generic/Vector.h:291
Vector< double > vector_diff(const Vector< double > &a, const Vector< double > &b)
Definition: ode_problem.h:46
void check_lengths_match(const Vector< double > &a, const Vector< double > &b)
Check the lengths if two Vectors are the same length.
Definition: oomph-lib/src/generic/Vector.h:271
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
OomphInfo oomph_info
Definition: oomph_definitions.cc:319
t
Definition: plotPSD.py:36
#define OOMPH_EXCEPTION_LOCATION
Definition: oomph_definitions.h:61
#define OOMPH_CURRENT_FUNCTION
Definition: oomph_definitions.h:86
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2