//************************************************************************************************** // CpntNgsIndSrc.cpp * // ------------------- * // Started : 2008-06-12 * // Last Update : 2014-12-15 * // Copyright : (C) 2008-2016 MSWaters * //************************************************************************************************** //************************************************************************************************** // * // This program is free software; you can redistribute it and/or modify it under the * // terms of the GNU General Public License as published by the Free Software Foundation; * // either version 3 of the License, or (at your option) any later version. * // * //************************************************************************************************** #include "CpntNgsIndSrc.hpp" //************************************************************************************************** // Constructor. CpntNgsIndSrc::CpntNgsIndSrc( void ) : Component( ) { bClear( ); } //************************************************************************************************** // Destructor. CpntNgsIndSrc::~CpntNgsIndSrc( ) { } //************************************************************************************************** // Parse the value part of the component definition string. // // Eg. : Vin 3 0 SIN(0 1 100Meg 1ns 1E10) // // Return Values : // true - Success // false - Failure bool CpntNgsIndSrc::bParseValue( void ) { wxStringTokenizer ostk1; size_t szSin, szPulse; size_t sz1, sz2; ClrValues( ); // Find the beginning of the SIN and/or PULSE sections szSin = Component::m_osValue.Upper( ).Find( wxT("SIN(") ); szPulse = Component::m_osValue.Upper( ).Find( wxT("PULSE(") ); if( szSin==wxString::npos && szPulse==wxString::npos ) return( false ); // Extract the sinusoid function parameter values if( szSin != wxString::npos ) { sz1 = Component::m_osValue.find( wxT('('), szSin ); sz2 = Component::m_osValue.find( wxT(')'), szSin ); if( sz1==wxString::npos || sz2==wxString::npos ) return( false ); ostk1.SetString( Component::m_osValue.substr( sz1+1, sz2-sz1-1 ) ); if( ostk1.CountTokens( ) != 5 ) return( false ); m_osSinOffset = ostk1.GetNextToken( ); m_osSinAmp = ostk1.GetNextToken( ); m_osSinFreq = ostk1.GetNextToken( ); m_osSinDelay = ostk1.GetNextToken( ); m_osSinDamp = ostk1.GetNextToken( ); } // Extract the pulse function parameter values if( szPulse != wxString::npos ) { sz1 = Component::m_osValue.find( wxT('('), szPulse ); sz2 = Component::m_osValue.find( wxT(')'), szPulse ); if( sz1==wxString::npos || sz2==wxString::npos ) return( false ); ostk1.SetString( Component::m_osValue.substr( sz1+1, sz2-sz1-1 ) ); if( ostk1.CountTokens( ) != 7 ) return( false ); m_osPulInitial = ostk1.GetNextToken( ); m_osPulMax = ostk1.GetNextToken( ); m_osPulDelay = ostk1.GetNextToken( ); m_osPulRise = ostk1.GetNextToken( ); m_osPulFall = ostk1.GetNextToken( ); m_osPulWidth = ostk1.GetNextToken( ); m_osPulPeriod = ostk1.GetNextToken( ); } return( true ); } //************************************************************************************************** // Format the value part of the command string. // // Eg. : Vin 3 0 SIN(0 1 100Meg 1ns 1E10) // // Return Values : // true - Success // false - Failure bool CpntNgsIndSrc::bFormatValue( void ) { float f1; bool b1; m_osValue.Empty( ); f1 = 0.0; b1 = CnvtType::bStrToFlt( m_osSinAmp, &f1 ); if( b1==true && f1!=0.0 ) { // Create the sinusoid function section m_osValue << wxT("SIN( "); m_osValue << m_osSinOffset << wxT(' '); m_osValue << m_osSinAmp << wxT(' '); m_osValue << m_osSinFreq << wxT(' '); m_osValue << m_osSinDelay << wxT(' '); m_osValue << m_osSinDamp << wxT(' '); m_osValue << wxT(')'); } f1 = 0.0; b1 = CnvtType::bStrToFlt( m_osPulMax, &f1 ); if( b1==true && f1!=0.0 ) { // Create the pulse function section if( ! m_osValue.IsEmpty( ) ) m_osValue << wxT(' '); m_osValue << wxT("PULSE( "); m_osValue << m_osPulInitial << wxT(' '); m_osValue << m_osPulMax << wxT(' '); m_osValue << m_osPulDelay << wxT(' '); m_osValue << m_osPulRise << wxT(' '); m_osValue << m_osPulFall << wxT(' '); m_osValue << m_osPulWidth << wxT(' '); m_osValue << m_osPulPeriod << wxT(' '); m_osValue << wxT(')'); } if( m_osValue.IsEmpty( ) ) m_osValue = wxT("0.0"); return( true ); } //************************************************************************************************** // Check that the object attributes are valid. // // Return Values : // true - Success // false - Failure bool CpntNgsIndSrc::bValidate( void ) { double dfSinOffset, dfSinAmp, dfSinFreq, dfSinDelay, dfSinDamp; double dfPulInitial, dfPulMax, dfPulDelay, dfPulRise, dfPulWidth, dfPulFall, dfPulPeriod; // Check the validity of the base component if( ! Component::bValidate( ) ) return( false ); // Check that the component type is valid if( m_eType!=eCPNT_IVS && m_eType!=eCPNT_ICS ) return( false ); // Check the sinusoidal source values dfSinAmp = 0.0; dfSinOffset = 0.0; dfSinFreq = 0.0; dfSinDelay = 0.0; dfSinDamp = 0.0; if( ! CnvtType::bStrToFlt( m_osSinOffset, &dfSinOffset ) ) bSetErrMsg( wxT("sinusoid offset value is invalid") ); if( ! CnvtType::bStrToFlt( m_osSinAmp, &dfSinAmp ) ) bSetErrMsg( wxT("sinusoid amplitude value is invalid") ); if( ! CnvtType::bStrToFlt( m_osSinFreq, &dfSinFreq ) ) bSetErrMsg( wxT("sinusoid frequency value is invalid") ); if( ! CnvtType::bStrToFlt( m_osSinDelay, &dfSinDelay ) ) bSetErrMsg( wxT("sinusoid delay value is invalid") ); if( ! CnvtType::bStrToFlt( m_osSinDamp, &dfSinDamp ) ) bSetErrMsg( wxT("sinusoid damping factor is invalid") ); // Check overall sinusoidal source logic if( dfSinFreq>0.0 && dfSinAmp <=0.0 ) bSetErrMsg( wxT("sinusoid amplitude value must be greater than zero") ); if( dfSinAmp >0.0 && dfSinFreq<=0.0 ) bSetErrMsg( wxT("sinusoid frequency must be greater than zero") ); // Check the pulse source values dfPulInitial = 0.0; dfPulMax = 0.0; dfPulDelay = 0.0; dfPulRise = 0.0; dfPulWidth = 0.0; dfPulFall = 0.0; dfPulPeriod = 0.0; if( ! CnvtType::bStrToFlt( m_osPulInitial, &dfPulInitial ) ) bSetErrMsg( wxT("initial pulse value is invalid") ); if( ! CnvtType::bStrToFlt( m_osPulMax, &dfPulMax ) ) bSetErrMsg( wxT("maximum pulse value is invalid") ); if( ! CnvtType::bStrToFlt( m_osPulDelay, &dfPulDelay ) ) bSetErrMsg( wxT("pulse delay value is invalid") ); if( ! CnvtType::bStrToFlt( m_osPulRise, &dfPulRise ) ) bSetErrMsg( wxT("pulse rise time value is invalid") ); if( ! CnvtType::bStrToFlt( m_osPulWidth, &dfPulWidth ) ) bSetErrMsg( wxT("pulse width value is invalid") ); if( ! CnvtType::bStrToFlt( m_osPulFall, &dfPulFall ) ) bSetErrMsg( wxT("pulse fall time value is invalid") ); if( ! CnvtType::bStrToFlt( m_osPulPeriod, &dfPulPeriod ) ) bSetErrMsg( wxT("pulse period value is invalid") ); // Check the pulse time values if( dfPulPeriod < dfPulRise ) bSetErrMsg( wxT("pulse rise time is greater than the period") ); if( dfPulPeriod < dfPulWidth ) bSetErrMsg( wxT("pulse width is greater than the period") ); if( dfPulPeriod < dfPulFall ) bSetErrMsg( wxT("pulse fall time is greater than the period") ); if( dfPulPeriod < dfPulRise+dfPulWidth+dfPulFall ) bSetErrMsg( wxT("pulse period is less then the width") ); // Check the pulse level values if( dfPulInitial > dfPulMax ) bSetErrMsg( wxT("initial pulse value is greater than the maximum value") ); // Check overall pulse source logic if( dfPulPeriod!=0.0 && (dfPulInitial==0.0 && dfPulMax==0.0) ) bSetErrMsg( wxT("pulse timing has been defined but no levels") ); if( dfPulPeriod==0.0 && (dfPulInitial!=0.0 || dfPulMax!=0.0) ) bSetErrMsg( wxT("pulse levels have been defined but no timings") ); return( bIsValid( ) ); } //************************************************************************************************** void CpntNgsIndSrc::ClrValues( void ) { m_osSinOffset = NGS_SINOFFSET; m_osSinAmp = NGS_SINAMP; m_osSinFreq = NGS_SINFREQ; m_osSinDelay = NGS_SINDELAY; m_osSinDamp = NGS_SINDAMP; m_osPulInitial = NGS_PULINITIAL; m_osPulMax = NGS_PULMAX; m_osPulDelay = NGS_PULDELAY; m_osPulRise = NGS_PULRISE; m_osPulWidth = NGS_PULWIDTH; m_osPulFall = NGS_PULFALL; m_osPulPeriod = NGS_PULPERIOD; } //************************************************************************************************** // Clear the object attributes. // // Return Values : // true - Success // false - Failure bool CpntNgsIndSrc::bClear( void ) { Component::bClear( ); ClrValues( ); return( true ); } //************************************************************************************************** // Copy and digest the contents of a Component object. // // Argument List : // roCpnt - A reference to a Component object // // Return Values : // A reference to this object CpntNgsIndSrc & CpntNgsIndSrc::operator = ( const Component & roCpnt ) { // Copy the component contents (Component &) *this = roCpnt; // Parse the value part of the component definition bParseValue( ); return( *this ); } //************************************************************************************************** // Copy the contents of an CmdGnuCapGEN object. // // Argument List : // roCmdGEN - A reference to a CmdGnuCapGEN object // // Return Values : // A reference to this object CpntNgsIndSrc & CpntNgsIndSrc::operator = ( const CmdGnuCapGEN & roCmdGEN ) { double df1, df2; m_osSinOffset = roCmdGEN.m_osOffset; m_osSinAmp = roCmdGEN.m_osAmplitude; m_osSinFreq = roCmdGEN.m_osSinFreq; if( CnvtType::bStrToFlt( roCmdGEN.m_osSinPhase, &df1 ) && CnvtType::bStrToFlt( roCmdGEN.m_osSinFreq, &df2 ) ) CnvtType::bFltToStr( df1 / (360.0 * df2), m_osSinDelay ); else m_osSinDelay = wxT("0.0"); m_osSinDamp = wxT("0.0"); m_osPulInitial = roCmdGEN.m_osPulInitial; m_osPulMax = roCmdGEN.m_osPulMax; m_osPulDelay = roCmdGEN.m_osPulDelay; m_osPulRise = roCmdGEN.m_osPulRise; m_osPulWidth = roCmdGEN.m_osPulWidth; m_osPulFall = roCmdGEN.m_osPulFall; m_osPulPeriod = roCmdGEN.m_osPulPeriod; bFormat( ); return( *this ); } //************************************************************************************************** // Print the object attributes. // // Argument List : // rosPrefix - A prefix to every line displayed (usually just spaces) void CpntNgsIndSrc::Print( const wxString & rosPrefix ) { Component::Print( rosPrefix + wxT("Component::") ); std::cout << rosPrefix.mb_str( ) << "m_osSinOffset : " << m_osSinOffset .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osSinAmp : " << m_osSinAmp .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osSinFreq : " << m_osSinFreq .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osSinDelay : " << m_osSinDelay .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osSinDamp : " << m_osSinDamp .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osPulseInitV : " << m_osPulInitial.mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osPulseMaxV : " << m_osPulMax .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osPulseDelay : " << m_osPulDelay .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osPulseRise : " << m_osPulRise .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osPulseWidth : " << m_osPulWidth .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osPulseFall : " << m_osPulFall .mb_str( ) << '\n'; std::cout << rosPrefix.mb_str( ) << "m_osPulsePeriod : " << m_osPulPeriod .mb_str( ) << '\n'; } //**************************************************************************************************