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 * functions for resistor.
23 * y.x = amps, y.f0 = volts, ev = y.f1 = ohms
24 * m.x = volts, m.c0 = amps, acg = m.c1 = mhos.
28 /*--------------------------------------------------------------------------*/
30 /*--------------------------------------------------------------------------*/
31 class DEV_RESISTANCE
: public ELEMENT
{
33 explicit DEV_RESISTANCE(const DEV_RESISTANCE
& p
) :ELEMENT(p
) {}
35 explicit DEV_RESISTANCE() :ELEMENT() {}
36 private: // override virtual
37 char id_letter()const {return 'R';}
38 std::string
value_name()const {return "r";}
39 std::string
dev_type()const {return "resistor";}
40 uint_t
max_nodes()const {return 2;}
41 uint_t
min_nodes()const {return 2;}
42 uint_t
matrix_nodes()const {return 2;}
43 uint_t
net_nodes()const {return 2;}
44 bool has_iv_probe()const {return true;}
45 bool use_obsolete_callback_parse()const {return true;}
46 CARD
* clone()const {return new DEV_RESISTANCE(*this);}
48 void tr_iwant_matrix() {tr_iwant_matrix_passive();}
51 void tr_load() {tr_load_passive();}
52 void tr_unload() {tr_unload_passive();}
53 double tr_involts()const {return tr_outvolts();}
54 double tr_input()const {untested(); return _m0
.c0
+ _m0
.c1
* tr_involts();}
55 double tr_involts_limited()const {return tr_outvolts_limited();}
56 double tr_input_limited()const {return _m0
.c0
+_m0
.c1
*tr_involts_limited();}
58 void ac_iwant_matrix() {ac_iwant_matrix_passive();}
59 void ac_begin() {_ev
= _y
[0].f1
; _acg
= 1. / _ev
;}
61 void ac_load() {ac_load_passive();}
62 COMPLEX
ac_involts()const {return ac_outvolts();}
63 double do_noise()const;
64 XPROBE
sens_probe_ext(const std::string
& x
)const;
66 std::string
port_name(uint_t i
)const {
69 static std::string names
[] = {"p", "n"};
73 /*--------------------------------------------------------------------------*/
74 void DEV_RESISTANCE::precalc_last()
76 ELEMENT::precalc_last();
77 set_constant(!has_tr_eval() || (has_common() && common()->is_constant()));
78 set_converged(!has_tr_eval() || (has_common() && common()->is_constant()));
80 /*--------------------------------------------------------------------------*/
81 void DEV_RESISTANCE::tr_begin()
84 _y1
.f1
= _y
[0].f1
= (value() != 0.) ? value() : OPT::shortckt
;
91 if (is_constant() && using_tr_eval()) {
93 }else if (value() == 0. && !has_common()) {
94 error(bPICKY
, long_label() + ": short circuit\n");
97 _n
[0].register_prop(_n
[1]);
98 _n
[1]->register_prop(_n
[0].operator->());
100 /*--------------------------------------------------------------------------*/
101 bool DEV_RESISTANCE::do_tr()
103 trace1("DEV_RESISTANCE::do_tr", using_tr_eval());
104 if (using_tr_eval()) {
105 _m0
.x
= tr_involts_limited();
106 _y
[0].x
= tr_input_limited();;
108 assert(_y
[0].f0
!= LINEAR
);
109 if (_y
[0].f1
== 0.) { // leq short??
110 error(bPICKY
, long_label() + ": short circuit\n");
111 _y
[0].f1
= OPT::shortckt
;
112 set_converged(conv_check());
117 _m0
.c1
= 1./_y
[0].f1
;
118 _m0
.c0
= _y
[0].x
- _y
[0].f0
/ _y
[0].f1
;
120 assert(_y
[0].f0
== LINEAR
);
121 assert(_y
[0].f1
== value() || _y
[0].f1
== OPT::shortckt
);
122 assert(conchk(_m0
.c1
, 1./_y
[0].f1
));
123 assert(_m0
.c0
== 0.);
124 assert(_y1
== _y
[0]);
129 /*--------------------------------------------------------------------------*/
130 void DEV_RESISTANCE::tr_regress()
132 ELEMENT::tr_regress();
133 if (OPT::disc
==dREJECT
){
134 for (unsigned i
=0;i
< 2; ++i
) {
135 if (DISCONT d
=_n
[i
]->discont()) {
142 /*--------------------------------------------------------------------------*/
143 void DEV_RESISTANCE::do_ac()
145 if (using_ac_eval()) {
148 error(bPICKY
, long_label() + ": short circuit\n");
154 assert(_ev
== _y
[0].f1
);
155 assert(has_tr_eval() || _ev
== double(value()) || _ev
== OPT::shortckt
);
158 /*--------------------------------------------------------------------------*/
159 double DEV_RESISTANCE::do_noise()const
161 // Assumed that everything is evaluated as AC was called just before
164 // assert(_ev == double(value()));
165 assert(_ev
== _y
[0].f1
);
166 assert(_acg
== 1./_ev
);
168 double temp
= OPT::temp_c
+ P_CELSIUS0
; // 300.15;
169 double g
= real(_acg
);
170 double i_noise_r
= sqrt(4*P_K
*temp
*mfactor()*g
);
171 uint_t n1
= _n
[OUT1
].m_();
172 uint_t n2
= _n
[OUT2
].m_();
173 COMPLEX v
= _sim
->_sens
[n1
] - _sim
->_sens
[n2
];
174 double noisepow
= abs(v
*i_noise_r
);
175 noisepow
*= noisepow
;
179 trace4("DEV_RESISTANCE::do_noise", long_label(), opower
, i_noise_r
, g
);
182 /*--------------------------------------------------------------------------*/
183 XPROBE
DEV_RESISTANCE::sens_probe_ext(const std::string
& x
)const
185 trace1("DEV_RESISTANCE::sens_probe_ext", x
);
186 unsigned n1
= _n
[OUT1
].m_();
187 unsigned n2
= _n
[OUT2
].m_();
188 COMPLEX a
= CKT_BASE::_sim
->_sens
[n1
];
189 COMPLEX b
= CKT_BASE::_sim
->_sens
[n2
];
190 double vp
= CKT_BASE::_sim
->vdc()[n1
];
191 double vn
= CKT_BASE::_sim
->vdc()[n2
];
193 double G( real(_acg
) );
195 if (Umatch(x
, "r{es} ")) {
196 COMPLEX ddr
= (a
-b
) * G
*G
;
197 return XPROBE( ddr
*dv
);
198 } else if (Umatch(x
, "g ")) {
199 return XPROBE( -(a
-b
) * dv
);
202 if (Umatch(x
, "d1 ")) { // debug...
205 return ELEMENT::sens_probe_ext(x
);
207 /*--------------------------------------------------------------------------*/
208 /*--------------------------------------------------------------------------*/
210 DISPATCHER
<CARD
>::INSTALL
d1(&device_dispatcher
, "R|resistor", &p1
);
212 /*--------------------------------------------------------------------------*/
213 /*--------------------------------------------------------------------------*/
214 // vim:ts=8:sw=2:noet: