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 + -
显示快捷键?