prcngspice.cpp
来自「gspiceui电子CAD仿真程序.用于电路参数模拟仿真」· C++ 代码 · 共 989 行 · 第 1/2 页
CPP
989 行
<< roSim.rosGetSwpStop( ); // Create the PRINT command osCmdPR = wxT(".PRINT AC"); for( uiPar=Simulation::ePAR_FST; uiPar<=Simulation::ePAR_LST; uiPar++ ) { if( ! roSim.bGetOutPar( (Simulation::eParType) uiPar ) ) continue; // Add the parameter prefix switch( uiPar ) { case Simulation::ePAR_VLT: osPar = wxT('V'); break; case Simulation::ePAR_CUR: osPar = wxT('I'); break; case Simulation::ePAR_PWR: osPar = wxT('P'); break; case Simulation::ePAR_RES: osPar = wxT('R'); break; default: continue; } // Add the complex part prefix for( uiCpx=Simulation::eCPX_FST; uiCpx<=Simulation::eCPX_LST; uiCpx++ ) { if( ! roSim.bGetOutCpx( (Simulation::eCpxType) uiCpx ) ) continue; osCpx = osPar; switch( uiCpx ) { case Simulation::eCPX_MAG: if( ! roSim.bGetOutCpx( Simulation::eCPX_MAGDB ) ) osCpx << wxT('M'); else osCpx << wxT("DB"); break; case Simulation::eCPX_PHASE: osCpx << wxT('P'); break; case Simulation::eCPX_REAL: osCpx << wxT('R'); break; case Simulation::eCPX_IMAG: osCpx << wxT('I'); break; default: continue; } osCpx << wxT('('); // Add any components and/or nodes to derivation list for this parameter os1 = rosMakeArgsPR( roSim, osCpx ); if( ! os1.IsEmpty( ) ) osCmdPR << os1; } } // Add simulation commands to Simulation object roSim.bAddSimCmd( osCmdOPT ); roSim.bAddSimCmd( osCmdPR ); roSim.bAddSimCmd( osCmdOP ); roSim.bAddSimCmd( osCmdAC );}//*****************************************************************************// Create the simulator command sequence for a transient analysis.//// Argument List:// roSim - Simulation objectvoid PrcNgSpice::MakeCmdTR( Simulation & roSim ){ wxString osCmdOPT; wxString osCmdIC; wxString osCmdPR; wxString osCmdTR; wxString osPar, os1; uint uiPar, ui1; size_t szt1; // Clear the field list m_osFieldLst.Empty( ); // Create the OPTIONS command os1 = roSim.rosGetTempC( ); osCmdOPT << wxT(".OPTIONS TEMP=") << os1 << wxT(" TNOM=") << os1; // Create initial conditions command ui1 = (uint) roSim.iGetSwpScale( ); if( ui1==PnlNgSpiceTR::eINITC_COLD || ui1==PnlNgSpiceTR::eINITC_UICS ) { const wxArrayString & roas1 = roSim.roasGetNodeLbls( ); if( roas1.GetCount( ) > 0 ) { osCmdIC << wxT(".IC"); for( szt1=0; szt1<roas1.GetCount( ); szt1++ ) osCmdIC << wxT(" V(") << roas1.Item( szt1 ) << wxT(")=0.0"); } } // Create the TR command osCmdTR << wxT(".TRAN ") << roSim.rosGetSwpStep( ) << wxT(' ') << roSim.rosGetSwpStop( ) << wxT(' ') << roSim.rosGetSwpStart( ) << wxT(' ') << roSim.rosGetSwpStep( ); // TMAX calculation increment if( roSim.iGetSwpScale( ) == PnlNgSpiceTR::eINITC_UICS ) osCmdTR << wxT(" UIC"); // Create the PRINT commands osCmdPR << wxT(".PRINT TRAN"); for( uiPar=Simulation::ePAR_FST; uiPar<=Simulation::ePAR_LST; uiPar++ ) { if( ! roSim.bGetOutPar( (Simulation::eParType) uiPar ) ) continue; switch( uiPar ) { case Simulation::ePAR_VLT: osPar = wxT("V("); break; case Simulation::ePAR_CUR: osPar = wxT("I("); break; case Simulation::ePAR_PWR: osPar = wxT("P("); break; case Simulation::ePAR_RES: osPar = wxT("R("); break; default: continue; } // Add any components and/or nodes to derivation list for this parameter os1 = rosMakeArgsPR( roSim, osPar ); if( ! os1.IsEmpty( ) ) osCmdPR << os1; } // Add simulation commands to Simulation object roSim.bAddSimCmd( osCmdOPT ); roSim.bAddSimCmd( osCmdIC ); roSim.bAddSimCmd( osCmdPR ); roSim.bAddSimCmd( osCmdTR );}//*****************************************************************************// Generate the simulator commands to be executed based on the simulation// specifications and the NetList description.//// Arguments:// roSim - The net list and simulation specification//// Return Values:// TRUE - Success// FALSE - Failurebool PrcNgSpice::bMakeCmds( Simulation & roSim ){ switch( roSim.eGetAnaType( ) ) { case Simulation::eANA_DC: MakeCmdDC( roSim ); break; case Simulation::eANA_AC: MakeCmdAC( roSim ); break; case Simulation::eANA_TR: MakeCmdTR( roSim ); break; default: return( FALSE ); } if( roSim.roasGetSimCmds( ).IsEmpty( ) ) return( FALSE ); return( TRUE );}//*****************************************************************************// Create a list of arguments for the Spice PRINT command based on the test// components and test nodes specified in a Simulation object. A prefix may be// specified which is prepended to each argument in the list.//// Argument List:// roSim - The Simutation object// rosPrefix - The prefix to be prepended to each argument//// Return Values:// Success - A list of correctly formatted arguments// Failure - An empty stringwxString & PrcNgSpice::rosMakeArgsPR( Simulation & roSim, wxString & rosPrefix ){ static wxString osArgs; Component oCpnt; wxString os1; wxChar oc1; size_t szt1; osArgs.Empty( ); // Add any components to derivation list for this parameter for( szt1=0; szt1<roSim.roasGetTstCpnts( ).GetCount( ); szt1++ ) { os1 = roSim.roasGetTstCpnts( ).Item( szt1 ); m_osFieldLst << rosPrefix << os1 << wxT(')'); os1 = roSim.rosGetCpnt( os1.c_str( ) ); if( os1.IsEmpty( ) ) continue; if( ! oCpnt.bSetLine( os1.c_str( ) ) ) continue; const wxArrayString & roas2 = oCpnt.roasGetNodes( ); if( roas2.GetCount( ) != 2 ) continue; osArgs << wxT(' '); if( roas2.Item( 0 ).IsSameAs( wxT('0') ) ) osArgs << wxT('-') << rosPrefix; else osArgs << rosPrefix << roas2.Item( 0 ) << wxT(','); osArgs << roas2.Item( 1 ) << wxT(')'); } // Add any nodes to derivation list for voltage only for( oc1=0, szt1=0; szt1<rosPrefix.Length( ); szt1++ ) { oc1 = rosPrefix.GetChar( szt1 ); if( ! wxIsspace( oc1 ) ) break; } if( oc1==wxT('v') || oc1==wxT('V') ) { for( szt1=0; szt1<roSim.roasGetTstNodes( ).GetCount( ); szt1++ ) { os1.Empty( ); os1 << wxT(' ') << rosPrefix << roSim.roasGetTstNodes( ).Item( szt1 ) << wxT(')'); osArgs << os1; m_osFieldLst << os1; } } return( osArgs );}//*****************************************************************************// Format the results file eg. get rid of simulation engine banner message.//// Return Values:// TRUE - Success// FALSE - Failurebool PrcNgSpice::bFmtResultsFile( void ){ wxString os1; size_t szt1, szt2; // Attempt to open the results file wxTextFile oFile( m_oFnmResults.GetFullPath( ) ); if( ! oFile.Exists( ) ) return( FALSE ); if( ! oFile.Open( ) ) return( FALSE ); // Find the beginning of the data area (ie. the 1st line starting with "Index") for( szt1=0; szt1<oFile.GetLineCount( ); szt1++ ) { os1 = oFile.GetLine( szt1 ); if( os1.StartsWith( wxT("Index") ) ) break; } if( szt1 >= (oFile.GetLineCount( )-1) ) { oFile.Close( ); return( FALSE ); } // Format the column header line if( ! bFmtResultsHead( os1 ) ) { oFile.Close( ); return( FALSE ); } oFile.GetLine( szt1 ) = os1; // Delete everything before the data area szt2 = szt1; for( szt1=0; szt1<szt2; szt1++ ) oFile.RemoveLine( 0 ); if( oFile.GetLineCount( ) > 0 ) oFile.RemoveLine( 1 ); // Delete lines other than data lines for( szt1=1; szt1<oFile.GetLineCount( ); szt1++ ) { os1 = oFile.GetLine( szt1 ); if( ! wxIsdigit( os1.GetChar( 0 ) ) ) { oFile.RemoveLine( szt1 ); szt1--; } } oFile.AddLine( wxT("") ); // Format data lines for( szt1=1; szt1<oFile.GetLineCount( ); szt1++ ) { os1 = oFile.GetLine( szt1 ); bFmtResultsLine( os1 ); oFile.GetLine( szt1 ) = os1; } oFile.Write( ); // Save the changes to disk oFile.Close( ); // Close the file return( TRUE );}//*****************************************************************************// Format the column header from the results file.//// Argument List:// rosLine - The column header to be formatted//// Return Values:// TRUE - Success// FALSE - Failurebool PrcNgSpice::bFmtResultsHead( wxString & rosLine ){ wxStringTokenizer oStrTok; wxString os1; int i1; // Tokenize the string oStrTok.SetString( rosLine ); if( oStrTok.CountTokens( ) < 3 ) return( FALSE ); // Dispose of the first field oStrTok.GetNextToken( ); // Extract the operator field and replace the Ng-Spice field identifiers os1 << oStrTok.GetNextToken( ) << wxT(' ') << m_osFieldLst; oStrTok.SetString( os1 ); // Format each field rosLine = wxT('#'); while( oStrTok.HasMoreTokens( ) ) { if( rosLine.Length( ) > 1 ) { // Place a new field at every 12 columns i1 = 12 - (rosLine.Length( ) % 12) + 1; rosLine.Append( wxT(' '), i1 ); } rosLine << oStrTok.GetNextToken( ); } return( TRUE );}//*****************************************************************************// Format a data line from the results file.//// Argument List:// rosLine - The data line to be formatted//// Return Values:// TRUE - Success// FALSE - Failurebool PrcNgSpice::bFmtResultsLine( wxString & rosLine ){ wxStringTokenizer oStrTok; wxString os1; double f1; int i1; // Tokenize the string oStrTok.SetString( rosLine ); if( oStrTok.CountTokens( ) < 3 ) return( FALSE ); // Dispose of the first field oStrTok.GetNextToken( ); // Format each field rosLine.Empty( ); while( oStrTok.HasMoreTokens( ) ) { if( rosLine.Length( ) > 0 ) { // Place a new field at every 12 columns i1 = 12 - (rosLine.Length( ) % 12); rosLine.Append( wxT(' '), i1 ); } os1 = oStrTok.GetNextToken( ); if( os1.Last( ) == wxT(',') ) { os1.Last( ) = wxT(' '); oStrTok.GetNextToken( ); } if( ! ConvertType::bStrToFlt( os1, &f1 ) ) f1 = -9.999e+99; if( ! ConvertType::bFltToStr( f1, os1 ) ) os1 = wxT("-9.999e+99"); rosLine << os1; } return( TRUE );}//*****************************************************************************// Parse the simulation commands strings found in a Simulation object and load// the values back into the Simulation object.//// Arguments:// roSim - The simulation object//// Return Values:// TRUE - Success// FALSE - Failurebool PrcNgSpice::bParseSim( Simulation & roSim ){ const wxArrayString & roasCmds=roSim.roasGetSimCmds( ); wxString os1; size_t szt1; // Set the default state of some of the simulation object attributes roSim.bSetOutPar( Simulation::ePAR_VLT, TRUE ); roSim.bSetOutCpx( Simulation::eCPX_MAG, TRUE ); roSim.bSetOutCpx( Simulation::eCPX_MAGDB, TRUE ); // Go through the simulation commands and attempt to parse them for( szt1=0; szt1<roasCmds.GetCount( ); szt1++ ) { os1 = roasCmds.Item( szt1 ); if( bParseCmdOPT( os1, roSim ) ) continue; if( bParseCmdOP ( os1, roSim ) ) continue; if( bParseCmdIC ( os1, roSim ) ) continue; if( bParseCmdDC ( os1, roSim ) ) continue; if( bParseCmdAC ( os1, roSim ) ) continue; if( bParseCmdTR ( os1, roSim ) ) continue; if( bParseCmdPR ( os1, roSim ) ) continue; } return( TRUE );}//*****************************************************************************// Create the simulation commands from the values found in a Simulation object// and load the command string back into the Simulation object.//// Arguments:// roSim - The simulation object//// Return Values:// TRUE - Success// FALSE - Failurebool PrcNgSpice::bMakeSim( Simulation & roSim ){ wxFileName ofn1; wxString os1; int i1; // Clear error attributes m_osError.Empty( ); // Only execute simulation if it isn't already running if( bIsExec( ) ) { m_osError = wxT("Simulation already running"); return( FALSE ); } // Create the simulator commands if( ! bMakeCmds( roSim ) ) { m_osError = wxT("Couldn't create simulator commands"); return( FALSE ); } // Save circuit description and SPICE commands to file ofn1 = roSim.roGetLoadFile( ); if( ofn1.GetFullName( ).Find( wxT(".gspiceui.") ) == -1 ) ofn1.SetName( ofn1.GetName( ) + wxT(".gspiceui") ); if( ! roSim.bSaveFile( ofn1.GetFullPath( ) ) ) { m_osError=wxT("Simulation couldn't be saved to file"); return( FALSE ); } // Create the results file name os1 = roSim.roGetLoadFile( ).GetPath( ) + wxT('/') + roSim.roGetLoadFile( ).GetName( ); i1 = os1.Find( wxT(".gspiceui") ); if( i1 > 0 ) os1 = os1.Truncate( (size_t) i1 ); os1 << wxT('.') << roGetBinary( ).GetName( ); switch( roSim.eGetAnaType( ) ) { case Simulation::eANA_DC: os1 << wxT(".dc"); break; case Simulation::eANA_AC: os1 << wxT(".ac"); break; case Simulation::eANA_DI: os1 << wxT(".di"); break; case Simulation::eANA_NO: os1 << wxT(".no"); break; case Simulation::eANA_PZ: os1 << wxT(".pz"); break; case Simulation::eANA_SE: os1 << wxT(".se"); break; case Simulation::eANA_TR: os1 << wxT(".tr"); break; case Simulation::eANA_TF: os1 << wxT(".tf"); break; default: return( FALSE ); } if( ! bSetResultsFile( os1.c_str( ) ) ) { m_osError = wxT("Couldn't set results file name"); return( FALSE ); } // Construct the command line to execute the simulation os1 = wxT("-n -b ") + roSim.roGetSaveFile( ).GetFullPath( ); if( ! bSetArgLst( os1.c_str( ) ) ) { m_osError = wxT("Couldn't set argument list"); return( FALSE ); } return( TRUE );}//*****************************************************************************// Execute a simulation.//// Return Values:// TRUE - Success// FALSE - Failurebool PrcNgSpice::bExec( void ){ wxString os1, os2; // Execute the simulation if( ! PrcBase::bExec( ) ) return( FALSE ); // Save the simulation output to file os1 = roGetLogFile( ).GetFullPath( ); if( ! bSaveOutput( os1 ) ) return( FALSE ); // Copy the log file to the results file os2 = roGetResultsFile( ).GetFullPath( ); if( ! wxCopyFile( os1, os2 ) ) return( FALSE ); // Format the simulation results if( ! bFmtResultsFile( ) ) return( FALSE ); return( TRUE );}//*****************************************************************************
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?