Branch data Line data Source code
1 : : /*
2 : : * tswitch.cpp - time controlled switch class implementation
3 : : *
4 : : * Copyright (C) 2006, 2008 Stefan Jahn <stefan@lkcc.org>
5 : : *
6 : : * This 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 2, or (at your option)
9 : : * any later version.
10 : : *
11 : : * This software 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.
15 : : *
16 : : * You should have received a copy of the GNU General Public License
17 : : * along with this package; see the file COPYING. If not, write to
18 : : * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19 : : * Boston, MA 02110-1301, USA.
20 : : *
21 : : * $Id$
22 : : *
23 : : */
24 : :
25 : : #if HAVE_CONFIG_H
26 : : # include <config.h>
27 : : #endif
28 : :
29 : : #include <iostream>
30 : : #include <cmath>
31 : : #include "component.h"
32 : : #include "tswitch.h"
33 : :
34 : : using namespace qucs;
35 : :
36 : 2 : tswitch::tswitch () : circuit (2) {
37 : 2 : type = CIR_TSWITCH;
38 [ + - # # ]: 2 : setVoltageSources (1);
39 : 2 : }
40 : :
41 : 4 : nr_double_t tswitch::initState (void) {
42 : 4 : const char * const init = getPropertyString ("init");
43 : 4 : bool on = !strcmp (init, "on");
44 [ + + ]: 4 : return on ? getPropertyDouble ("Ron") : getPropertyDouble ("Roff");
45 : : }
46 : :
47 : 0 : void tswitch::initSP (void) {
48 : 0 : nr_double_t r = initState ();
49 : 0 : allocMatrixS ();
50 [ # # ]: 0 : setS (NODE_1, NODE_1, r / (r + 2));
51 [ # # ]: 0 : setS (NODE_2, NODE_2, r / (r + 2));
52 [ # # ]: 0 : setS (NODE_1, NODE_2, 2 / (r + 2));
53 [ # # ]: 0 : setS (NODE_2, NODE_1, 2 / (r + 2));
54 : 0 : }
55 : :
56 : 0 : void tswitch::calcNoiseSP (nr_double_t) {
57 : 0 : nr_double_t T = getPropertyDouble ("Temp");
58 : 0 : nr_double_t r = initState ();
59 : 0 : nr_double_t f = kelvin (T) * 4.0 * r * z0 / sqr (2.0 * z0 + r) / T0;
60 [ # # ][ # # ]: 0 : setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
61 [ # # ][ # # ]: 0 : setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
62 : 0 : }
63 : :
64 : 0 : void tswitch::calcNoiseAC (nr_double_t) {
65 : 0 : nr_double_t r = initState ();
66 [ # # ][ # # ]: 0 : if (r > 0.0 || r < 0.0) {
67 : 0 : nr_double_t T = getPropertyDouble ("Temp");
68 : 0 : nr_double_t f = kelvin (T) / T0 * 4.0 / r;
69 [ # # ][ # # ]: 0 : setN (NODE_1, NODE_1, +f); setN (NODE_2, NODE_2, +f);
70 [ # # ][ # # ]: 0 : setN (NODE_1, NODE_2, -f); setN (NODE_2, NODE_1, -f);
71 : : }
72 : 0 : }
73 : :
74 : 4 : void tswitch::initDC (void) {
75 : 4 : nr_double_t r = initState ();
76 : 4 : allocMatrixMNA ();
77 : 4 : voltageSource (VSRC_1, NODE_1, NODE_2);
78 [ + - ]: 4 : setD (VSRC_1, VSRC_1, -r);
79 : 4 : }
80 : :
81 : 0 : void tswitch::initAC (void) {
82 : 0 : initDC ();
83 : 0 : }
84 : :
85 : 2 : void tswitch::initTR (void) {
86 [ + - ]: 2 : qucs::vector * values = getPropertyVector ("time");
87 : : // Find the total time of the switching periods
88 [ + - ][ + - ]: 2 : T = real (sum (*values));
[ + - ]
89 : : // if the user enters an even number of switchng times
90 : : // the pattern is repeated continuously
91 [ + - ]: 2 : repeat = (values->getSize () % 2) == 0 ? true : false;
92 : : // make the time taken to go from fully on to fully off
93 : : // the smallest switching time / 100, or the smallest possible
94 : : // number, but no bogger than the max specified duration
95 [ + - ]: 2 : nr_double_t maxduration = getPropertyDouble("MaxDuration");
96 [ + - ]: 2 : duration = std::min ( std::max (10*NR_TINY, values->minimum() / 100),
97 : 2 : maxduration );
98 : :
99 [ + - ]: 2 : initDC ();
100 : 2 : }
101 : :
102 : 7268 : void tswitch::calcTR (nr_double_t t) {
103 : 7268 : const char * const init = getPropertyString ("init");
104 : 7268 : nr_double_t ron = getPropertyDouble ("Ron");
105 : 7268 : nr_double_t roff = getPropertyDouble ("Roff");
106 : 7268 : nr_double_t r = 0;
107 : 7268 : nr_double_t rdiff = 0;
108 : 7268 : nr_double_t s_i = 0;
109 : 7268 : nr_double_t r_0 = 0;
110 : 7268 : qucs::vector * values = getPropertyVector ("time");
111 : 7268 : bool on = !strcmp (init, "on");
112 : 7268 : nr_double_t ti = 0;
113 : :
114 [ - + ]: 7268 : if (repeat) {
115 : : // if the user enters an even number of switchng times
116 : : // the pattern is repeated continuously. This is acieved by
117 : : // subtracting an integer number of total switching periods
118 : : // from the real time
119 : 0 : t = t - T * qucs::floor (t / T);
120 : : }
121 : :
122 : : // Initialise the last switching time to be a full
123 : : // switching duration
124 : 7268 : nr_double_t ts = t - duration;
125 : :
126 : : // here we determine whether a switching event should occur
127 : : // by looping through the list of switching times and comparing
128 : : // to the current time
129 [ + + ]: 13898 : for (int i = 0; i < values->getSize (); i++) {
130 : : // add the current value from the list of switching times
131 : : // to a counter
132 : 7268 : ti += real (values->get (i));
133 : :
134 [ + + ]: 7268 : if (t >= ti)
135 : : {
136 : : // the current time is greater than or equal to the current
137 : : // sum of switching times so the switch state changes
138 : 6630 : on = !on;
139 : : // store the current switching time
140 : 6630 : ts = ti;
141 : : }
142 : : else {
143 : : // the current sum of switching times is in the future
144 : : // so exit the loop
145 : 638 : break;
146 : : }
147 : : }
148 : : // calculate the time since the last switch occured
149 : 7268 : nr_double_t tdiff = std::max(NR_TINY, t - ts);
150 : :
151 : : // set the time difference to be no more than the max switch
152 : : // duration so when we interpolate below we only get the max
153 : : // or min function value if we are past a switching time
154 [ + + ]: 7268 : if (tdiff > duration) {
155 : 6454 : tdiff = duration;
156 : : }
157 : :
158 : : // Set the appropriate resistance. The resistance is interpolated
159 : : // along a cubic spline with zero derivative at the start and end
160 : : // points to ensure a smooth derivative
161 [ + + ]: 7268 : if (on)
162 : : {
163 : 3628 : r_0 = roff;
164 : :
165 : 3628 : rdiff = ron - roff;
166 : :
167 : 3628 : s_i = (rdiff) / (duration);
168 : : }
169 : : else
170 : : {
171 : 3640 : r_0 = ron;
172 : :
173 : 3640 : rdiff = roff - ron;
174 : :
175 : 3640 : s_i = (rdiff) / (duration);
176 : : }
177 : :
178 : : // perform the interpolation of the constrained cubic spline
179 : 7268 : r = r_0 + ((3. * s_i * qucs::pow (tdiff,2.0)) / (duration))
180 : 7268 : + ((-2. * s_i * qucs::pow (tdiff,3.0)) / qucs::pow (duration, 2.0));
181 : :
182 [ + - ]: 7268 : setD (VSRC_1, VSRC_1, -r);
183 : 7268 : }
184 : :
185 : : // properties
186 : : PROP_REQ [] = {
187 : : { "init", PROP_STR, { PROP_NO_VAL, "off" }, PROP_RNG_STR2 ("on", "off") },
188 : : { "time", PROP_LIST, { 1e-9, PROP_NO_STR }, PROP_POS_RANGE },
189 : : PROP_NO_PROP };
190 : : PROP_OPT [] = {
191 : : { "Ron", PROP_REAL, { 0, PROP_NO_STR }, PROP_POS_RANGE },
192 : : { "Roff", PROP_REAL, { 1e12, PROP_NO_STR }, PROP_POS_RANGE },
193 : : { "Temp", PROP_REAL, { 26.85, PROP_NO_STR }, PROP_MIN_VAL (K) },
194 : : { "MaxDuration", PROP_REAL, { 1e-6, PROP_NO_STR }, PROP_MIN_VAL (10*NR_TINY) },
195 : : PROP_NO_PROP };
196 : : struct define_t tswitch::cirdef =
197 [ + - ][ + - ]: 321 : { "Switch", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };
|