1 /*$Id: d_poly_cap.cc $ -*- 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 *------------------------------------------------------------------
23 * number of nodes = 2*n_ports
24 * number of val, ov = n_ports+1
25 * val[0] is the constant part, val[1] is self admittance,
26 * val[2+] are transadmittances, up to n_ports
27 * node[0] and node[1] are the output.
28 * node[2] up are inputs.
29 * node[2*i] and node[2*i+1] correspond to val[i+1]
31 //testing=script 2006.07.17
33 /*--------------------------------------------------------------------------*/
35 /*--------------------------------------------------------------------------*/
36 class DEV_CPOLY_CAP
: public STORAGE
{
38 hp_float_t
* _vy0
; // vector form of _y0 _values; charge, capacitance
39 hp_float_t
* _vy1
; // vector form of _y1 _old_values;
40 hp_float_t
* _vi0
; // vector form of _i0; current, difference conductance
41 hp_float_t
* _vi1
; // vector form of _i1
43 hp_float_t _load_time
;
44 const hp_float_t
** _inputs
;
46 explicit DEV_CPOLY_CAP(const DEV_CPOLY_CAP
& p
);
48 explicit DEV_CPOLY_CAP();
50 protected: // override virtual
51 char id_letter()const {unreachable(); return '\0';}
52 std::string
value_name()const {incomplete(); return "";}
53 std::string
dev_type()const {unreachable(); return "cpoly_cap";}
54 uint_t
max_nodes()const {return net_nodes();}
55 uint_t
min_nodes()const {return net_nodes();}
56 uint_t
matrix_nodes()const {return _n_ports
*2;}
57 uint_t
net_nodes()const {return _n_ports
*2;}
58 CARD
* clone()const {unreachable();return new DEV_CPOLY_CAP(*this);}
59 void tr_iwant_matrix() {tr_iwant_matrix_extended();}
60 bool tr_needs_eval()const {/*assert(!is_q_for_eval());*/ return true;}
63 TIME_PAIR
tr_review() {return _time_by
.reset();}//BUG//review(_i0.f0, _it1.f0);}
65 double tr_involts()const { return tr_outvolts(); } // temporary hack, better override keep_ic (?)
66 hp_float_t
tr_involts_limited()const {unreachable(); return NOT_VALID
;}
67 hp_float_t
tr_amps()const;
68 void ac_iwant_matrix() {ac_iwant_matrix_extended();}
70 COMPLEX
ac_involts()const {itested(); return NOT_VALID
;}
71 COMPLEX
ac_amps()const {itested(); return NOT_VALID
;}
73 std::string
port_name(uint_t
)const {untested();
79 void set_parameters(const std::string
& Label
, CARD
* Parent
,
80 COMMON_COMPONENT
* Common
, double Value
,
81 uint_t state_count
, hp_float_t state
[],
82 uint_t node_count
, const node_t nodes
[]);
83 // const double* inputs[]=0);
85 bool do_tr_con_chk_and_q();
87 /*--------------------------------------------------------------------------*/
88 class DEV_FPOLY_CAP
: public DEV_CPOLY_CAP
{
90 explicit DEV_FPOLY_CAP(const DEV_FPOLY_CAP
& p
)
93 explicit DEV_FPOLY_CAP() :DEV_CPOLY_CAP() {}
94 private: // override virtual
95 char id_letter()const {unreachable(); return '\0';}
96 std::string
dev_type()const{unreachable(); return "fpoly_cap";}
97 CARD
* clone()const {return new DEV_FPOLY_CAP(*this);}
100 /*--------------------------------------------------------------------------*/
101 /*--------------------------------------------------------------------------*/
102 DEV_CPOLY_CAP::DEV_CPOLY_CAP(const DEV_CPOLY_CAP
& p
)
108 _n_ports(p
._n_ports
),
109 _load_time(NOT_VALID
),
112 // not really a copy .. only valid to copy a default
113 // too lazy to do it right, and that's all that is being used
114 // to do it correctly requires a deep copy
115 // just filling in defaults is better than a shallow copy, hence this:
120 assert(p
._n_ports
== 0);
123 /*--------------------------------------------------------------------------*/
124 DEV_CPOLY_CAP::DEV_CPOLY_CAP()
131 _load_time(NOT_VALID
),
135 /*--------------------------------------------------------------------------*/
136 DEV_CPOLY_CAP::~DEV_CPOLY_CAP()
141 if (net_nodes() > NODES_PER_BRANCH
) {
144 // it is part of a base class
147 /*--------------------------------------------------------------------------*/
148 bool DEV_CPOLY_CAP::do_tr_con_chk_and_q()
153 set_converged(conchk(_load_time
, _sim
->_time0
));
154 _load_time
= _sim
->_time0
;
155 for (uint_t i
=0; converged() && i
<=_n_ports
; ++i
) {
156 set_converged(conchk(_vy1
[i
], _vy0
[i
]));
161 /*--------------------------------------------------------------------------*/
162 bool DEV_CPOLY_CAP::do_tr()
165 _m0
= CPOLY1(0., _vi0
[0], _vi0
[1]);
166 return do_tr_con_chk_and_q();
168 /*--------------------------------------------------------------------------*/
169 bool DEV_FPOLY_CAP::do_tr()
171 assert((_time
[0] == 0) || (_vy0
[0] == _vy0
[0]));
173 _y
[0].x
= tr_outvolts();
177 _i
[0] = differentiate(_y
, _i
, _time
, _method_a
);
180 assert(_vi0
[0] == _vi0
[0]);
182 if (_inputs
) {untested();
183 for (uint_t i
=1; i
<=_n_ports
; ++i
) {untested();
184 _vi0
[i
] = tr_c_to_g(_vy0
[i
], _vi0
[i
]);
185 _vi0
[0] -= *(_inputs
[i
]) * _vi0
[i
];
188 for (uint_t i
=1; i
<=_n_ports
; ++i
) {
189 _vi0
[i
] = tr_c_to_g(_vy0
[i
], _vi0
[i
]);
190 _vi0
[0] -= volts_limited(_n
[2*i
-2],_n
[2*i
-1]) * _vi0
[i
];
191 assert(_vi0
[i
] == _vi0
[i
]);
192 assert(_vi0
[0] == _vi0
[0]);
195 for (uint_t i
=0; i
<=_n_ports
; ++i
) {
196 assert(_vi0
[i
] == _vi0
[i
]);
199 _m0
= CPOLY1(0., _vi0
[0], _vi0
[1]);
200 return do_tr_con_chk_and_q();
202 /*--------------------------------------------------------------------------*/
203 void DEV_CPOLY_CAP::tr_load()
205 for (uint_t i
=0; i
<=_n_ports
; ++i
) {
206 assert(_vi0
[i
] == _vi0
[i
]);
211 for (uint_t i
=2; i
<=_n_ports
; ++i
) {
212 tr_load_extended(_n
[OUT1
], _n
[OUT2
], _n
[2*i
-2], _n
[2*i
-1], &(_vi0
[i
]), &(_vi1
[i
]));
215 /*--------------------------------------------------------------------------*/
216 void DEV_CPOLY_CAP::tr_unload()
218 std::fill_n(_vi0
, _n_ports
+1, 0.);
219 _m0
.c0
= _m0
.c1
= 0.;
220 _sim
->mark_inc_mode_bad();
223 /*--------------------------------------------------------------------------*/
224 hp_float_t
DEV_CPOLY_CAP::tr_amps()const
226 hp_float_t amps
= _m0
.c0
;
227 for (uint_t i
=1; i
<=_n_ports
; ++i
) {untested();
228 amps
+= dn_diff(_n
[2*i
-2].v0(),_n
[2*i
-1].v0()) * _vi0
[i
];
232 /*--------------------------------------------------------------------------*/
233 void DEV_CPOLY_CAP::ac_load()
235 _acg
= (double)_vy0
[1] * _sim
->_jomega
;
237 for (uint_t i
=2; i
<=_n_ports
; ++i
) {
238 ac_load_extended(_n
[OUT1
], _n
[OUT2
], _n
[2*i
-2], _n
[2*i
-1], (double)_vy0
[i
] * _sim
->_jomega
);
241 /*--------------------------------------------------------------------------*/
242 /* set: set parameters, used in model building
244 void DEV_CPOLY_CAP::set_parameters(const std::string
& Label
, CARD
*Owner
,
245 COMMON_COMPONENT
*Common
, double Value
,
246 uint_t n_states
, hp_float_t states
[],
247 uint_t n_nodes
, const node_t nodes
[])
248 // const double* inputs[])
250 bool first_time
= (net_nodes() == 0);
255 attach_common(Common
);
258 _n_ports
= n_nodes
/2; // sets num_nodes() = _n_ports*2
259 assert(_n_ports
+1 == n_states
);
264 _vy1
= new hp_float_t
[n_states
];
265 _vi0
= new hp_float_t
[n_states
];
266 _vi1
= new hp_float_t
[n_states
];
268 if (net_nodes() > NODES_PER_BRANCH
) {
269 // allocate a bigger node list
270 _n
= new node_t
[net_nodes()];
272 // use the default node list, already set
275 assert(_n_ports
== n_states
-1);
279 assert(net_nodes() == n_nodes
);
280 // assert could fail if changing the number of nodes after a run
286 std::fill_n(_vy0
, n_states
, 0.);
287 std::fill_n(_vy1
, n_states
, 0.);
288 std::fill_n(_vi0
, n_states
, 0.);
289 std::fill_n(_vi1
, n_states
, 0.);
290 notstd::copy_n(nodes
, net_nodes(), _n
);
291 assert(net_nodes() == _n_ports
* 2);
293 /*--------------------------------------------------------------------------*/
294 /*--------------------------------------------------------------------------*/
296 DISPATCHER
<CARD
>::INSTALL
297 d4(&device_dispatcher
, "fpoly_cap", &p4
);
299 /*--------------------------------------------------------------------------*/
300 /*--------------------------------------------------------------------------*/
301 // vim:ts=8:sw=2:noet: