00001
00002
00003
00004
00005
00006
00007
00008
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
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