⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ode.cpp

📁 利用C
💻 CPP
字号:
// Copyright (C) 2003-2008 Johan Jansson and Anders Logg.// Licensed under the GNU LGPL Version 2.1.//// First added:  2003-10-21// Last changed: 2008-04-22#include <dolfin/common/constants.h>#include <dolfin/math/dolfin_math.h>#include <dolfin/la/uBlasVector.h>#include "ODESolver.h"#include "ODE.h"using namespace dolfin;//-----------------------------------------------------------------------------ODE::ODE(uint N, real T)  : N(N), T(T), dependencies(N), transpose(N), tmp(0),    not_impl_f("Warning: consider implementing mono-adaptive ODE::f() to improve efficiency."),    not_impl_M("Warning: multiplication with M not implemented, assuming identity."),    not_impl_J("Warning: consider implementing Jacobian ODE::J() to improve efficiency."),    not_impl_JT("Warning: consider implementing Jacobian transpose ODE::JT() to improve efficiency"){  message("Creating ODE of size %d.", N);}//-----------------------------------------------------------------------------ODE::~ODE(){  // Do nothing}//-----------------------------------------------------------------------------void ODE::f(const uBlasVector& u, real t, uBlasVector& y){  // If a user of the mono-adaptive solver does not supply this function,  // then call f_i() for each component.  // Display a warning, more efficiently if implemented  not_impl_f();  // Call f for each component  for (uint i = 0; i < N; i++)    y[i] = this->f(u, t, i);}//-----------------------------------------------------------------------------real ODE::f(const uBlasVector& u, real t, uint i){  error("Right-hand side for ODE not supplied by user.");  return 0.0;}//-----------------------------------------------------------------------------void ODE::M(const uBlasVector& x, uBlasVector& y, const uBlasVector& u, real t){  // Display a warning, implicit system but M is not implemented  not_impl_M();  // Assume M is the identity if not supplied by user: y = x  y = x;}//-----------------------------------------------------------------------------void ODE::J(const uBlasVector& x, uBlasVector& y, const uBlasVector& u, real t){  // If a user does not supply J, then compute it by the approximation  //  //     Jx = ( f(u + hx) - f(u - hx) ) / 2h  // FIXME: Maybe we should move this somewhere else?  // Display a warning, more efficiently if implemented  not_impl_J();  // Small change in u  real umax = 0.0;  for (unsigned int i = 0; i < N; i++)    umax = std::max(umax, std::abs(u[i]));  real h = std::max(DOLFIN_SQRT_EPS, DOLFIN_SQRT_EPS * umax);  // We are not allowed to change u, but we restore it afterwards,  // so maybe we can cheat a little...  uBlasVector& uu = const_cast<uBlasVector&>(u);  // Initialize temporary array if necessary  if ( tmp.size() != N )    tmp.init(N);    // Evaluate at u + hx  ublas::noalias(uu.vec()) += h*x.vec();  f(uu, t, y);  // Evaluate at u - hx  ublas::noalias(uu.vec()) -= 2.0*h*x.vec();  f(uu, t, tmp);  // Reset u  ublas::noalias(uu.vec()) += h*x.vec();  // Compute product y = Jx  ublas::noalias(y.vec()) -= tmp.vec();  y *= 0.5/h;}//------------------------------------------------------------------------void ODE::JT(const uBlasVector& x, uBlasVector& y, const uBlasVector& u, real t) {  //Display warning  not_impl_JT();  // Similar to J()  real umax = 0.0;  for (unsigned int i = 0; i < N; i++)    umax = std::max(umax, std::abs(u[i]));  real h = std::max(DOLFIN_SQRT_EPS, DOLFIN_SQRT_EPS * umax);  uBlasVector& uu = const_cast<uBlasVector&>(u);  if ( tmp.size() != N )    tmp.init(N);  uBlasVector tmp2(N);  for (uint i = 0; i < N; ++i) {    uu[i] += h; //small change component i    f(uu, t, tmp);        uu[i] -= 2*h;    f(uu, t, tmp2);    //restore u    uu[i] += h;    tmp -= tmp2;    tmp /= 2*h;    y[i] = ublas::inner_prod(tmp.vec(), x.vec());  }}//------------------------------------------------------------------------real ODE::dfdu(const uBlasVector& u, real t, uint i, uint j){  // Compute Jacobian numerically if dfdu() is not implemented by user    // FIXME: Maybe we should move this somewhere else?  // We are not allowed to change u, but we restore it afterwards,  // so maybe we can cheat a little...  uBlasVector& uu = const_cast<uBlasVector&>(u);  // Save value of u_j  real uj = uu[j];    // Small change in u_j  real h = std::max(DOLFIN_SQRT_EPS, DOLFIN_SQRT_EPS * std::abs(uj));    // Compute F values  uu[j] -= 0.5 * h;  real f1 = f(uu, t, i);    uu[j] = uj + 0.5*h;  real f2 = f(uu, t, i);           // Reset value of uj  uu[j] = uj;  // Compute derivative  if ( std::abs(f1 - f2) < DOLFIN_EPS * std::max(std::abs(f1), std::abs(f2)) )    return 0.0;  return (f2 - f1) / h;}//-----------------------------------------------------------------------------real ODE::timestep(real t, real k0) const{  // Keep old time step by default when "fixed time step" is set  // and user has not overloaded this function  return k0;}//-----------------------------------------------------------------------------real ODE::timestep(real t, uint i, real k0) const{  // Keep old time step by default when "fixed time step" is set  // and user has not overloaded this function  return k0;}//-----------------------------------------------------------------------------bool ODE::update(const uBlasVector& u, real t, bool end){  return true;}//-----------------------------------------------------------------------------void ODE::save(Sample& sample){  // Do nothing}//-----------------------------------------------------------------------------real ODE::time(real t) const{  return t;}//-----------------------------------------------------------------------------void ODE::sparse(){  dependencies.detect(*this);}//-----------------------------------------------------------------------------void ODE::sparse(const uBlasSparseMatrix& A){  dependencies.set(A);}//-----------------------------------------------------------------------------dolfin::uint ODE::size() const{  return N;  }//-----------------------------------------------------------------------------real ODE::endtime() const{  return T;}//-----------------------------------------------------------------------------void ODE::solve(){  ODESolver::solve(*this);}//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -