Qucs-core
0.0.19
|
00001 /* 00002 * ecvs.cpp - ecvs class implementation 00003 * 00004 * Copyright (C) 2003, 2004, 2006, 2008 Stefan Jahn <stefan@lkcc.org> 00005 * 00006 * This is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2, or (at your option) 00009 * any later version. 00010 * 00011 * This software is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this package; see the file COPYING. If not, write to 00018 * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor, 00019 * Boston, MA 02110-1301, USA. 00020 * 00021 * $Id$ 00022 * 00023 */ 00024 00034 #if HAVE_CONFIG_H 00035 # include <config.h> 00036 #endif 00037 00038 #include "component.h" 00039 #include "ecvs.h" 00040 00041 using namespace qucs; 00042 00043 ecvs::ecvs () : circuit (2) { 00044 type = CIR_ECVS; 00045 setVSource (true); 00046 setVoltageSources (1); 00047 } 00048 00049 void ecvs::initSP (void) { 00050 allocMatrixS (); 00051 setS (NODE_1, NODE_1, 0.0); 00052 setS (NODE_1, NODE_2, 1.0); 00053 setS (NODE_2, NODE_1, 1.0); 00054 setS (NODE_2, NODE_2, 0.0); 00055 } 00056 00057 void ecvs::initDC (void) { 00058 allocMatrixMNA (); 00059 voltageSource (VSRC_1, NODE_1, NODE_2); 00060 setE (VSRC_1, 0); 00061 } 00062 00063 void ecvs::initAC (void) { 00064 initDC (); 00065 setE (VSRC_1, 0); 00066 } 00067 00068 void ecvs::initTR (void) { 00069 initDC (); 00070 // we need to store a history of time values 00071 // for interpolation, initialise the history here 00072 deleteHistory (); 00073 setHistory (true); 00074 initHistory (0); 00075 } 00076 00077 void ecvs::calcTR (nr_double_t t) { 00078 nr_double_t V = 0; 00079 nr_double_t y0 = 0; 00080 nr_double_t Tlast; 00081 int hsize = getHistorySize (); 00082 // choose the voltage at the current time by interpolating 00083 // at the current time, using the previous values of the 00084 // voltage and the value of the voltage at the specified 00085 // next time in Tnext 00086 nr_double_t y1 = getPropertyDouble ("U"); 00087 if (hsize < 1) 00088 { 00089 Tlast = t; 00090 y0 = y1; 00091 } 00092 else 00093 { 00094 Tlast = getHistoryTFromIndex (hsize-1); 00095 y0 = (getV (NODE_1, hsize-1) - getV (NODE_2, hsize-1)); 00096 } 00097 nr_double_t Tnext = getPropertyDouble ("Tnext"); 00098 // do the interpolation 00099 nr_double_t tdiff = t - Tlast; 00100 if (tdiff <= 0) 00101 { 00102 V = y0; 00103 } 00104 else 00105 { 00106 V = y0 + (y1 - y0) * (tdiff / (Tnext - Tlast)); 00107 } 00108 #ifdef DEBUG 00109 printf ("ECVS -- t: %e, V: %e\n", t, V); 00110 #endif 00111 // set the voltage source value 00112 setE (VSRC_1, V); 00113 } 00114 00115 // properties 00116 PROP_REQ [] = { 00117 { "U", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE }, PROP_NO_PROP }; 00118 PROP_OPT [] = { 00119 { "Interpolator", PROP_STR, { PROP_NO_VAL, "linear" }, 00120 PROP_RNG_STR3 ("hold", "linear", "cubic") }, 00121 { "Tnext", PROP_REAL, { 0, PROP_NO_STR }, PROP_NO_RANGE }, 00122 PROP_NO_PROP }; 00123 struct define_t ecvs::cirdef = 00124 { "ECVS", 2, PROP_COMPONENT, PROP_NO_SUBSTRATE, PROP_LINEAR, PROP_DEF };