interactive testing
[gnucap-felix.git] / src / e_compon.h
blob08e51e8dccc812c5cd9c57f6c809c87d9b6519db
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)
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 * base class for all components
24 //testing=script 2007.07.13
25 #ifndef E_COMPON_H
26 #define E_COMPON_H
27 #include "u_sim_data.h"
28 #include "u_time_pair.h"
29 #include "u_parameter.h"
30 #include "e_card.h"
31 #include <typeinfo>
32 //HACK
33 // #include "s_tr.h"
34 // #include "s__.h"
35 //#include "u_adp.h"
36 #include "e_adplist.h"
37 #include "globals.h"
38 /*--------------------------------------------------------------------------*/
39 // needed by storage and ADMS_BASE
40 enum METHOD {mINVALID=-1, mTRAPGEAR, mEULER, mTRAP, mGEAR, mTRAPEULER};
41 #define HAVE_METHOD
42 #include <boost/assign.hpp>
43 #include <boost/algorithm/string.hpp>
44 /*--------------------------------------------------------------------------*/
45 // this file
46 class COMMON_COMPONENT;
47 class COMPONENT;
48 class ADP_CARD;
49 /*--------------------------------------------------------------------------*/
50 // external
51 class MODEL_CARD;
52 class CS;
53 class ELEMENT;
54 class CARD_LIST;
55 class ADP_LIST;
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)
66 :Exception(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 {
75 protected:
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;
81 private:
82 std::string _modelname;
83 mutable const MODEL_CARD* _model;
84 int _attach_count;
85 static std::map<std::string, PARA_BASE COMMON_COMPONENT::*> _param_dict;
86 public:
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;}
92 private:
93 COMMON_COMPONENT& operator=(const COMMON_COMPONENT&)
94 {unreachable(); return *this;}
95 explicit COMMON_COMPONENT() : CKT_BASE() {unreachable();incomplete();}
96 protected:
97 explicit COMMON_COMPONENT(const COMMON_COMPONENT& p);
98 explicit COMMON_COMPONENT(int c);
99 public:
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;}
124 public:
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(){}??
140 public:
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));
159 return _modelname;}
160 const MODEL_CARD* model()const {
161 if(!_model) { untested(); }
162 return _model;}
163 bool has_model()const {return _model;}
164 const PARAMETER<double>& mfactor()const {return _mfactor;}
165 const PARAMETER<double>& value()const {return _value;}
166 private:
167 bool parse_param_list(CS&);
168 public:
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 {
188 private:
189 COMMON_COMPONENT* _common;
190 protected:
191 PARAMETER<double> _value; // value, for simple parts
192 PARAMETER<double> _mfactor; // number of devices in parallel
193 private:
194 double _mfactor_fixed; // composite, including subckt mfactor
195 bool _converged;
196 int _q_for_eval;
197 public:
198 TIME_PAIR _time_by;
199 //--------------------------------------------------------------------
200 protected: // create and destroy.
201 explicit COMPONENT();
202 explicit COMPONENT(const COMPONENT& p);
204 ~COMPONENT();
205 //--------------------------------------------------------------------
206 public: // "elaborate"
207 void precalc_first();
208 void expand();
209 void precalc_last();
210 //--------------------------------------------------------------------
211 public: // dc-tran
212 void tr_iwant_matrix();
213 void tr_queue_eval();
214 TIME_PAIR tr_review();
215 void tr_accept();
216 double tr_probe_num(const std::string&)const;
217 virtual bool has_memory() {return false;}
218 virtual void keep_ic(){};
219 //--------------------------------------------------------------------
220 public: // tt-tran
221 double tt_probe_num(const std::string&)const;
222 //--------------------------------------------------------------------
223 public: // ac
224 void ac_iwant_matrix();
225 //--------------------------------------------------------------------
226 public: // state, aux data
227 bool is_device()const {return true;}
228 void set_slave();
229 void map_nodes();
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);
238 #ifndef NDEBUG
239 if (const COMPONENT* o = prechecked_cast<const COMPONENT*>(owner())) {
240 assert(_mfactor_fixed == o->mfactor() * _mfactor);
241 }else{
242 assert(_mfactor_fixed == _mfactor);
244 #endif
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;}
255 void q_eval();
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 //--------------------------------------------------------------------
260 // model
261 const MODEL_CARD* find_model(const std::string& name)const;
262 void attach_model()const {assert(has_common()); _common->attach_model(this);}
263 //--------------------------------------------------------------------
264 // common
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 //--------------------------------------------------------------------
273 public: // type
274 void set_dev_type(const std::string& new_type);
275 virtual std::string dev_type()const {unreachable(); return "COMPONENT";}
276 //--------------------------------------------------------------------
277 public: // ports
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 //--------------------------------------------------------------------
335 public:
336 ADP_CARD* adp()const {return(_adp);}
337 void attach_adp(ADP_CARD* a);
338 protected:
339 double _tr_amps_diff_cur;
340 double _tr_amps_diff_max;
341 double _tr_amps_scale_max;
342 double* _amps;
343 double* _amps_new;
344 double _amps_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() );
351 _amps=NULL;
352 // _amps_new = (double*) malloc(sizeof (double) * net_nodes() * TRANSIENT::total_outsteps() );
353 // _amps_new = new double[net_nodes() * TRANSIENT::steps_total_out()];
357 void tr_dinge(){
358 // _amps[SIM::stepno()]= 4;
361 void tr_diff_amps();
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; }
369 private:
370 ADP_CARD* _adp;
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 /*--------------------------------------------------------------------------*/
387 #endif
388 // vim:ts=8:sw=2:noet: