testing
[gnucap-felix.git] / src / bm_exp.cc
blob949cf5537344e34b7b46a826eb4ce396fd6794c2
1 /*$Id: bm_exp.cc,v 1.3 2009-12-13 17:55:01 felix Exp $ -*- C++ -*-
2 * Copyright (C) 2001 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 * 02110-1301, USA.
21 *------------------------------------------------------------------
22 * SPICE compatible EXP
24 //testing=script 2005.10.06
25 #include "e_elemnt.h"
26 #include "u_lang.h"
27 #include "bm.h"
28 /*--------------------------------------------------------------------------*/
29 namespace {
30 /*--------------------------------------------------------------------------*/
31 const double _default_iv (NOT_INPUT);
32 const double _default_pv (NOT_INPUT);
33 const double _default_td1 (0);
34 const double _default_tau1 (0);
35 const double _default_td2 (0);
36 const double _default_tau2 (0);
37 const double _default_period(BIGBIG);
38 /*--------------------------------------------------------------------------*/
39 class EVAL_BM_EXP : public EVAL_BM_ACTION_BASE {
40 private:
41 PARAMETER<double> _iv; // initial value
42 PARAMETER<double> _pv; // pulsed value
43 PARAMETER<double> _td1; // rise delay
44 PARAMETER<double> _tau1; // rise time constant
45 PARAMETER<double> _td2; // fall delay
46 PARAMETER<double> _tau2; // fall time constant
47 PARAMETER<double> _period; // repeat period
48 PARAMETER<double> _end; // marks the end of the list
49 static map<string, PARA_BASE EVAL_BM_EXP::*> param_dict;
50 explicit EVAL_BM_EXP(const EVAL_BM_EXP& p);
51 public:
52 explicit EVAL_BM_EXP(int c=0);
53 ~EVAL_BM_EXP() {}
54 private: // override vitrual
55 bool operator==(const COMMON_COMPONENT&)const;
56 COMMON_COMPONENT* clone()const {return new EVAL_BM_EXP(*this);}
57 void print_common_obsolete_callback(OMSTREAM&, LANGUAGE*)const;
59 void precalc_first(const CARD_LIST*);
60 void tr_eval(ELEMENT*)const;
61 TIME_PAIR tr_review(COMPONENT*)const;
62 std::string name()const {return "exp";}
63 bool ac_too()const {return false;}
64 bool parse_numlist(CS&);
65 void set_param_by_name(string N, string V);
66 bool parse_params_obsolete_callback(CS&);
68 /*--------------------------------------------------------------------------*/
69 /*--------------------------------------------------------------------------*/
70 EVAL_BM_EXP::EVAL_BM_EXP(int c)
71 :EVAL_BM_ACTION_BASE(c),
72 _iv(_default_iv),
73 _pv(_default_pv),
74 _td1(_default_td1),
75 _tau1(_default_tau1),
76 _td2(_default_td2),
77 _tau2(_default_tau2),
78 _period(_default_period),
79 _end(NOT_VALID)
82 /*--------------------------------------------------------------------------*/
83 EVAL_BM_EXP::EVAL_BM_EXP(const EVAL_BM_EXP& p)
84 :EVAL_BM_ACTION_BASE(p),
85 _iv(p._iv),
86 _pv(p._pv),
87 _td1(p._td1),
88 _tau1(p._tau1),
89 _td2(p._td2),
90 _tau2(p._tau2),
91 _period(p._period),
92 _end(NOT_VALID)
95 /*--------------------------------------------------------------------------*/
96 bool EVAL_BM_EXP::operator==(const COMMON_COMPONENT& x)const
98 const EVAL_BM_EXP* p = dynamic_cast<const EVAL_BM_EXP*>(&x);
99 bool rv = p
100 && _iv== p->_iv
101 && _pv== p->_pv
102 && _td1== p->_td1
103 && _tau1== p->_tau1
104 && _td2== p->_td2
105 && _tau2== p->_tau2
106 && _period== p->_period
107 && EVAL_BM_ACTION_BASE::operator==(x);
108 return rv;
110 /*--------------------------------------------------------------------------*/
111 map<string, PARA_BASE EVAL_BM_EXP::*> EVAL_BM_EXP::param_dict =
112 boost::assign::map_list_of
113 ("iv", (PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_iv)
114 ("pv", (PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_pv)
115 ("td1", (PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_td1)
116 ("tau1", (PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_tau1)
117 ("td2", (PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_td2)
118 ("tau2", (PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_tau2)
119 ("period",(PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_period)
120 ("period",(PARA_BASE EVAL_BM_EXP::*) &EVAL_BM_EXP::_period);
121 /*--------------------------------------------------------------------------*/
122 void EVAL_BM_EXP::set_param_by_name(std::string Name, std::string Value)
123 { untested();
124 PARA_BASE EVAL_BM_EXP::* x = (param_dict[Name]);
125 if(x) {
126 PARA_BASE* p = &(this->*x);
127 *p = Value;
128 } else {
129 EVAL_BM_ACTION_BASE::set_param_by_name(Name, Value);
132 /*--------------------------------------------------------------------------*/
133 void EVAL_BM_EXP::print_common_obsolete_callback(OMSTREAM& o, LANGUAGE* lang)const
135 assert(lang);
136 o << name();
137 print_pair(o, lang, "iv", _iv);
138 print_pair(o, lang, "pv", _pv);
139 print_pair(o, lang, "td1", _td1);
140 print_pair(o, lang, "tau1", _tau1);
141 print_pair(o, lang, "td2", _td2);
142 print_pair(o, lang, "tau2", _tau2);
143 print_pair(o, lang, "period",_period, _period.has_hard_value());
144 EVAL_BM_ACTION_BASE::print_common_obsolete_callback(o, lang);
146 /*--------------------------------------------------------------------------*/
147 void EVAL_BM_EXP::precalc_first(const CARD_LIST* Scope)
149 assert(Scope);
150 EVAL_BM_ACTION_BASE::precalc_first(Scope);
151 _iv.e_val(_default_iv, Scope);
152 _pv.e_val(_default_pv, Scope);
153 _td1.e_val(_default_td1, Scope);
154 _tau1.e_val(_default_tau1, Scope);
155 _td2.e_val(_default_td2, Scope);
156 _tau2.e_val(_default_tau2, Scope);
157 _period.e_val(_default_period, Scope);
159 /*--------------------------------------------------------------------------*/
160 void EVAL_BM_EXP::tr_eval(ELEMENT* d)const
162 double ev = _iv;
163 for (double time = d->_sim->_time0; time >= 0; time -= _period) {
164 if (time > _td1) {
165 ev += (_pv - _iv) * (1. - exp(-(time-_td1)/_tau1));
166 }else{
168 if (time > _td2) {
169 ev += (_iv - _pv) * (1. - exp(-(time-_td2)/_tau2));
170 }else{
173 tr_finish_tdv(d, ev);
175 /*--------------------------------------------------------------------------*/
176 TIME_PAIR EVAL_BM_EXP::tr_review(COMPONENT* d)const
178 double time = d->_sim->_time0;
179 time += d->_sim->_dtmin * .01; // hack to avoid duplicate events from numerical noise
180 double raw_time = time;
182 if (0 < _period && _period < BIGBIG) {
183 time = fmod(time,_period);
184 }else{
186 double time_offset = raw_time - time;
188 double dt = NEVER;
189 if (time > _td2) {
190 d->_time_by.min_event(_period + time_offset);
191 dt = (_tau2 > 0) ? _tau2 : NEVER;
192 }else if (time > _td1) {
193 d->_time_by.min_event(_td2 + time_offset);
194 dt = (_tau1 > 0) ? _tau1 : NEVER;
195 }else if (d->_sim->_time0 < _period) {
196 d->_time_by.min_event(_td1 + time_offset);
197 dt = NEVER;
198 }else{
199 d->_time_by.min_event(_td1 + time_offset);
200 dt = (_tau2 > 0) ? _tau2 : NEVER;
202 d->_time_by.min_error_estimate(d->_sim->_time0 + dt);
204 return d->_time_by;
206 /*--------------------------------------------------------------------------*/
207 bool EVAL_BM_EXP::parse_numlist(CS& cmd)
209 unsigned start = cmd.cursor();
210 unsigned here = cmd.cursor();
211 for (PARAMETER<double>* i = &_iv; i < &_end; ++i) {
212 PARAMETER<double> val(NOT_VALID);
213 cmd >> val;
214 if (cmd.stuck(&here)) {
215 break;
216 }else{
217 *i = val;
218 untested();
221 if (cmd.gotit(start)) {
222 untested();
224 return cmd.gotit(start);
226 /*--------------------------------------------------------------------------*/
227 bool EVAL_BM_EXP::parse_params_obsolete_callback(CS& cmd)
229 return ONE_OF
230 || Get(cmd, "iv", &_iv)
231 || Get(cmd, "pv", &_pv)
232 || Get(cmd, "td1", &_td1)
233 || Get(cmd, "tau1", &_tau1)
234 || Get(cmd, "td2", &_td2)
235 || Get(cmd, "tau2", &_tau2)
236 || Get(cmd, "period", &_period)
237 || EVAL_BM_ACTION_BASE::parse_params_obsolete_callback(cmd)
240 /*--------------------------------------------------------------------------*/
241 /*--------------------------------------------------------------------------*/
242 EVAL_BM_EXP p1(CC_STATIC);
243 DISPATCHER<COMMON_COMPONENT>::INSTALL d1(&bm_dispatcher, "exp", &p1);
245 /*--------------------------------------------------------------------------*/
246 /*--------------------------------------------------------------------------*/
247 // vim:ts=8:sw=2:noet: