1 /*$Id: e_compon.h 2016/03/23 al $ -*- 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 * base class for all components
24 //testing=script 2007.07.13
27 #include "u_sim_data.h"
28 #include "u_time_pair.h"
29 #include "u_parameter.h"
36 #include "e_adplist.h"
38 /*--------------------------------------------------------------------------*/
39 // needed by storage and ADMS_BASE
40 enum METHOD
{mINVALID
=-1, mTRAPGEAR
, mEULER
, mTRAP
, mGEAR
, mTRAPEULER
};
42 #include <boost/assign.hpp>
43 #include <boost/algorithm/string.hpp>
44 /*--------------------------------------------------------------------------*/
46 class COMMON_COMPONENT
;
49 /*--------------------------------------------------------------------------*/
56 /*--------------------------------------------------------------------------*/
57 template<class T
, class S
>
58 inline bool conchk(T o
, S n
,
59 double a
=OPT::abstol
, double r
=OPT::reltol
)
61 return (std::abs(n
-o
) <= (r
* std::abs(n
) + a
));
63 /*--------------------------------------------------------------------------*/
64 struct Exception_Precalc
:public Exception
{
65 Exception_Precalc(const std::string
& Message
)
69 /*--------------------------------------------------------------------------*/
70 enum {CC_STATIC
=27342}; // mid-sized arbitrary positive int
71 // pass this as an argument to a common constructor to mark it as static,
72 // so it won't be deleted
73 /*--------------------------------------------------------------------------*/
74 class INTERFACE COMMON_COMPONENT
: public CKT_BASE
{
76 PARAMETER
<double> _tnom_c
; // specification temperature
77 PARAMETER
<double> _dtemp
; // rise over enclosing temperature
78 PARAMETER
<double> _temp_c
; // actual temperature of device
79 PARAMETER
<double> _mfactor
; // number of devices in parallel
80 PARAMETER
<double> _value
;
82 std::string _modelname
;
83 mutable const MODEL_CARD
* _model
;
85 static std::map
<std::string
, PARA_BASE
COMMON_COMPONENT::*> _param_dict
;
87 static void attach_common(COMMON_COMPONENT
* c
, COMMON_COMPONENT
** to
);
88 static void detach_common(COMMON_COMPONENT
** from
);
89 int attach_count(){return _attach_count
;}
90 void set_value(double x
) { _value
= x
; } // HACK
91 virtual bool is_constant()const{return false;}
93 COMMON_COMPONENT
& operator=(const COMMON_COMPONENT
&)
94 {unreachable(); return *this;}
95 explicit COMMON_COMPONENT() : CKT_BASE() {unreachable();incomplete();}
97 explicit COMMON_COMPONENT(const COMMON_COMPONENT
& p
);
98 explicit COMMON_COMPONENT(int c
);
100 virtual ~COMMON_COMPONENT();
102 void attach_model(const COMPONENT
*)const;
103 COMMON_COMPONENT
& attach(const MODEL_CARD
* m
) {_model
= m
; return *this;}
104 void set_modelname(const std::string
& n
) {_modelname
= n
;}
105 void parse_modelname(CS
&);
107 virtual COMMON_COMPONENT
* clone()const = 0;
109 virtual bool use_obsolete_callback_parse()const {return false;}
110 virtual bool use_obsolete_callback_print()const {return false;}
111 virtual void parse_common_obsolete_callback(CS
&);
112 virtual void print_common_obsolete_callback(OMSTREAM
&, LANGUAGE
*)const;
113 virtual bool has_parse_params_obsolete_callback()const {return false;}
114 virtual bool is_trivial()const {return false;}
116 virtual bool param_is_printable(int)const;
117 virtual std::string
param_name(int)const;
118 virtual std::string
param_name(int,int)const;
119 virtual std::string
param_value(int)const;
120 virtual void set_param_by_name(std::string
, std::string
);
121 void Set_param_by_name(std::string
, std::string
); //BUG// see implementation
122 virtual void set_param_by_index(int, std::string
&, int);
123 virtual int param_count()const {return 4;}
125 virtual void precalc_first(const CARD_LIST
*) {}
126 virtual void expand(const COMPONENT
*) {}
127 virtual COMMON_COMPONENT
* deflate() {return this;}
128 virtual void precalc_last(const CARD_LIST
*);
130 virtual void tr_eval(ELEMENT
*)const;
131 virtual void ac_eval(ELEMENT
*)const;
132 virtual TIME_PAIR
tr_review(COMPONENT
*)const {return TIME_PAIR(NEVER
,NEVER
);}
133 virtual void tr_accept(COMPONENT
*)const {}
134 virtual bool has_tr_eval()const {untested(); return false;}
135 virtual bool has_ac_eval()const {untested(); return false;}
136 virtual void set_ic(double){ error(bWARNING
, "set_ic not implemented for %s\n", typeid(*this).name()); }
137 virtual double* set__ic() { return NULL
; }
138 // virtual void keep_ic(){}??
141 virtual bool has_tt_eval()const {untested(); return false;}
142 virtual void tt_commit (ELEMENT
*)const;
143 virtual void do_tt() {untested();}
145 virtual bool parse_numlist(CS
&);
146 virtual bool parse_params_obsolete_callback(CS
&);
147 virtual void skip_type_tail(CS
&)const {}
148 virtual void parse_type_tail(CS
&) {}
150 virtual std::string
name()const = 0;
151 virtual bool operator==(const COMMON_COMPONENT
&x
)const;
153 bool operator!=(const COMMON_COMPONENT
& x
)const {return !(*this == x
);}
154 int attach_count()const{
155 return _attach_count
;
157 std::string
modelname()const {
158 //trace1("COMMON_COMPONENT::modelname", hp(this));
160 const MODEL_CARD
* model()const {
161 if(!_model
) { untested(); }
163 bool has_model()const {return _model
;}
164 const PARAMETER
<double>& mfactor()const {return _mfactor
;}
165 const PARAMETER
<double>& value()const {return _value
;}
167 bool parse_param_list(CS
&);
169 double temp()const{return _temp_c
;}
171 /*--------------------------------------------------------------------------*/
172 /* note on _attach_count ...
173 * The int argument is the initial _attach_count (default = 0)
174 * Set it to CC_STATIC for static default versions that will never be deleted.
175 * Set it to 0 (default) for auto versions, so they can be deleted.
176 * A common will not be deleted on a detach if its _attach_count != 0
177 * A failed assertion from the common destructor probably means
178 * the common is being deleted before a device it is attached to is,
179 * without being first detached.
180 * This is why ~COMPONENT destroys the subckt explicitly.
182 * Static commons (CC_STATIC) must be in file scope, not in function scope,
183 * because local statics are deleted first, before any globals.
184 * //BUG// possible portability problem. What is deletion order?
186 /*--------------------------------------------------------------------------*/
187 class INTERFACE COMPONENT
: public CARD
{
189 COMMON_COMPONENT
* _common
;
191 PARAMETER
<double> _value
; // value, for simple parts
192 PARAMETER
<double> _mfactor
; // number of devices in parallel
194 double _mfactor_fixed
; // composite, including subckt mfactor
199 //--------------------------------------------------------------------
200 protected: // create and destroy.
201 explicit COMPONENT();
202 explicit COMPONENT(const COMPONENT
& p
);
205 //--------------------------------------------------------------------
206 public: // "elaborate"
207 void precalc_first();
210 //--------------------------------------------------------------------
212 void tr_iwant_matrix();
213 void tr_queue_eval();
214 TIME_PAIR
tr_review();
216 double tr_probe_num(const std::string
&)const;
217 virtual bool has_memory() {return false;}
218 virtual void keep_ic(){};
219 //--------------------------------------------------------------------
221 double tt_probe_num(const std::string
&)const;
222 //--------------------------------------------------------------------
224 void ac_iwant_matrix();
225 //--------------------------------------------------------------------
226 public: // state, aux data
227 bool is_device()const {return true;}
230 virtual const std::string
current_probe_name()const {untested(); return "";}
231 static double volts_limited(const node_t
& n1
, const node_t
& n2
);
232 bool converged()const {return _converged
;}
233 void set_converged(bool s
=true) {_converged
= s
;}
234 void set_not_converged() {_converged
= false;}
236 double mfactor()const {
237 assert(_mfactor_fixed
!= NOT_VALID
);
239 if (const COMPONENT
* o
= prechecked_cast
<const COMPONENT
*>(owner())) {
240 assert(_mfactor_fixed
== o
->mfactor() * _mfactor
);
242 assert(_mfactor_fixed
== _mfactor
);
245 return _mfactor_fixed
;
247 //--------------------------------------------------------------------
248 // list and queue management
249 bool is_q_for_eval()const {return (_q_for_eval
>= _sim
->iteration_tag());}
250 void mark_q_for_eval() {
251 assert(_q_for_eval
!= INT_MAX
);
252 _q_for_eval
= _sim
->iteration_tag();
254 void mark_always_q_for_eval() {_q_for_eval
= INT_MAX
;}
256 void q_load() {_sim
->_loadq
.push_back(this);}
257 void q_accept() {_sim
->_acceptq
.push_back(this);}
258 void q_tt_accept() {_sim
->_tt_acceptq
.push_back(this);}
259 //--------------------------------------------------------------------
261 const MODEL_CARD
* find_model(const std::string
& name
)const;
262 void attach_model()const {assert(has_common()); _common
->attach_model(this);}
263 //--------------------------------------------------------------------
265 COMMON_COMPONENT
* mutable_common() {return _common
;}
266 const COMMON_COMPONENT
* common()const {return _common
;}
267 bool has_common()const {return _common
;}
268 void attach_common(COMMON_COMPONENT
*c
) {
269 COMMON_COMPONENT::attach_common(c
,&_common
);}
270 void detach_common() {COMMON_COMPONENT::detach_common(&_common
);}
271 void deflate_common();
272 //--------------------------------------------------------------------
274 void set_dev_type(const std::string
& new_type
);
275 virtual std::string
dev_type()const {unreachable(); return "COMPONENT";}
276 //--------------------------------------------------------------------
278 virtual std::string
port_name(uint_t
)const = 0;
279 virtual void set_port_by_name(std::string
& name
, std::string
& value
);
280 virtual void set_port_by_index(uint_t index
, std::string
& value
);
281 bool port_exists(uint_t i
)const {return i
< net_nodes();}
282 const std::string
port_value(uint_t i
)const;
283 void set_port_to_ground(uint_t index
);
285 virtual std::string
current_port_name(uint_t
)const {return "";}
286 virtual const std::string
current_port_value(uint_t
)const;
287 virtual void set_current_port_by_index(uint_t
, const std::string
&) {unreachable();}
288 bool current_port_exists(uint_t i
)const {return i
< num_current_ports();}
290 virtual uint_t
max_nodes()const {unreachable(); return 0;}
291 virtual uint_t
min_nodes()const {unreachable(); return 0;}
292 virtual uint_t
num_current_ports()const {return 0;}
293 virtual uint_t
tail_size()const {return 0;}
295 virtual uint_t
net_nodes()const {return 0;} //override
296 virtual uint_t
ext_nodes()const {return max_nodes();}
297 virtual uint_t
int_nodes()const {return 0;}
298 virtual uint_t
matrix_nodes()const {return 0;}
300 virtual bool has_inode()const {return false;}
301 virtual bool has_iv_probe()const {return false;}
302 virtual bool is_source()const {return false;}
303 virtual bool f_is_value()const {return false;}
305 bool node_is_grounded(uint_t i
)const;
306 virtual bool node_is_connected(uint_t i
)const;
307 //--------------------------------------------------------------------
308 public: // parameters
309 void set_param_by_name(std::string
, std::string
);
310 void set_param_by_index(int, std::string
&, int);
311 int param_count()const
312 {return ((has_common()) ? (common()->param_count()) : (2 + CARD::param_count()));}
313 bool param_is_printable(int)const;
314 std::string
param_name(int)const;
315 std::string
param_name(int,int)const;
316 std::string
param_value(int)const;
318 virtual void set_parameters(const std::string
& Label
, CARD
* Parent
,
319 COMMON_COMPONENT
* Common
, double Value
,
320 uint_t state_count
, hp_float_t state
[],
321 uint_t node_count
, const node_t nodes
[]);
322 void set_value(const PARAMETER
<double>& v
) {_value
= v
;}
323 void set_value(double v
) {_value
= v
;}
324 void set_value(const std::string
& v
) {_value
= v
;}
325 void set_value(double v
, COMMON_COMPONENT
* c
);
326 const PARAMETER
<double>& value()const {return _value
;}
327 //--------------------------------------------------------------------
328 public: // obsolete -- do not use in new code
329 virtual bool print_type_in_spice()const {return false;}
330 bool use_obsolete_callback_parse()const;
331 bool use_obsolete_callback_print()const;
332 void print_args_obsolete_callback(OMSTREAM
&, LANGUAGE
*)const;
333 void obsolete_move_parameters_from_common(const COMMON_COMPONENT
*);
334 //--------------------------------------------------------------------
336 ADP_CARD
* adp()const {return(_adp
);}
337 void attach_adp(ADP_CARD
* a
);
339 double _tr_amps_diff_cur
;
340 double _tr_amps_diff_max
;
341 double _tr_amps_scale_max
;
346 void tt_behaviour_update();
347 void tr_behaviour(){ tt_behaviour_update(); }
349 virtual void tt_init_i(){
350 // _amps = (double*) malloc(sizeof (double) * net_nodes() * TRANSIENT::total_outsteps() );
352 // _amps_new = (double*) malloc(sizeof (double) * net_nodes() * TRANSIENT::total_outsteps() );
353 // _amps_new = new double[net_nodes() * TRANSIENT::steps_total_out()];
358 // _amps[SIM::stepno()]= 4;
362 double _amps_max_diff
;
363 double get_amps_max_diff(){ return _amps_max_diff
; }
364 virtual void tr_do_behaviour();
365 virtual void tr_save_amps(int n
);
366 void reset_amps_max_diff(){ _amps_max_diff
=0; }
371 public: // twotime interface.
372 virtual void tt_begin() {}
373 virtual void tt_next() {}
374 virtual void tt_accept();
375 virtual void do_tt() {}
376 virtual void tr_stress() {unreachable();} // obsolete. still used by d_mos
377 virtual void tr_stress_last() { trace1("COMPONENT::tr_stress_last", long_label());}
378 virtual double tr_amps_diff()const {return 0.;}
379 virtual double tr_amps_diff_cur()const {return 0.;}
380 virtual bool has_stress()const {untested(); return false;}
382 public: // move to element? rcd is not an element currently...
383 double tt_review_check_and_convert(double timestep
);
385 /*--------------------------------------------------------------------------*/
386 /*--------------------------------------------------------------------------*/
388 // vim:ts=8:sw=2:noet: