/******************************************************* * * DESCRIPTION: QBG parallel junction class * * AUTHOR: Mariana C. D'Abreu * * EMAIL: mdabreu@dc.uba.ar * ********************************************************/ #include "qbg_pjunc.h" #include "defaults.h" #include "defaults_mapping.h" /******************************************************************* * Function Name: QBGParallelJunction * Description: constructor ********************************************************************/ QBGParallelJunction::QBGParallelJunction( const string &name ) : Atomic( name ) , e1p( addInputPort( "e1p" ) ) , e1n( addInputPort( "e1n" ) ) , f2p( addInputPort( "f2p" ) ) , f3p( addInputPort( "f3p" ) ) , f4p( addInputPort( "f4p" ) ) , f5p( addInputPort( "f5p" ) ) , f6p( addInputPort( "f6p" ) ) , f2n( addInputPort( "f2n" ) ) , f3n( addInputPort( "f3n" ) ) , f4n( addInputPort( "f4n" ) ) , f5n( addInputPort( "f5n" ) ) , f6n( addInputPort( "f6n" ) ) , f1p( addOutputPort( "f1p" ) ) , f1n( addOutputPort( "f1n" ) ) , e2p( addOutputPort( "e2p" ) ) , e3p( addOutputPort( "e3p" ) ) , e4p( addOutputPort( "e4p" ) ) , e5p( addOutputPort( "e5p" ) ) , e6p( addOutputPort( "e6p" ) ) , e2n( addOutputPort( "e2n" ) ) , e3n( addOutputPort( "e3n" ) ) , e4n( addOutputPort( "e4n" ) ) , e5n( addOutputPort( "e5n" ) ) , e6n( addOutputPort( "e6n" ) ) { effort = 0; flowP = 0; flowN = 0; flows = new RealValue[JUNC_MAX_PORTS]; MASSERT( flows ); } /******************************************************************* * Function Name: ********************************************************************/ QBGParallelJunction::~QBGParallelJunction() { if( flows != NULL ) { delete flows; } } /******************************************************************* * Function Name: initFunction ********************************************************************/ Model &QBGParallelJunction::initFunction() { init = true; effort = 0; flowP = 0; flowN = 0; resetFlows(); passivate(); return *this ; } /******************************************************************* * Function Name: internalFunction ********************************************************************/ Model &QBGParallelJunction::internalFunction( const InternalMessage &msg ) { passivate(); return *this; } /******************************************************************* * Function Name: externalFunction ********************************************************************/ Model &QBGParallelJunction::externalFunction( const ExternalMessage &msg ) { RealValue value = msg.value(); if ( msg.port() == e1p || msg.port() == e1n ) { // Si recibe nuevo effort, y es distinto al ultimo effort recibido, actualiza los valores if( value != effort || init ) { effort = value; holdIn( active, Time::Zero ); } else { passivate(); } } else { // Si se produjo entrada de flow por alguno de los ports, y es distinto al // ultimo flow recibido para ese port, recalculo el valor if( updateFlow( msg.port().name(), value ) ) { holdIn( active, Time::Zero ); } else { passivate(); } } init = false; return *this; } /******************************************************************* * Function Name: outputFunction ********************************************************************/ Model &QBGParallelJunction::outputFunction( const InternalMessage &msg ) { // Envia el effort por todos los puertos de effort... sendOutput( msg.time(), e2p, effort ); sendOutput( msg.time(), e3p, effort ); sendOutput( msg.time(), e4p, effort ); sendOutput( msg.time(), e5p, effort ); sendOutput( msg.time(), e6p, effort ); sendOutput( msg.time(), e2n, effort ); sendOutput( msg.time(), e3n, effort ); sendOutput( msg.time(), e4n, effort ); sendOutput( msg.time(), e5n, effort ); sendOutput( msg.time(), e6n, effort ); // ... y el flow por el port de salida de flow sendOutput( msg.time(), f1p, flowP ); sendOutput( msg.time(), f1n, ( flowP * -1 ) ); return *this ; } /******************************************************************* * Function Name: ********************************************************************/ bool QBGParallelJunction::updateFlow( const string &portName, const RealValue &value ) { RealValue val; int signPort; getPortValueAndSign( portName, val, signPort ); if( value == val && !init ) { // no se realiza actualizacion return false; } flowP = flowP + ( val * signPort ); flowP = flowP - ( value * signPort ); setPortValue( portName, value ); return true; } /******************************************************************* * Function Name: ********************************************************************/ void QBGParallelJunction::resetFlows() { for( int i = 0; i < JUNC_MAX_PORTS - 1; i++ ) flows[i] = 0; } /******************************************************************* * Function Name: ********************************************************************/ void QBGParallelJunction::getPortInfo( const string &pName, string &pType, int &pNum, string &pSign ) { // Descompongo el nombre del puerto en (e|f) + id + sign int len = strlen( pName.c_str() ); pType = pName.substr( 0, 1 ); pNum = atoi( pName.substr( 1, len - 1).c_str() ); pSign = pName.substr( len - 1 ); } /******************************************************************* * Function Name: ********************************************************************/ void QBGParallelJunction::getPortValueAndSign( const string &pName, RealValue &pVal, int &pSign ) { string type, sign; int num; getPortInfo( pName, type, num, sign ); if ( num < 2 || num > JUNC_MAX_PORTS ) { throw MException( "Invalid port number: " + num ); } num -= 2; // los puertos se numeran desde 2 pVal = flows[num]; if( sign == POSITIVE_ID ) pSign = 1; else pSign = -1; } /******************************************************************* * Function Name: ********************************************************************/ void QBGParallelJunction::setPortValue( const string &pName, const RealValue &pVal ) { string type, sign; int num; getPortInfo( pName, type, num, sign ); if ( num < 2 || num > JUNC_MAX_PORTS ) { throw MException( "Invalid port number: " + num ); } num -= 2; // los puertos se numeran desde 2 flows[num] = pVal; }