viminfo
[gnucap-felix.git] / lib / u_sim_data.cc
blob1a604485e061652bac6fcbbb7c9943e2bb8938b7
1 /*$Id: u_sim_data.cc,v 26.137 2010/04/10 02:37:33 al 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)
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 * aux functions associated with the SIM class
24 //testing=obsolete
25 #include "m_wave.h"
26 #include "e_node.h"
27 #include "u_nodemap.h"
28 #include "e_cardlist.h"
29 #include "u_status.h"
30 /*--------------------------------------------------------------------------*/
31 SIM_DATA::SIM_DATA()
32 :_time0(0.),
33 _freq(0.),
34 _temp_c(0.),
35 _damp(0.),
36 _dtmin(0.),
37 _genout(0.),
38 _bypass_ok(true),
39 _fulldamp(false),
40 _last_time(0.),
41 _freezetime(false),
42 //_iter(),
43 _user_nodes(0),
44 _subckt_nodes(0),
45 _model_nodes(0),
46 _total_nodes(0),
47 _jomega(0.,0.),
48 _limiting(true),
49 _vmax(0.),
50 _vmin(0.),
51 _uic(false),
52 _inc_mode(tsNO),
53 //_mode(),
54 //_phase(),
55 _nm(NULL),
56 _i(NULL),
57 _v0(NULL),
58 _vt1(NULL),
59 _ac(NULL),
60 _nstat(NULL),
61 _vdc(NULL),
62 _aa(),
63 _lu(),
64 _acx(),
65 _eq(),
66 _loadq(),
67 _acceptq(),
68 _evalq1(),
69 _evalq2(),
70 _late_evalq(),
71 _evalq(NULL),
72 _evalq_uc(NULL),
73 _waves(NULL)
75 _evalq = &_evalq1;
76 _evalq_uc = &_evalq2;
78 /*--------------------------------------------------------------------------*/
79 SIM_DATA::~SIM_DATA()
81 if (_nm) {untested();
82 delete [] _nm;
83 _nm = NULL;
84 }else{
86 if (_i) {untested();
87 delete [] _i;
88 _i = NULL;
89 }else{
91 if (_v0) {untested();
92 delete [] _v0;
93 _v0 = NULL;
94 }else{
96 if (_vt1) {untested();
97 delete [] _vt1;
98 _vt1 = NULL;
99 }else{
101 if (_ac) {untested();
102 delete [] _ac;
103 _ac = NULL;
104 }else{
106 if (_nstat) {untested();
107 delete [] _nstat;
108 _nstat = NULL;
109 }else{
111 if (_vdc) {untested();
112 delete [] _vdc;
113 _vdc = NULL;
114 }else{
116 //assert(_eq.empty()); //BUG// should be empty here
117 assert(_loadq.empty());
118 assert(_acceptq.empty());
119 assert(_evalq1.empty());
120 assert(_evalq2.empty());
121 assert(_late_evalq.empty());
122 if (_evalq) {
123 _evalq = NULL;
124 }else{untested();
126 if (_evalq_uc) {
127 _evalq_uc = NULL;
128 }else{untested();
130 if (_waves) {
131 delete [] _waves;
132 _waves = NULL;
133 }else{
136 /*--------------------------------------------------------------------------*/
137 /*--------------------------------------------------------------------------*/
138 void SIM_DATA::set_limit()
140 for (int ii = 1; ii <= _total_nodes; ++ii) {
141 set_limit(_v0[ii]);
144 /*--------------------------------------------------------------------------*/
145 void SIM_DATA::set_limit(double v)
147 if (v+.4 > _vmax) {
148 _vmax = v+.5;
149 error(bTRACE, "new max = %g, new limit = %g\n", v, _vmax);
151 if (v-.4 < _vmin) {
152 _vmin = v-.5;
153 error(bTRACE, "new min = %g, new limit = %g\n", v, _vmin);
156 /*--------------------------------------------------------------------------*/
157 void SIM_DATA::clear_limit()
159 _vmax = OPT::vmax;
160 _vmin = OPT::vmin;
162 /*--------------------------------------------------------------------------*/
163 void SIM_DATA::keep_voltages()
165 if (!_freezetime) {
166 for (int ii = 1; ii <= _total_nodes; ++ii) {
167 _vdc[ii] = _v0[ii];
169 _last_time = (_time0 > 0.) ? _time0 : 0.;
170 }else{untested();
173 /*--------------------------------------------------------------------------*/
174 void SIM_DATA::restore_voltages()
176 for (int ii = 1; ii <= _total_nodes; ++ii) {
177 _vt1[ii] = _v0[ii] = _vdc[ii];
180 /*--------------------------------------------------------------------------*/
181 void SIM_DATA::zero_voltages()
183 for (int ii = 1; ii <= _total_nodes; ++ii) {
184 _vt1[ii] = _v0[ii] = _vdc[ii] = _i[ii] = 0.;
187 /*--------------------------------------------------------------------------*/
188 /*--------------------------------------------------------------------------*/
189 /* map__nodes: map intermediate node number to internal node number.
190 * Ideally, this function would find some near-optimal order
191 * and squash out gaps.
193 void SIM_DATA::map__nodes()
195 _nm = new int[_total_nodes+1];
196 ::status.order.reset().start();
197 switch (OPT::order) {
198 default: untested();
199 error(bWARNING, "invalid order spec: %d\n", OPT::order);
200 case oAUTO: order_auto(); break;
201 case oREVERSE: untested(); order_reverse(); break;
202 case oFORWARD: untested(); order_forward(); break;
204 ::status.order.stop();
206 /*--------------------------------------------------------------------------*/
207 /* order_reverse: force ordering to reverse of user ordering
208 * subcircuits at beginning, results on border at the bottom
210 void SIM_DATA::order_reverse()
211 {untested();
212 _nm[0] = 0;
213 for (int node = 1; node <= _total_nodes; ++node) {untested();
214 _nm[node] = _total_nodes - node + 1;
217 /*--------------------------------------------------------------------------*/
218 /* order_forward: use user ordering, with subcircuits added to end
219 * results in border at the top (worst possible if lots of subcircuits)
221 void SIM_DATA::order_forward()
222 {untested();
223 _nm[0] = 0;
224 for (int node = 1; node <= _total_nodes; ++node) {untested();
225 _nm[node] = node;
228 /*--------------------------------------------------------------------------*/
229 /* order_auto: full automatic ordering
230 * reverse, for now
232 void SIM_DATA::order_auto()
234 _nm[0] = 0;
235 for (int node = 1; node <= _total_nodes; ++node) {
236 _nm[node] = _total_nodes - node + 1;
239 /*--------------------------------------------------------------------------*/
240 /*--------------------------------------------------------------------------*/
241 /* init: allocate, set up, etc ... for any type of simulation
242 * also called by status and probe for access to internals and subckts
244 void SIM_DATA::init()
246 if (is_first_expand()) {
247 uninit();
248 init_node_count(CARD_LIST::card_list.nodes()->how_many(), 0, 0);
249 CARD_LIST::card_list.expand();
250 CARD_LIST::card_list.precalc_last();
251 map__nodes();
252 CARD_LIST::card_list.map_nodes();
253 alloc_hold_vectors();
254 _aa.reinit(_total_nodes);
255 _lu.reinit(_total_nodes);
256 _acx.reinit(_total_nodes);
257 CARD_LIST::card_list.tr_iwant_matrix();
258 CARD_LIST::card_list.ac_iwant_matrix();
259 _last_time = 0;
260 }else{
261 CARD_LIST::card_list.precalc_first();
262 CARD_LIST::card_list.precalc_last();
265 /*--------------------------------------------------------------------------*/
266 /* alloc_hold_vectors:
267 * allocate space to hold data between commands.
268 * for restart, convergence assistance, bias for AC, post-processing, etc.
269 * must be done BEFORE deciding what array elements to allocate,
270 * but after mapping
271 * if they already exist, leave them alone to save data
273 void SIM_DATA::alloc_hold_vectors()
275 assert(is_first_expand());
277 assert(!_nstat);
278 _nstat = new LOGIC_NODE[_total_nodes+1];
279 for (int ii=0; ii <= _total_nodes; ++ii) {
280 _nstat[_nm[ii]].set_user_number(ii);
283 assert(!_vdc);
284 _vdc = new double[_total_nodes+1];
285 std::fill_n(_vdc, _total_nodes+1, 0);
287 assert(_nstat);
288 assert(_vdc);
290 /*--------------------------------------------------------------------------*/
291 /* alloc_vectors:
292 * these are new with every run and are discarded after the run.
294 void SIM_DATA::alloc_vectors()
296 assert(_evalq1.empty());
297 assert(_evalq2.empty());
298 assert(_evalq != _evalq_uc);
300 assert(!_ac);
301 assert(!_i);
302 assert(!_v0);
303 assert(!_vt1);
305 _ac = new COMPLEX[_total_nodes+1];
306 _i = new double[_total_nodes+1];
307 _v0 = new double[_total_nodes+1];
308 _vt1 = new double[_total_nodes+1];
309 std::fill_n(_ac, _total_nodes+1, 0);
310 std::fill_n(_i, _total_nodes+1, 0);
311 std::fill_n(_v0, _total_nodes+1, 0);
312 std::fill_n(_vt1,_total_nodes+1, 0);
314 /*--------------------------------------------------------------------------*/
315 void SIM_DATA::unalloc_vectors()
317 _evalq1.clear();
318 _evalq2.clear();
319 delete [] _i;
320 _i = NULL;
321 delete [] _v0;
322 _v0 = NULL;
323 delete [] _vt1;
324 _vt1 = NULL;
325 delete [] _ac;
326 _ac = NULL;
328 /*--------------------------------------------------------------------------*/
329 /* uninit: undo all the allocation associated with any simulation
330 * called when the circuit changes after a run, so it needs a restart
331 * may be called multiple times without damage to make sure it is clean
333 void SIM_DATA::uninit()
335 if (_vdc) {
336 _acx.reinit(0);
337 _lu.reinit(0);
338 _aa.reinit(0);
339 delete [] _vdc;
340 _vdc = NULL;
341 delete [] _nstat;
342 _nstat = NULL;
343 delete [] _nm;
344 _nm = NULL;
345 }else{
346 assert(_acx.size() == 0);
347 assert(_lu.size() == 0);
348 assert(_aa.size() == 0);
349 assert(!_nstat);
350 assert(!_nm);
353 /*--------------------------------------------------------------------------*/
354 /*--------------------------------------------------------------------------*/
355 // vim:ts=8:sw=2:noet: