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)
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 * aux functions associated with the SIM class
27 #include "u_nodemap.h"
28 #include "e_cardlist.h"
30 /*--------------------------------------------------------------------------*/
78 /*--------------------------------------------------------------------------*/
96 if (_vt1
) {untested();
101 if (_ac
) {untested();
106 if (_nstat
) {untested();
111 if (_vdc
) {untested();
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());
136 /*--------------------------------------------------------------------------*/
137 /*--------------------------------------------------------------------------*/
138 void SIM_DATA::set_limit()
140 for (int ii
= 1; ii
<= _total_nodes
; ++ii
) {
144 /*--------------------------------------------------------------------------*/
145 void SIM_DATA::set_limit(double v
)
149 error(bTRACE
, "new max = %g, new limit = %g\n", v
, _vmax
);
153 error(bTRACE
, "new min = %g, new limit = %g\n", v
, _vmin
);
156 /*--------------------------------------------------------------------------*/
157 void SIM_DATA::clear_limit()
162 /*--------------------------------------------------------------------------*/
163 void SIM_DATA::keep_voltages()
166 for (int ii
= 1; ii
<= _total_nodes
; ++ii
) {
169 _last_time
= (_time0
> 0.) ? _time0
: 0.;
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
) {
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()
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()
224 for (int node
= 1; node
<= _total_nodes
; ++node
) {untested();
228 /*--------------------------------------------------------------------------*/
229 /* order_auto: full automatic ordering
232 void SIM_DATA::order_auto()
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()) {
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();
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();
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,
271 * if they already exist, leave them alone to save data
273 void SIM_DATA::alloc_hold_vectors()
275 assert(is_first_expand());
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
);
284 _vdc
= new double[_total_nodes
+1];
285 std::fill_n(_vdc
, _total_nodes
+1, 0);
290 /*--------------------------------------------------------------------------*/
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
);
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()
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()
346 assert(_acx
.size() == 0);
347 assert(_lu
.size() == 0);
348 assert(_aa
.size() == 0);
353 /*--------------------------------------------------------------------------*/
354 /*--------------------------------------------------------------------------*/
355 // vim:ts=8:sw=2:noet: