/******************************************************* * * DESCRIPTION: QBG inductor class * * AUTHOR: Mariana C. D'Abreu * * EMAIL: mdabreu@dc.uba.ar * ********************************************************/ #include "qbg_inductor_ei.h" #include "ini.h" #include "mainsimu.h" #include "defaults.h" #include "functions.h" #include "realprec.h" const RealValue QBGInductorEffortIn::DefaultInductance = 1; const RealValue QBGInductorEffortIn::DefaultInitialLoad = 0; /******************************************************************* * Function Name: QBGInductorEffortIn * Description: constructor ********************************************************************/ QBGInductorEffortIn::QBGInductorEffortIn( const string &name ) : Atomic( name ) , e1p( addInputPort( "e1p" ) ) , f1p( addOutputPort( "f1p" ) ) { try { try { // inductance string inductance( MainSimulator::Instance().getParameter( description(), "I" ) ); I = atof( inductance.data() ); } catch ( MException &exc ) { I = DefaultInductance; } if ( I <= 0 ) { throw MException( "Invalid Inductance value : " + Value2StrReal( I ) ); } try { // initial load string load( MainSimulator::Instance().getParameter( description(), "initialLoad" ) ); initialLoad = atof( load.data() ); } catch ( MException &exc ) { initialLoad = DefaultInitialLoad; } if ( initialLoad < 0 ) { throw MException( "Invalid initial load: " + Value2StrReal( initialLoad ) ); } // Quantum try { string quant( MainSimulator::Instance().getParameter( description(), "quantum" ) ); quantum = atof( quant.data() ); } catch ( MException &e ) { quantum = DEFAULT_QUANTUM; } if( quantum <= 0 ) { throw MException( "Invalid quantum value : " + Value2StrReal( quantum ) ); } // Hysteresis window try { string hystW( MainSimulator::Instance().getParameter( description(), "hystWindow" ) ); hystWindow = atof( hystW.data() ); } catch ( MException &e ) { hystWindow = DEFAULT_HYST_WINDOW; } if( hystWindow < 0 ) { throw MException( "Invalid hysteresis window value : " + Value2StrReal( hystWindow ) ); } createQuantizer(); // output file try { outFileName = MainSimulator::Instance().getParameter( description(), "outputFile" ); } catch ( MException &e ) { outFileName = DEFAULT_QBG_OUTFILENAME; } } catch ( MException &e ) { e.print( cerr ); MTHROW( e ) ; } } /******************************************************************* * Function Name: ~QBGInductorEffortIn * Destructor ********************************************************************/ QBGInductorEffortIn::~QBGInductorEffortIn() { if( quantizer != NULL ) { delete quantizer; } outFile.close(); } /******************************************************************* * Function Name: createQuantizer ********************************************************************/ Model &QBGInductorEffortIn::createQuantizer() { quantizer = new UniformQuantizer(); assert( quantizer ); ((UniformQuantizer *)quantizer)->setQuantum( quantum ); return *this; } /******************************************************************* * Function Name: initFunction ********************************************************************/ Model &QBGInductorEffortIn::initFunction() { i = quantizer->quantize( initialLoad ); qValue = i + quantum; time = 0; der = 0; init = true; eps1 = quantum/2; eps2 = (quantum - hystWindow )/2; // out file outFile.open( outFileName.c_str() ); outFile << "\nTime, Flow, Effort"; holdIn( active, Time::Zero ); return *this ; } /******************************************************************* * Function Name: externalFunction ********************************************************************/ Model &QBGInductorEffortIn::externalFunction( const ExternalMessage &msg ) { RealValue currTime = msg.time().asMsecs(); RealValue nextTime; RealValue val = msg.value(); RealValue e; RealValue func; effort = val; e = currTime - time; val = val * TICK_VALUE; // en msecs val = val * 1/I; if( TRUNCATE( fabs( val ), TOLERANCE ) == 0 ) { time = currTime; i = i + der * e; der = 0; passivate(); } else { func = i + der * e; if( val > 0 ) { if ( der < 0 ) { qValue += quantum; } nextTime = fabs( ( qValue + eps1 - func ) / val ); } else { if ( init ) { qValue -= quantum; init = false; } if ( der > 0 ) { qValue -= quantum; } nextTime = fabs( ( func - ( qValue - hystWindow - eps2 ) ) / val ); } RealValue waitTime = nextTime * TICK_VALUE; time = currTime; i = func; der = val; ni = i + der * nextTime; holdIn( active, Time( static_cast( waitTime ) ) ); } return *this ; } /******************************************************************* * Function Name: internalFunction ********************************************************************/ Model &QBGInductorEffortIn::internalFunction( const InternalMessage &msg ) { RealValue currTime = msg.time().asMsecs(); RealValue nextTime; RealValue e; RealValue func; e = currTime - time; func = i + der * e; if( TRUNCATE( fabs( der ), TOLERANCE ) == 0 ) { passivate(); } else if( der > 0 && ( fabs( qValue - quantizer->quantize( func ) ) > TOLERANCE ) ) { // El quantum es muy chico, precision no soportada MException e( "\nPrecision not supported by the simulator! Increase the quantum value for component " + description() ); throw e; } else if( ( der < 0 ) && ( ( func > ( qValue - hystWindow ) ) || ( func < ( qValue - quantum ) ) ) ) { // El quantum es muy chico, precision no soportada MException e( "\nPrecision not supported by the simulator! Increase the quantum value for component " + description() ); throw e; } else { if( der > 0 ) { qValue += quantum; nextTime = fabs( ( qValue + eps1 - func ) / der ); } else { qValue -= quantum; nextTime = fabs( ( func - ( qValue - hystWindow - eps2 ) ) / der ); } RealValue waitTime = nextTime * TICK_VALUE; time = currTime; i = func; ni = i + der * nextTime; holdIn( active, Time( static_cast( waitTime ) ) ); } return *this ; } /******************************************************************* * Function Name: outputFunction ********************************************************************/ Model &QBGInductorEffortIn::outputFunction( const InternalMessage &msg ) { sendOutput( msg.time(), f1p, ni ) ; outFile << "\n" << msg.time().asMsecs() << "," << quantizer->quantize( ni ) << "," << effort; return *this ; }