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 #include "element.h" 00012 #include "elementset.h" 00013 00014 #include <cassert> 00015 #include <cmath> 00016 #include <kdebug.h> 00017 00018 Element::Element() 00019 { 00020 b_status = false; 00021 p_A = 0; 00022 p_eSet = 0; 00023 p_b = 0; 00024 b_componentDeleted = false; 00025 b_eSetDeleted = true; 00026 00027 for( int i=0; i<8; i++ ) p_cnode[i] = 0; 00028 00029 resetCurrents(); 00030 00031 for( int i=0; i<4; i++ ) p_cbranch[i] = 0; 00032 00033 m_numCBranches = 0; 00034 m_numCNodes = 0; 00035 } 00036 00037 // may be used in subclasses, 00038 Element::~Element() {} 00039 00040 void Element::resetCurrents() 00041 { 00042 for( int i=0; i<8; i++ ) m_cnodeI[i] = 0.0; 00043 } 00044 00045 void Element::setElementSet( ElementSet *c ) 00046 { 00047 assert(!b_componentDeleted); 00048 assert(!p_eSet); 00049 00050 if(!c) return elementSetDeleted(); 00051 00052 b_eSetDeleted = false; 00053 p_eSet = c; 00054 p_A = p_eSet->matrix(); 00055 00056 if(p_b) delete p_b; 00057 p_b = p_eSet->b(); 00058 updateStatus(); 00059 } 00060 00061 void Element::componentDeleted() 00062 { 00063 // assert(!b_componentDeleted); 00064 if(b_componentDeleted) { 00065 // Something strange happened here.... 00066 // FIXME missing code. 00067 } 00068 00069 if(b_eSetDeleted) return delete this; 00070 00071 b_componentDeleted = true; 00072 b_status = false; 00073 // kdDebug() << "Element::componentDeleted(): Setting b_status to false, this="<<this<<endl; 00074 00075 // we only point to these, right?????? 00076 p_eSet = 0; 00077 p_A = 0; 00078 p_b = 0; 00079 // ??????????????????????????????????? 00080 00081 setCNodes(); 00082 setCBranches(); 00083 } 00084 00085 void Element::elementSetDeleted() 00086 { 00087 // assert(!b_eSetDeleted); 00088 if(b_eSetDeleted) 00089 { 00090 // Something strange happened here.... 00091 // FIXME missing code. 00092 } 00093 00094 if(b_componentDeleted) return delete this; 00095 00096 b_eSetDeleted = true; 00097 b_status = false; 00098 // kdDebug() << "Element::elementSetDeleted(): Setting b_status to false, this="<<this<<endl; 00099 00100 p_eSet = 0; 00101 p_A = 0; 00102 p_b = 0; 00103 setCNodes(); 00104 setCBranches(); 00105 } 00106 00107 void Element::setCNodes( const int n0, const int n1, const int n2, const int n3 ) 00108 { 00109 if( !p_eSet ) { 00110 // cerr << "Element::setCNodes: can't set nodes without circuit!"<<endl; 00111 for( int i=0; i<8; i++ ) p_cnode[i] = 0; 00112 return; 00113 } 00114 00115 // MAX_CNODES-1 should match the last array index below. 00116 assert( MAX_CNODES == 4 ); 00117 p_cnode[0] = (n0>-1) ? p_eSet->cnodes(n0) : (n0==-1?p_eSet->ground() : 0); 00118 p_cnode[1] = (n1>-1) ? p_eSet->cnodes(n1) : (n1==-1?p_eSet->ground() : 0); 00119 p_cnode[2] = (n2>-1) ? p_eSet->cnodes(n2) : (n2==-1?p_eSet->ground() : 0); 00120 p_cnode[3] = (n3>-1) ? p_eSet->cnodes(n3) : (n3==-1?p_eSet->ground() : 0); 00121 updateStatus(); 00122 } 00123 00124 void Element::setCBranches( const int b0, const int b1, const int b2, const int b3 ) 00125 { 00126 if( !p_eSet ) { 00127 // cerr << "Element::setCBranches: can't set branches without circuit!"<<endl; 00128 for( int i=0; i<4; i++ ) p_cbranch[i] = 0; 00129 return; 00130 } 00131 p_cbranch[0] = (b0>-1) ? p_eSet->cbranches(b0) : 0; 00132 p_cbranch[1] = (b1>-1) ? p_eSet->cbranches(b1) : 0; 00133 p_cbranch[2] = (b2>-1) ? p_eSet->cbranches(b2) : 0; 00134 p_cbranch[3] = (b3>-1) ? p_eSet->cbranches(b3) : 0; 00135 updateStatus(); 00136 } 00137 00138 bool Element::updateStatus() 00139 { 00140 // First, set status to false if all nodes in use are ground 00141 b_status = false; 00142 for(unsigned int i=0; i<m_numCNodes; i++ ) { 00143 b_status |= p_cnode[i]?!p_cnode[i]->isGround:false; 00144 } 00145 00146 // Set status to false if any of the nodes are not set 00147 for(unsigned int i=0; i<m_numCNodes; i++ ) { 00148 if(!p_cnode[i]) b_status = false; 00149 } 00150 00151 // Finally, set status to false if not all the required branches are set 00152 for(unsigned int i=0; i<m_numCBranches; i++ ) { 00153 if(!p_cbranch[i]) b_status = false; 00154 } 00155 00156 // Finally, check for various pointers 00157 if( !p_eSet || !p_A || !p_b ) b_status = false; 00158 00159 if(!b_status) resetCurrents(); 00160 00161 // And return the status :-) 00162 // kdDebug() << "Element::updateStatus(): Setting b_status to "<<(b_status?"true":"false")<<" this="<<this<<endl; 00163 return b_status; 00164 } 00165 00166 double Element::cbranchCurrent( const int branch ) 00167 { 00168 if( !b_status || branch<0 || branch>=m_numCBranches ) return 0.; 00169 return (*p_cbranch)[branch].i; 00170 } 00171 00172 double Element::cnodeVoltage( const int node ) 00173 { 00174 if( !b_status || node<0 || node>=m_numCNodes ) return 0.; 00175 return (*p_cnode)[node].v; 00176 } 00177 00178 double Element::checkCurrents() const { 00179 double sum = 0; 00180 for(unsigned int i = 0; i < m_numCNodes ; i++ ) { 00181 sum += m_cnodeI[i]; 00182 } 00183 00184 // return fabs(sum); 00185 return sum; 00186 } 00187 00188 00189 00190
1.5.1