BDF.h (2231B)
1 /* File: BDF.h */ 2 /* Date: Mon Feb 8 11:44:23 2016 */ 3 /* Author: Fabian Wermelinger */ 4 /* Tag: Backward differentiation formula using SUNDIALS library */ 5 /* Copyright 2016 ETH Zurich. All Rights Reserved. */ 6 #ifndef BDF_H_YF523CRX 7 #define BDF_H_YF523CRX 8 9 #ifdef _USE_SUNDIALS_ 10 #include <ODETB/TimeStepper/StepperBase.h> 11 12 #include <cvode/cvode.h> 13 #include <cvode/cvode_dense.h> 14 #include <nvector/nvector_serial.h> 15 16 #include <cassert> 17 18 template <typename Tinput, typename Trhs> 19 class BDF : public StepperBase<Tinput,Trhs> 20 { 21 Real m_a; 22 void* m_cvode_mem; 23 N_Vector m_y; 24 25 void _init_sundials() 26 { 27 m_cvode_mem = CVodeCreate(CV_BDF, CV_NEWTON); 28 m_y = N_VMake_Serial(Tinput::SIZE, m_U.data()); 29 CVodeInit(m_cvode_mem, BDF::f, 0.0, m_y); 30 CVodeSStolerances(m_cvode_mem, 1.0e-6, 1.0e-6); 31 CVDense(m_cvode_mem, Trhs::SIZE); 32 CVodeSetUserData(m_cvode_mem, static_cast<void*>(&m_a)); 33 } 34 35 protected: 36 using StepperBase<Tinput,Trhs>::m_settings; 37 using StepperBase<Tinput,Trhs>::m_U; 38 using StepperBase<Tinput,Trhs>::m_kernel; 39 Trhs m_rhs; 40 41 public: 42 BDF(Tinput& U, StepperSettings& S, KernelBase<Tinput,Trhs> * const kern) : 43 StepperBase<Tinput,Trhs>(U,S,kern), m_rhs(U.size()) 44 { 45 _init_sundials(); 46 } 47 ~BDF() { CVodeFree(&m_cvode_mem); } 48 49 virtual void step(void const* const data=nullptr) 50 { 51 /* TODO: (fabianw; Fri Feb 12 13:26:02 2016) this does not work yet. 52 * Do not compile with Sundials support */ 53 /* m_a = a; */ 54 Real tret; // interface dummy 55 CVode(m_cvode_mem, t+dt, m_y, &tret, CV_ONE_STEP); 56 t = tret; 57 58 if (m_settings.step % m_settings.reportGranularity == 0) 59 std::printf("Time = %e;\tStep = %d\n", m_settings.t, m_settings.step); 60 } 61 62 virtual inline void setIC(Real const ic, const Real t0=0) 63 { 64 m_U = ic; 65 CVodeReInit(m_cvode_mem, t0, m_y); 66 } 67 68 static inline int f(Real t, N_Vector y, N_Vector ydot, void *a) 69 { 70 Tkernel kernel(Trhs::SIZE); 71 kernel.compute(NV_DATA_S(y), NV_DATA_S(ydot), *static_cast<Real*>(a), t); 72 return 0; 73 } 74 }; 75 #endif /* _USE_SUNDIALS_ */ 76 77 #endif /* BDF_H_YF523CRX */