/*$Id: e_storag.h,v 26.13 2007/01/25 01:30:04 al Exp $ -*- C++ -*- * Copyright (C) 2001 Albert Davis * Author: Albert Davis * * This file is part of "Gnucap", the Gnu Circuit Analysis Package * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. *------------------------------------------------------------------ * "base" class for energy storage elements (L & C) */ //testing=script,complete 2006.07.11 #ifndef E_STORAGE_H #define E_STORAGE_H #include "e_elemnt.h" /*--------------------------------------------------------------------------*/ enum METHOD {mTRAPGEAR, mEULER, mTRAP, mGEAR, mTRAPEULER}; /*--------------------------------------------------------------------------*/ FPOLY1 differentiate(const FPOLY1* q, const FPOLY1* i, double* time, METHOD method); /*--------------------------------------------------------------------------*/ class STORAGE : public ELEMENT { private: protected: explicit STORAGE() :ELEMENT(), _method_u(meUNKNOWN), _method_a(mTRAPGEAR) {} explicit STORAGE(const STORAGE& p) :ELEMENT(p), _method_u(p._method_u), _method_a(p._method_a) {} ~STORAGE() {} protected: // override virtual void precalc(); void dc_begin(); void tr_begin() {STORAGE::dc_begin();} void tr_restore(); void dc_advance(); void tr_advance(); bool tr_needs_eval()const; //void tr_queue_eval() //ELEMENT DPAIR tr_review(); double tr_probe_num(CS&)const; public: FPOLY1 differentiate(); double tr_review_trunc_error(const FPOLY1* q); double tr_review_check_and_convert(double timestep); double tr_c_to_g(double c, double g)const; private: int order()const { const int o[] = {1, 1, 2, 1, 1}; int ord = o[_method_a]; assert(ord <= _max_order); return ord; } double error_factor()const { const double f[]={1./2., 1./2., 1./12., 1./2., 1./2.}; return f[_method_a]; } public: // used by commons enum {_max_order = 2, _keep_time_steps=_max_order+1}; method_t _method_u; /* method to use for this part per user */ METHOD _method_a; /* actual integration method (auto) */ double _time_future; double _time[_keep_time_steps]; double _dt; FPOLY1 _q[_keep_time_steps]; /* charge or flux, and deriv. */ protected: FPOLY1 _i[_keep_time_steps]; /* deriv of _q */ protected: static METHOD method_select[meNUM_METHODS][meNUM_METHODS]; }; /*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/ #endif