ode_element_for_imr.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_ELEMENT_FOR_IMR_H
27 #define OOMPH_ODE_ELEMENT_FOR_IMR_H
28 
29 
30 #include "generic.h"
31 #include "ode.h"
32 
33 namespace oomph
34 {
39  class IMRODEElement : public ODEElement
40  {
41  public:
43  IMRODEElement(TimeStepper* time_stepper_pt,
44  SolutionFunctorBase* exact_solution_pt)
45  : ODEElement(time_stepper_pt, exact_solution_pt) {}
46 
48  virtual ~IMRODEElement() {}
49 
54  {
55 
56  // Get pointer to one-and-only internal data object
57  Data* dat_pt = internal_data_pt(0);
58 
59  // Get time stepper
60  TimeStepper* ts_pt = dat_pt->time_stepper_pt();
61 
62  // Number of history values to interpolate over for value/time calculation
63  const unsigned nj = ts_pt->nprev_values_for_value_at_evaluation_time();
64 
65  Vector<double> u(nvalue(), 0.0);
66  for(unsigned j=0; j<nj; j++)
67  {
68  for(unsigned i=0; i<nvalue(); i++)
69  {
70  u[i] += dat_pt->value(j, i) * ts_pt->weight(0, j);
71  }
72  }
73 
74  return u;
75  }
76 
80  double time_interpolate_time() const
81  {
82 
83  // Get pointer to one-and-only internal data object
84  Data* dat_pt = internal_data_pt(0);
85 
86  // Get time stepper
87  TimeStepper* ts_pt = dat_pt->time_stepper_pt();
88 
89  // Number of history values to interpolate over for value/time calculation
90  const unsigned nj = ts_pt->nprev_values_for_value_at_evaluation_time();
91 
92  double t = 0;
93  for(unsigned j=0; j<nj; j++)
94  {
95  t += ts_pt->time_pt()->time(j) * ts_pt->weight(0, j);
96  }
97 
98  return t;
99  }
100 
105  {
106 
107  // Get pointer to one-and-only internal data object
108  Data* dat_pt = internal_data_pt(0);
109 
110  // Get time stepper
111  TimeStepper* ts_pt = dat_pt->time_stepper_pt();
112 
113  // Get values **interpolated in time**
115 
116  // Get **interpolated** continuous time
117  double t = time_interpolate_time();
118 
120  for(unsigned j=0, nj=deriv.size(); j<nj; j++)
121  {
122  // Get dudt approximation from time stepper
123  double dudt = ts_pt->time_derivative(1, dat_pt, j);
124 
125  // Residual is difference between the exact derivative and our
126  // time stepper's derivative estimate.
127  residuals[j] = deriv[j] - dudt;
128  }
129  }
130 
139  DenseMatrix<double>& jacobian)
140  {
141  // Get residuals
143 
145  {
146  const unsigned n = nvalue();
148 
149  // Get values **interpolated in time**
151 
152  // Get **interpolated** continuous time
153  double t = time_interpolate_time();
154 
155  // get df/du jacobian analytically
156  Vector<double> dummy;
157  Exact_solution_pt->jacobian(t, dummy, u, jacobian);
158 
159  // Multiply by the weight of the history value 0 (i.e. at time n+1) in
160  // the calculation of the time-interpolated "current" value (0th
161  // derivative). Need to do this because of the chain rule, just write
162  // out the derivation of dr/du for nvalue=1 to see it.
163  const double w00 = ts_pt->weight(0,0);
164  for(unsigned i=0; i<n; i++)
165  {
166  for(unsigned j=0; j<n; j++)
167  {
168  jacobian(i, j) *= w00;
169  }
170  }
171 
172  // We actually need jacobian of residual = f(imr_t, imr_u) - dudt so
173  // subtract diagonal (dudt)/du term now.
174  const double w10 = ts_pt->weight(1,0);
175  for(unsigned i=0; i<n; i++)
176  {
177  jacobian(i, i) -= w10;
178  }
179  }
180  else
181  {
182  // Use FD for jacobian
184  (residuals, jacobian, true);
185  }
186  }
187 
188  // Mass matrix calculation should be unaffected by the use of IMR.
189 
190  private:
193  {BrokenCopy::broken_copy("IMRODEElement");}
194 
195  };
196 
197 } // End of oomph namespace
198 
199 #endif
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
Definition: nodes.h:86
TimeStepper *& time_stepper_pt()
Return the pointer to the timestepper.
Definition: nodes.h:238
double value(const unsigned &i) const
Definition: nodes.h:293
Data *& internal_data_pt(const unsigned &i)
Return a pointer to i-th internal data object.
Definition: elements.h:622
void fill_in_jacobian_from_internal_by_fd(Vector< double > &residuals, DenseMatrix< double > &jacobian, const bool &fd_all_data=false)
Definition: elements.cc:1102
Definition: ode_element_for_imr.h:40
Vector< double > time_interpolate_u() const
Definition: ode_element_for_imr.h:53
void fill_in_contribution_to_residuals(Vector< double > &residuals)
Definition: ode_element_for_imr.h:104
IMRODEElement(TimeStepper *time_stepper_pt, SolutionFunctorBase *exact_solution_pt)
Constructor.
Definition: ode_element_for_imr.h:43
void fill_in_contribution_to_jacobian(Vector< double > &residuals, DenseMatrix< double > &jacobian)
Definition: ode_element_for_imr.h:138
double time_interpolate_time() const
Definition: ode_element_for_imr.h:80
IMRODEElement(const IMRODEElement &dummy)
Broken copy constructor.
Definition: ode_element_for_imr.h:192
virtual ~IMRODEElement()
Virtual destructor.
Definition: ode_element_for_imr.h:48
Element for integrating an initial value ODE.
Definition: ode_elements.h:41
bool Use_fd_jacobian
Definition: ode_elements.h:182
SolutionFunctorBase * Exact_solution_pt
Definition: ode_elements.h:180
Vector< double > derivative_function(const double &t, const Vector< double > &u)
Exact solution.
Definition: ode_elements.h:166
unsigned nvalue() const
Definition: ode_elements.h:76
Definition: oomph_utilities.h:1109
virtual void jacobian(const double &t, const Vector< double > &x, const Vector< double > &u, DenseMatrix< double > &jacobian) const
Definition: oomph_utilities.h:1142
virtual bool have_jacobian() const
Is a jacobian function implemented?
Definition: oomph_utilities.h:1153
Definition: timesteppers.h:231
virtual double weight(const unsigned &i, const unsigned &j) const
Access function for j-th weight for the i-th derivative.
Definition: timesteppers.h:594
virtual unsigned nprev_values_for_value_at_evaluation_time() const
Definition: timesteppers.h:359
void time_derivative(const unsigned &i, Data *const &data_pt, Vector< double > &deriv)
Definition: timesteppers.h:502
Time *const & time_pt() const
Access function for the pointer to time (const version)
Definition: timesteppers.h:572
double & time()
Return the current value of the continuous time.
Definition: timesteppers.h:123
void broken_copy(const std::string &class_name)
Issue error message and terminate execution.
Definition: oomph_utilities.cc:212
DRAIG: Change all instances of (SPATIAL_DIM) to (DIM-1).
Definition: AnisotropicHookean.h:10
t
Definition: plotPSD.py:36
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2