Merge branch 'testing-uf' into master-uf
[gnucap-felix.git] / apps / d_poly_cap.cc
blobd78ea6a4e510bd6065ab75028421c60e448292d9
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)
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 * DEV_CPOLY_CAP
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
32 #include "e_storag.h"
33 /*--------------------------------------------------------------------------*/
34 namespace {
35 /*--------------------------------------------------------------------------*/
36 class DEV_CPOLY_CAP : public STORAGE {
37 protected:
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
42 uint_t _n_ports;
43 hp_float_t _load_time;
44 const hp_float_t** _inputs;
45 protected:
46 explicit DEV_CPOLY_CAP(const DEV_CPOLY_CAP& p);
47 public:
48 explicit DEV_CPOLY_CAP();
49 ~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;}
61 bool do_tr();
62 void tr_load();
63 TIME_PAIR tr_review() {return _time_by.reset();}//BUG//review(_i0.f0, _it1.f0);}
64 void tr_unload();
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();}
69 void ac_load();
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();
74 incomplete();
75 unreachable();
76 return "";
78 public:
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);
84 protected:
85 bool do_tr_con_chk_and_q();
87 /*--------------------------------------------------------------------------*/
88 class DEV_FPOLY_CAP : public DEV_CPOLY_CAP {
89 private:
90 explicit DEV_FPOLY_CAP(const DEV_FPOLY_CAP& p)
91 :DEV_CPOLY_CAP(p) {}
92 public:
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);}
98 bool do_tr();
100 /*--------------------------------------------------------------------------*/
101 /*--------------------------------------------------------------------------*/
102 DEV_CPOLY_CAP::DEV_CPOLY_CAP(const DEV_CPOLY_CAP& p)
103 :STORAGE(p),
104 _vy0(NULL),
105 _vy1(NULL),
106 _vi0(NULL),
107 _vi1(NULL),
108 _n_ports(p._n_ports),
109 _load_time(NOT_VALID),
110 _inputs(NULL)
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:
116 assert(!p._vy0);
117 assert(!p._vy1);
118 assert(!p._vi0);
119 assert(!p._vi1);
120 assert(p._n_ports == 0);
121 assert(!p._inputs);
123 /*--------------------------------------------------------------------------*/
124 DEV_CPOLY_CAP::DEV_CPOLY_CAP()
125 :STORAGE(),
126 _vy0(NULL),
127 _vy1(NULL),
128 _vi0(NULL),
129 _vi1(NULL),
130 _n_ports(0),
131 _load_time(NOT_VALID),
132 _inputs(NULL)
135 /*--------------------------------------------------------------------------*/
136 DEV_CPOLY_CAP::~DEV_CPOLY_CAP()
138 delete [] _vy1;
139 delete [] _vi0;
140 delete [] _vi1;
141 if (net_nodes() > NODES_PER_BRANCH) {
142 delete [] _n;
143 }else{
144 // it is part of a base class
147 /*--------------------------------------------------------------------------*/
148 bool DEV_CPOLY_CAP::do_tr_con_chk_and_q()
150 q_load();
152 assert(_vy1);
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]));
158 set_converged();
159 return converged();
161 /*--------------------------------------------------------------------------*/
162 bool DEV_CPOLY_CAP::do_tr()
163 {untested();
164 incomplete();
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();
174 _y[0].f0 = _vy0[0];
175 _y[0].f1 = _vy0[1];
177 _i[0] = differentiate(_y, _i, _time, _method_a);
178 _vi0[0] = _i[0].f0;
179 _vi0[1] = _i[0].f1;
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];
187 }else{
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]);
208 tr_load_passive();
209 _vi1[0] = _vi0[0];
210 _vi1[1] = _vi0[1];
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()
217 {untested();
218 std::fill_n(_vi0, _n_ports+1, 0.);
219 _m0.c0 = _m0.c1 = 0.;
220 _sim->mark_inc_mode_bad();
221 tr_load();
223 /*--------------------------------------------------------------------------*/
224 hp_float_t DEV_CPOLY_CAP::tr_amps()const
225 {untested();
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];
230 return amps;
232 /*--------------------------------------------------------------------------*/
233 void DEV_CPOLY_CAP::ac_load()
235 _acg = (double)_vy0[1] * _sim->_jomega;
236 ac_load_passive();
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);
252 set_label(Label);
253 set_owner(Owner);
254 set_value(Value);
255 attach_common(Common);
257 if (first_time) {
258 _n_ports = n_nodes/2; // sets num_nodes() = _n_ports*2
259 assert(_n_ports+1 == n_states);
261 assert(!_vy1);
262 assert(!_vi0);
263 assert(!_vi1);
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()];
271 }else{
272 // use the default node list, already set
274 }else{
275 assert(_n_ports == n_states-1);
276 assert(_vy1);
277 assert(_vi0);
278 assert(_vi1);
279 assert(net_nodes() == n_nodes);
280 // assert could fail if changing the number of nodes after a run
283 //_inputs = inputs;
284 _inputs = 0;
285 _vy0 = states;
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 /*--------------------------------------------------------------------------*/
295 DEV_FPOLY_CAP p4;
296 DISPATCHER<CARD>::INSTALL
297 d4(&device_dispatcher, "fpoly_cap", &p4);
299 /*--------------------------------------------------------------------------*/
300 /*--------------------------------------------------------------------------*/
301 // vim:ts=8:sw=2:noet: