1 /*$Id: c_modify.cc,v 26.137 2010/04/10 02:37:05 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
22 //testing=script,sparse 2006.07.17
28 extern const int swp_type
[];
29 extern const int swp_count
[], swp_steps
[];
30 extern const int swp_nest
;
31 /*--------------------------------------------------------------------------*/
33 /*--------------------------------------------------------------------------*/
34 enum WHATTODO
{FAULT
, MODIFY
};
35 std::list
<CARDSTASH
> faultstack
;
36 /*--------------------------------------------------------------------------*/
37 /* faultbranch: "fault" a single branch. (temporarily change a value)
38 * save the existing info in "faultlist", then patch
40 void faultbranch(CARD
* brh
, double value
)
42 if (!brh
->is_device()) {
44 error(bWARNING
, brh
->long_label() + ": not a device, can't fault:\n");
45 }else if (brh
->subckt()) {
47 error(bWARNING
, brh
->long_label() + " has subckt, can't fault:\n");
49 faultstack
.push_back(CARDSTASH(brh
));
50 ELEMENT
* e
= prechecked_cast
<ELEMENT
*>(brh
);
52 e
->set_value(value
, 0);
53 //BUG// messy way to do this, loses other attributes
56 /*--------------------------------------------------------------------------*/
57 /* sweep_fix: fix the value for sweep command.
58 * (find value by interpolation)
59 * if not sweeping, return "start" (the first arg).
61 double sweep_fix(CS
& cmd
, const CARD
*brh
)
63 double start
= cmd
.ctof();
65 if (swp_steps
[swp_nest
] != 0 && cmd
.is_float()) {
67 double last
= cmd
.ctof();
68 double offset
= static_cast<double>(swp_count
[swp_nest
])
69 / static_cast<double>(swp_steps
[swp_nest
]);
70 if (swp_type
[swp_nest
]=='L') {
74 throw Exception("log sweep can't pass zero");
78 value
= start
* pow( (last
/start
), offset
);
82 value
= start
+ (last
-start
) * offset
;
84 IO::mstdout
.setfloatwidth(7)
85 << swp_count
[swp_nest
]+1 << "> sweep " << brh
->long_label()
86 << " =" << value
<< '\n';
90 /*--------------------------------------------------------------------------*/
91 void modify_fault(CS
& cmd
, WHATTODO command
, CARD_LIST
* scope
)
93 CKT_BASE::_sim
->uninit();
94 while (cmd
.is_alpha()) {
95 unsigned mark
= cmd
.cursor();
96 unsigned cmax
= cmd
.cursor();
97 CARD_LIST::fat_iterator
ci(scope
, scope
->begin());
100 ci
= findbranch(cmd
, ci
);
101 cmax
= std::max(cmax
, cmd
.cursor());
109 ELEMENT
* e
= prechecked_cast
<ELEMENT
*>(brh
);
111 e
->set_value(cmd
.ctof(), 0);
112 //BUG// messy way to do this, loses other attributes
115 faultbranch(brh
, sweep_fix(cmd
,brh
));
118 cmax
= std::max(cmax
, cmd
.cursor());
124 cmd
.check(bWARNING
, "what's this?");
129 /*--------------------------------------------------------------------------*/
130 class CMD_MODIFY
: public CMD
{
132 void do_it(CS
& cmd
, CARD_LIST
* Scope
)
134 modify_fault(cmd
, MODIFY
, Scope
);
137 DISPATCHER
<CMD
>::INSTALL
d1(&command_dispatcher
, "modify|alter", &p1
);
138 /*--------------------------------------------------------------------------*/
139 class CMD_FAULT
: public CMD
{
141 void do_it(CS
& cmd
, CARD_LIST
* Scope
)
143 modify_fault(cmd
, FAULT
, Scope
);
146 DISPATCHER
<CMD
>::INSTALL
d2(&command_dispatcher
, "fault", &p2
);
147 /*--------------------------------------------------------------------------*/
148 class CMD_RESTORE
: public CMD
{
150 void do_it(CS
&, CARD_LIST
* Scope
)
152 command("unfault", Scope
);
153 command("unmark", Scope
);
156 DISPATCHER
<CMD
>::INSTALL
d3(&command_dispatcher
, "restore", &p3
);
157 /*--------------------------------------------------------------------------*/
158 class CMD_UNFAULT
: public CMD
{
160 void do_it(CS
&, CARD_LIST
*)
162 while (!faultstack
.empty()) {
163 faultstack
.back().restore();
164 faultstack
.pop_back();
169 DISPATCHER
<CMD
>::INSTALL
d4(&command_dispatcher
, "unfault", &p4
);
170 /*--------------------------------------------------------------------------*/
172 /*--------------------------------------------------------------------------*/
173 /*--------------------------------------------------------------------------*/
174 // vim:ts=8:sw=2:noet: