element.h

00001 /***************************************************************************
00002  *   Copyright (C) 2003-2004 by David Saxton                               *
00003  *   david@bluehaze.org                                                    *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  ***************************************************************************/
00010 
00011 #ifndef ELEMENT_H
00012 #define ELEMENT_H
00013 
00014 #include "elementset.h"
00015 #include "matrix.h"
00016 
00017 using namespace std;
00018 class ElementSet;
00019 
00020 /* FIXME Too many responsibilities.
00021 
00022 Seems to cover many different things such as physics, wires, the base class for
00023 parts, simulation-related things... Either a necessary kludge or a prime target for refactoring. 
00024 
00025 */
00026 
00027 const double T = 300.; // Temperature in Kelvin
00028 const double K = 1.3806503e-23; // Boltzmann's constant
00029 const double q = 1.602176462e-19; // Charge on an electron
00030 const double V_T = K*T/q; // Thermal voltage
00031 const double gmin = 1e-12; // Minimum parallel conductance used in dc domain
00032 
00033 class CNode
00034 {
00035 public:
00036         CNode() : v(0.0), isGround(false), m_n(0) {}
00037         CNode(const uint32_t n) : v(0.0), isGround(false), m_n(n) {}
00038         void set_n( const uint32_t n ) { m_n=n; }
00039         uint32_t n() { return m_n; }
00040         double v; // Voltage on node. This is set from the last calculated voltage.
00041         bool isGround; // True for ground nodes. Obviously, you should ignore n and v if this is true
00042 private:
00043         uint32_t m_n; // CNode number
00044 };
00045 
00046 class CBranch
00047 {
00048 public:
00049         CBranch() : i(0.0), m_n(0) {}
00050         CBranch(const uint32_t n) : i(0.0), m_n(n) {}
00051         void set_n( const uint32_t n ) { m_n=n; }
00052         uint32_t n() { return m_n; }
00053         double i; // Current flowing through branch. This is set from the last calculated current.
00054 private:
00055         uint32_t m_n; // CBranch number
00056 };
00057 
00058 const int MAX_CNODES = 4;
00059 
00060 // Default node number that represents no node (remember that
00061 // Ground node is -1, and the rest are numbered from 0 to n-1
00062 const int noCNode = -2;
00063 // Likewise for branch (although there is no "ground" branch;
00064 // it is merely -2 for likeness with noCNode)
00065 const int noBranch = -2;
00066 
00071 class Element
00072 {
00073 public:
00074 
00075 // FIXME Base classes should be stupid. --
00076 // information hiding is good programming but bad government.
00077         enum Type
00078         {
00079                 Element_BJT,
00080                 Element_Capacitance,
00081                 Element_CCCS,
00082                 Element_CCVS,
00083                 Element_CurrentSignal,
00084                 Element_CurrentSource,
00085                 Element_Diode,
00086                 Element_Inductance,
00087                 Element_LogicIn,
00088                 Element_LogicOut,
00089                 Element_OpAmp,
00090                 Element_Resistance,
00091                 Element_VCCS,
00092                 Element_VCVS,
00093                 Element_VoltagePoint,
00094                 Element_VoltageSignal,
00095                 Element_VoltageSource
00096         };
00097         
00098         Element();
00099         virtual ~Element();
00104         virtual void setElementSet( ElementSet *c );
00108         ElementSet *elementSet() { return p_eSet; }
00113         void setCNodes( const int n0 = noCNode, const int n1 = noCNode, const int n2 = noCNode, const int n3 = noCNode );
00118         void setCBranches( const int b0 = noBranch, const int b1 = noBranch, const int b2 = noBranch, const int b3 = noBranch );
00122         CNode *cnode( const uint32_t num ) { return p_cnode[num]; }
00126         CBranch *cbranch( const uint32_t num ) { return p_cbranch[num]; }
00130         int numCBranches() { return m_numCBranches; }
00134         int numCNodes() { return m_numCNodes; }
00140         virtual void updateCurrents() = 0;
00145         virtual bool isReactive() { return false; }
00150         virtual bool isNonLinear() { return false; }
00154         virtual Type type() const = 0;
00158         virtual void add_map() {};
00162         virtual void add_initial_dc() = 0;
00167         void componentDeleted();
00168         void elementSetDeleted();
00169 
00170 // what is this actually used for? is it necessary?     
00171 
00172         double cbranchCurrent( const int branch );
00173         double cnodeVoltage( const int node );
00174 
00175         double nodeCurrent(unsigned int i) const { return m_cnodeI[i]; }
00176         double checkCurrents() const; // returns error current.
00177 
00178 protected:
00182         void resetCurrents();
00183         double m_cnodeI[8]; 
00184 
00185         inline double & A_g( uint32_t i, uint32_t j );
00186         inline double & A_b( uint32_t i, uint32_t j );
00187         inline double & A_c( uint32_t i, uint32_t j );
00188         inline double & A_d( uint32_t i, uint32_t j );
00189         
00190         inline double & b_i( uint32_t i );
00191         inline double & b_v( uint32_t i );
00192 
00193 
00194         
00195         ElementSet *p_eSet;
00196         Matrix *p_A;
00197         QuickVector *p_b;
00198 
00199 // maintained by elementset.
00200 /* TODO: design issue, I don't think these pointers should be leaked out of
00201   elementset. Elements should access their nodes by index. This would allow use of
00202 STL vector class in element set, though that may not yield much benefit.
00203 */
00204 
00205         CNode *p_cnode[MAX_CNODES];
00206         CBranch *p_cbranch[4];
00207         
00212         bool b_status;
00216         virtual bool updateStatus();
00222         unsigned int m_numCBranches;
00226         unsigned int m_numCNodes;
00227         
00228 private:
00229         bool b_componentDeleted;
00230         bool b_eSetDeleted; 
00231         double m_temp;
00232 };
00233 
00234 double & Element::A_g( uint32_t i, uint32_t j )
00235 {
00236         if ( p_cnode[i]->isGround || p_cnode[j]->isGround )
00237                 return m_temp;
00238         return p_A->g( p_cnode[i]->n(), p_cnode[j]->n() );
00239 }
00240 
00241 double & Element::A_b( uint32_t i, uint32_t j )
00242 {
00243         if ( p_cnode[i]->isGround )
00244                 return m_temp;
00245         return p_A->b( p_cnode[i]->n(), p_cbranch[j]->n() );
00246 }
00247 
00248 double & Element::A_c( uint32_t i, uint32_t j )
00249 {
00250         if ( p_cnode[j]->isGround ) return m_temp;
00251         return p_A->c( p_cbranch[i]->n(), p_cnode[j]->n() );
00252 }
00253 
00254 double & Element::A_d( uint32_t i, uint32_t j )
00255 {
00256         return p_A->d( p_cbranch[i]->n(), p_cbranch[j]->n() );
00257 }
00258 
00259 double & Element::b_i( uint32_t i )
00260 {
00261         if ( p_cnode[i]->isGround ) return m_temp;
00262         
00263         return (*p_b)[ p_cnode[i]->n() ];
00264 }
00265 
00266 double & Element::b_v( uint32_t i )  {
00267         return (*p_b)[ p_eSet->cnodeCount() + p_cbranch[i]->n() ];
00268 }
00269 
00270 #endif

Generated on Tue May 8 17:05:29 2007 for KTechLab by  doxygen 1.5.1