wire.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2005 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 "pin.h"
00012 #include "wire.h"
00013 #include <cassert>
00014 #include <kdebug.h>
00015 #include <cmath>
00016 
00017 using namespace std;
00018 
00019 Wire::Wire( Pin *startPin, Pin *endPin )
00020 {
00021         assert(startPin);
00022         assert(endPin);
00023 
00024         m_pStartPin = startPin;
00025         m_pEndPin = endPin;
00026         m_current = 0.;
00027         m_bCurrentIsKnown = false;
00028 
00029         m_pStartPin->addOutputWire(this);
00030         m_pEndPin->addInputWire(this);
00031 }
00032 
00033 Wire::~Wire()
00034 {
00035 }
00036 
00037 bool Wire::calculateCurrent()
00038 {
00039         if ( m_pStartPin->currentIsKnown() && m_pStartPin->numWires() < 2 ) {
00040                 m_current = m_pStartPin->current();
00041                 m_bCurrentIsKnown = true;
00042                 return true;
00043         }
00044 
00045         if ( m_pEndPin->currentIsKnown() && m_pEndPin->numWires() < 2 ) {
00046                 m_current = -m_pEndPin->current();
00047                 m_bCurrentIsKnown = true;
00048                 return true;
00049         }
00050 
00051         if ( m_pStartPin->currentIsKnown() ) {
00052                 double i = m_pStartPin->current();
00053                 bool ok = true;
00054                 const WireList outlist = m_pStartPin->outputWireList();
00055                 WireList::const_iterator end = outlist.end();
00056                 for(WireList::const_iterator it = outlist.begin(); it != end && ok; ++it)
00057                 {
00058                         if ( *it && (Wire*)*it != this ) {
00059                                 if ( (*it)->currentIsKnown() )
00060                                         i -= (*it)->current();
00061                                 else ok = false;
00062                         }
00063                 }
00064 
00065                 const WireList inlist = m_pStartPin->inputWireList();
00066                 end = inlist.end();
00067                 for(WireList::const_iterator it = inlist.begin(); it != end && ok; ++it) {
00068                         if ( *it && (Wire*)*it != this ) {
00069                                 if ( (*it)->currentIsKnown() )
00070                                         i += (*it)->current();
00071                                 else ok = false;
00072                         }
00073                 }
00074                 
00075                 if(ok) {
00076                         m_current = i;
00077                         m_bCurrentIsKnown = true;
00078                         return true;
00079                 }
00080         }
00081 
00082         if ( m_pEndPin->currentIsKnown() ) {
00083                 double i = -m_pEndPin->current();
00084                 bool ok = true;
00085                 const WireList outlist = m_pEndPin->outputWireList();
00086                 WireList::const_iterator end = outlist.end();
00087                 for ( WireList::const_iterator it = outlist.begin(); it != end && ok; ++it ) {
00088                         if ( *it && (Wire*)*it != this ) {
00089                                 if ( (*it)->currentIsKnown() )
00090                                         i += (*it)->current();
00091                                 else ok = false;
00092                         }       
00093                 }
00094 
00095                 const WireList inlist = m_pEndPin->inputWireList();
00096                 end = inlist.end();
00097 
00098                 for ( WireList::const_iterator it = inlist.begin(); it != end && ok; ++it ) {
00099                         if ( *it && (Wire*)*it != this ) {
00100                                 if ( (*it)->currentIsKnown() )
00101                                         i -= (*it)->current();
00102                                 else ok = false;
00103                         }
00104                 }
00105 
00106                 if (ok) {
00107                         m_current = i;
00108                         m_bCurrentIsKnown = true;
00109                         return true;
00110                 }
00111         }
00112 
00113         m_bCurrentIsKnown = false;
00114         return false;
00115 }
00116 
00117 double Wire::voltage() const
00118 {
00119         // wires conduct, right?
00120         double error = fabs(m_pStartPin->voltage() - m_pEndPin->voltage());
00121         if(error > 1e-9) kdError() << "Wire not conducting right, voltage off by " << error << endl;
00122         return m_pStartPin->voltage();
00123 }
00124 
00125 void Wire::setCurrentKnown( bool known )
00126 {
00127         m_bCurrentIsKnown = known;
00128         if (!known) m_current = 0.;
00129 }
00130 

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