testing
[gnucap-felix.git] / src / d_vcvs.cc
blob75757d9fd886845e2cddb4b3ebe660f21ed31300
1 /* Copyright (C) 2001 Albert Davis
2 * Author: Albert Davis <aldavis@gnu.org>
4 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3, or (at your option)
9 * any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301, USA.
20 *------------------------------------------------------------------
21 * functions for vcvs
22 * temporary kludge: it has resistance
24 #include "e_elemnt.h"
25 /*--------------------------------------------------------------------------*/
26 namespace {
27 /*--------------------------------------------------------------------------*/
28 class DEV_VCVS : public ELEMENT {
29 private:
30 explicit DEV_VCVS(const DEV_VCVS& p) :ELEMENT(p) { }
31 public:
32 explicit DEV_VCVS() :ELEMENT() {} //{ _net_nodes=4; }
33 private: // override virtual
34 char id_letter()const {return 'E';}
35 std::string value_name()const {return "gain";}
36 std::string element_type()const {return "vcvs";}
37 bool use_obsolete_callback_parse()const {return true;}
38 CARD* clone()const {return new DEV_VCVS(*this);}
39 void precalc_last();
40 void expand();
41 void tr_iwant_matrix() {tr_iwant_matrix_extended(); if(subdev())subdev()->tr_iwant_matrix();}
42 void tr_begin();
43 bool do_tr();
44 void tr_load();
45 void tr_unload() {untested();tr_unload_active();}
46 hp_float_t tr_involts()const {return dn_diff(_n[IN1].v0(), _n[IN2].v0());}
47 hp_float_t tr_involts_limited()const {return volts_limited(_n[IN1],_n[IN2]);}
48 void ac_iwant_matrix() {ac_iwant_matrix_extended(); if(subdev())subdev()->ac_iwant_matrix();}
49 void ac_begin();
50 void do_ac();
51 void ac_load() {ac_load_shunt(); ac_load_active();}
52 COMPLEX ac_involts()const {return _n[IN1].vac() - _n[IN2].vac();}
54 std::string port_name(uint_t i)const {
55 assert(i !=INVALID_NODE);
56 assert(i < 6);
57 static std::string names[] = {"p", "n", "ps", "ns", "ps2", "ns2"};
58 return names[i];
60 bool _master;
62 /*--------------------------------------------------------------------------*/
63 /*--------------------------------------------------------------------------*/
64 void DEV_VCVS::tr_load()
66 if(subdev()){
67 subdev()->tr_load();
69 tr_load_shunt();
70 tr_load_active();
72 /*--------------------------------------------------------------------------*/
73 #if 0
74 unsigned DEV_VCVS::min_nodes() const
76 if( const EVAL_BM_ACTION_BASE* e=dynamic_cast<const EVAL_BM_ACTION_BASE*>(common())){
77 trace1("DEV_VCVS::min_nodes", e->input_order());
78 return e->input_order() + 2;
79 } else {
80 trace0("DEV_VCVS::min_nodes 4");
82 return 4;
84 #endif
85 /*--------------------------------------------------------------------------*/
86 void DEV_VCVS::precalc_last()
88 ELEMENT::precalc_last();
89 set_constant(!has_tr_eval());
90 set_converged(!has_tr_eval());
92 /*--------------------------------------------------------------------------*/
93 void DEV_VCVS::expand()
95 trace3("DEV_VCVS::expand", long_label(), input_order(), hp(common()));
96 assert(!subckt() || subckt()->size() < 2);
97 ELEMENT::expand();
98 _master = 1;
99 if (has_common()) {
100 if( const EVAL_BM_ACTION_BASE* e=dynamic_cast<const EVAL_BM_ACTION_BASE*>(common())){
101 _master = input_order() == e->input_order();
105 /*--------------------------------------------------------------------------*/
106 void DEV_VCVS::tr_begin()
108 trace1("DEV_VCVS::tr_begin", long_label());
109 ELEMENT::tr_begin();
110 double bm_ord = 1;
111 if (has_common()) {
112 if (const EVAL_BM_ACTION_BASE* e=dynamic_cast<const EVAL_BM_ACTION_BASE*>(common())) {
113 bm_ord = e->input_order();
116 _loss1 = _loss0 = bm_ord / OPT::shortckt;
117 _m0.x = 0.;
118 _m0.c1 = -_loss0 * _y[0].f1 * bm_ord;
119 _m0.c0 = 0.;
120 _m1 = _m0;
121 if(subdev()){
122 subdev()->tr_begin();
125 /*--------------------------------------------------------------------------*/
126 bool DEV_VCVS::do_tr()
128 double bm_ord = 1;
129 if (has_common()) {
130 if (const EVAL_BM_ACTION_BASE* e=dynamic_cast<const EVAL_BM_ACTION_BASE*>(common())) {
131 bm_ord = e->input_order();
134 if (using_tr_eval()) {
135 _y[0].x = _m0.x = tr_involts_limited();
136 //_y[0].x = tr_input_limited();
137 //assert(_y[0].x == _m0.x);
138 tr_eval();
139 assert(_y[0].f0 != LINEAR);
140 store_values();
141 trace5("DEV_VCVS::do_tr", long_label(), _loss0, _y[0].x, _y[0].f0, _y[0].f1);
142 double oldf0=_y[0].f0;
143 if (_master) {
144 q_load();
145 } else {
146 _y[0].f0 = 0;
148 _m0 = CPOLY1(_y[0]);
149 _y[0].f0=oldf0;
150 _m0 *= -_loss0 * bm_ord;
151 }else{
152 assert(conchk(_loss0, 1./OPT::shortckt));
153 assert(_y[0].f0 == LINEAR);
154 assert(_y[0].f1 == value());
155 assert(conchk(_m0.c1, -_loss0 * _y[0].f1));
156 assert(_m0.c0 == 0.);
157 assert(_y1 == _y[0]);
158 assert(converged());
160 return converged();
162 /*--------------------------------------------------------------------------*/
163 void DEV_VCVS::ac_begin()
165 _loss1 = _loss0 = 1./OPT::shortckt;
166 _ev = _y[0].f1;
167 _acg = -_loss0 * _ev;
168 if(subdev()) subdev()->ac_begin();
170 /*--------------------------------------------------------------------------*/
171 void DEV_VCVS::do_ac()
173 if (using_ac_eval()) {
174 ac_eval();
175 trace2("DEV_VCVS::do_ac", _loss0, _ev);
176 _acg = -_loss0 * _ev;
177 }else{
178 assert(_ev == _y[0].f1);
179 assert(has_tr_eval() || _ev == hp_float_t(value()));
182 /*--------------------------------------------------------------------------*/
183 /*--------------------------------------------------------------------------*/
184 DEV_VCVS p1;
185 DISPATCHER<CARD>::INSTALL d1(&device_dispatcher, "E|vcvs", &p1);
187 /*--------------------------------------------------------------------------*/
188 /*--------------------------------------------------------------------------*/
189 // vim:ts=8:sw=2:noet: