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)
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
21 *------------------------------------------------------------------
22 * SPICE compatible EXP
24 //testing=script 2005.10.06
28 /*--------------------------------------------------------------------------*/
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
{
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
);
52 explicit EVAL_BM_EXP(int c
=0);
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
),
78 _period(_default_period
),
82 /*--------------------------------------------------------------------------*/
83 EVAL_BM_EXP::EVAL_BM_EXP(const EVAL_BM_EXP
& p
)
84 :EVAL_BM_ACTION_BASE(p
),
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
);
106 && _period
== p
->_period
107 && EVAL_BM_ACTION_BASE::operator==(x
);
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
)
124 PARA_BASE
EVAL_BM_EXP::* x
= (param_dict
[Name
]);
126 PARA_BASE
* p
= &(this->*x
);
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
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
)
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
163 for (double time
= d
->_sim
->_time0
; time
>= 0; time
-= _period
) {
165 ev
+= (_pv
- _iv
) * (1. - exp(-(time
-_td1
)/_tau1
));
169 ev
+= (_iv
- _pv
) * (1. - exp(-(time
-_td2
)/_tau2
));
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
);
186 double time_offset
= raw_time
- time
;
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
);
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
);
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
);
214 if (cmd
.stuck(&here
)) {
221 if (cmd
.gotit(start
)) {
224 return cmd
.gotit(start
);
226 /*--------------------------------------------------------------------------*/
227 bool EVAL_BM_EXP::parse_params_obsolete_callback(CS
& cmd
)
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: