KiCad PCB EDA Suite
ngspice.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2016-2018 CERN
5  * Copyright (C) 2018-2021 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * @author Tomasz Wlostowski <[email protected]>
8  * @author Maciej Suminski <[email protected]>
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License
12  * as published by the Free Software Foundation; either version 3
13  * of the License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, you may find one here:
22  * https://www.gnu.org/licenses/gpl-3.0.html
23  * or you may search the http://www.gnu.org website for the version 3 license,
24  * or you may write to the Free Software Foundation, Inc.,
25  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
26  */
27 
28 #include <config.h> // Needed for MSW compilation
29 #include <wx/log.h>
30 
31 #include "ngspice.h"
32 #include "spice_reporter.h"
33 #include "spice_settings.h"
34 
35 #include <common.h>
36 #include <locale_io.h>
37 
38 #include <paths.h>
39 
40 #include <wx/stdpaths.h>
41 #include <wx/dir.h>
42 
43 #include <stdexcept>
44 
45 #include <algorithm>
46 
47 using namespace std;
48 
49 
57 static const wxChar* const traceNgspice = wxT( "KICAD_NGSPICE" );
58 
59 
61  m_ngSpice_Init( nullptr ),
62  m_ngSpice_Circ( nullptr ),
63  m_ngSpice_Command( nullptr ),
64  m_ngGet_Vec_Info( nullptr ),
65  m_ngSpice_CurPlot( nullptr ),
66  m_ngSpice_AllPlots( nullptr ),
67  m_ngSpice_AllVecs( nullptr ),
68  m_ngSpice_Running( nullptr ),
69  m_error( false )
70 {
71  init_dll();
72 }
73 
74 
76 {
77 }
78 
79 
80 void NGSPICE::Init( const SPICE_SIMULATOR_SETTINGS* aSettings )
81 {
82  Command( "reset" );
83 
84  for( const std::string& command : GetSettingCommands() )
85  {
86  wxLogTrace( traceNgspice, "Sending Ngspice configuration command '%s'.", command );
87  Command( command );
88  }
89 }
90 
91 
92 vector<string> NGSPICE::AllPlots() const
93 {
94  LOCALE_IO c_locale; // ngspice works correctly only with C locale
95  char* currentPlot = m_ngSpice_CurPlot();
96  char** allPlots = m_ngSpice_AllVecs( currentPlot );
97  int noOfPlots = 0;
98 
99  vector<string> retVal;
100 
101  if( allPlots != nullptr )
102  {
103  for( char** plot = allPlots; *plot != nullptr; plot++ )
104  noOfPlots++;
105 
106  retVal.reserve( noOfPlots );
107 
108  for( int i = 0; i < noOfPlots; i++, allPlots++ )
109  {
110  string vec = *allPlots;
111  retVal.push_back( vec );
112  }
113  }
114 
115 
116  return retVal;
117 }
118 
119 
120 vector<COMPLEX> NGSPICE::GetPlot( const string& aName, int aMaxLen )
121 {
122  LOCALE_IO c_locale; // ngspice works correctly only with C locale
123  vector<COMPLEX> data;
124  vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
125 
126  if( vi )
127  {
128  int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
129  data.reserve( length );
130 
131  if( vi->v_realdata )
132  {
133  for( int i = 0; i < length; i++ )
134  data.emplace_back( vi->v_realdata[i], 0.0 );
135  }
136  else if( vi->v_compdata )
137  {
138  for( int i = 0; i < length; i++ )
139  data.emplace_back( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag );
140  }
141  }
142 
143  return data;
144 }
145 
146 
147 vector<double> NGSPICE::GetRealPlot( const string& aName, int aMaxLen )
148 {
149  LOCALE_IO c_locale; // ngspice works correctly only with C locale
150  vector<double> data;
151  vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
152 
153  if( vi )
154  {
155  int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
156  data.reserve( length );
157 
158  if( vi->v_realdata )
159  {
160  for( int i = 0; i < length; i++ )
161  {
162  data.push_back( vi->v_realdata[i] );
163  }
164  }
165  else if( vi->v_compdata )
166  {
167  for( int i = 0; i < length; i++ )
168  {
169  wxASSERT( vi->v_compdata[i].cx_imag == 0.0 );
170  data.push_back( vi->v_compdata[i].cx_real );
171  }
172  }
173  }
174 
175  return data;
176 }
177 
178 
179 vector<double> NGSPICE::GetImagPlot( const string& aName, int aMaxLen )
180 {
181  LOCALE_IO c_locale; // ngspice works correctly only with C locale
182  vector<double> data;
183  vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
184 
185  if( vi )
186  {
187  int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
188  data.reserve( length );
189 
190  if( vi->v_compdata )
191  {
192  for( int i = 0; i < length; i++ )
193  {
194  data.push_back( vi->v_compdata[i].cx_imag );
195  }
196  }
197  }
198 
199  return data;
200 }
201 
202 
203 vector<double> NGSPICE::GetMagPlot( const string& aName, int aMaxLen )
204 {
205  LOCALE_IO c_locale; // ngspice works correctly only with C locale
206  vector<double> data;
207  vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
208 
209  if( vi )
210  {
211  int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
212  data.reserve( length );
213 
214  if( vi->v_realdata )
215  {
216  for( int i = 0; i < length; i++ )
217  data.push_back( vi->v_realdata[i] );
218  }
219  else if( vi->v_compdata )
220  {
221  for( int i = 0; i < length; i++ )
222  data.push_back( hypot( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag ) );
223  }
224  }
225 
226  return data;
227 }
228 
229 
230 vector<double> NGSPICE::GetPhasePlot( const string& aName, int aMaxLen )
231 {
232  LOCALE_IO c_locale; // ngspice works correctly only with C locale
233  vector<double> data;
234  vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() );
235 
236  if( vi )
237  {
238  int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
239  data.reserve( length );
240 
241  if( vi->v_realdata )
242  {
243  for( int i = 0; i < length; i++ )
244  data.push_back( 0.0 ); // well, that's life
245  }
246  else if( vi->v_compdata )
247  {
248  for( int i = 0; i < length; i++ )
249  data.push_back( atan2( vi->v_compdata[i].cx_imag, vi->v_compdata[i].cx_real ) );
250  }
251  }
252 
253  return data;
254 }
255 
256 
257 bool NGSPICE::LoadNetlist( const string& aNetlist )
258 {
259  LOCALE_IO c_locale; // ngspice works correctly only with C locale
260  vector<char*> lines;
261  stringstream ss( aNetlist );
262 
263  m_netlist = "";
264 
265  while( !ss.eof() )
266  {
267  char line[1024];
268  ss.getline( line, sizeof( line ) );
269  lines.push_back( strdup( line ) );
270  m_netlist += std::string( line ) + std::string( "\n" );
271  }
272 
273  lines.push_back( nullptr ); // sentinel, as requested in ngSpice_Circ description
274  m_ngSpice_Circ( lines.data() );
275 
276  for( auto line : lines )
277  free( line );
278 
279  return true;
280 }
281 
282 
284 {
285  wxBusyCursor dummy;
286 
287  LOCALE_IO c_locale; // ngspice works correctly only with C locale
288  bool success = Command( "bg_run" ); // bg_* commands execute in a separate thread
289 
290  if( success )
291  {
292  // wait for end of simulation.
293  // calling wxYield() allows printing activity, and stopping ngspice from GUI
294  // Also note: do not user wxSafeYield, because when using it we cannot stop
295  // ngspice from the GUI
296  do
297  {
298  wxMilliSleep( 50 );
299  wxYield();
300  } while( m_ngSpice_Running() );
301  }
302 
303  return success;
304 }
305 
306 
308 {
309  LOCALE_IO c_locale; // ngspice works correctly only with C locale
310  return Command( "bg_halt" ); // bg_* commands execute in a separate thread
311 }
312 
313 
315 {
316  // No need to use C locale here
317  return m_ngSpice_Running();
318 }
319 
320 
321 bool NGSPICE::Command( const string& aCmd )
322 {
323  LOCALE_IO c_locale; // ngspice works correctly only with C locale
324  validate();
325  m_ngSpice_Command( (char*) aCmd.c_str() );
326  return true;
327 }
328 
329 
330 string NGSPICE::GetXAxis( SIM_TYPE aType ) const
331 {
332  switch( aType )
333  {
334  case ST_AC:
335  case ST_NOISE:
336  return string( "frequency" );
337 
338  case ST_DC:
339  // find plot, which ends with "-sweep"
340  for( auto& plot : AllPlots() )
341  {
342  const string sweepEnding = "-sweep";
343  unsigned int len = sweepEnding.length();
344 
345  if( plot.length() > len
346  && plot.substr( plot.length() - len, len ).compare( sweepEnding ) == 0 )
347  {
348  return string( plot );
349  }
350  }
351  break;
352 
353  case ST_TRANSIENT:
354  return string( "time" );
355 
356  default:
357  break;
358  }
359 
360  return string( "" );
361 }
362 
363 
364 std::vector<std::string> NGSPICE::GetSettingCommands() const
365 {
366  const NGSPICE_SIMULATOR_SETTINGS* settings =
367  dynamic_cast<const NGSPICE_SIMULATOR_SETTINGS*>( Settings().get() );
368 
369  std::vector<std::string> commands;
370 
371  wxCHECK( settings, commands );
372 
373  switch( settings->GetModelMode() )
374  {
376  break;
377 
379  commands.emplace_back( "unset ngbehavior" );
380  break;
381 
383  commands.emplace_back( "set ngbehavior=ps" );
384  break;
385 
387  commands.emplace_back( "set ngbehavior=lt" );
388  break;
389 
391  commands.emplace_back( "set ngbehavior=ltps" );
392  break;
393 
395  commands.emplace_back( "set ngbehavior=hs" );
396  break;
397 
398  default:
399  wxFAIL_MSG( wxString::Format( "Undefined NGSPICE_MODEL_MODE %d.",
400  settings->GetModelMode() ) );
401  break;
402  }
403 
404  return commands;
405 }
406 
407 
408 const std::string NGSPICE::GetNetlist() const
409 {
410  return m_netlist;
411 }
412 
413 
415 {
416  if( m_initialized )
417  return;
418 
419  LOCALE_IO c_locale; // ngspice works correctly only with C locale
420  const wxStandardPaths& stdPaths = wxStandardPaths::Get();
421 
422  if( m_dll.IsLoaded() ) // enable force reload
423  m_dll.Unload();
424 
425  // Extra effort to find libngspice
426  // @todo Shouldn't we be using the normal KiCad path searching mechanism here?
427  wxFileName dllFile( "", NGSPICE_DLL_FILE );
428 #if defined(__WINDOWS__)
429  #if defined( _MSC_VER )
430  const vector<string> dllPaths = { "" };
431  #else
432  const vector<string> dllPaths = { "", "/mingw64/bin", "/mingw32/bin" };
433  #endif
434 #elif defined(__WXMAC__)
435  const vector<string> dllPaths = {
436  PATHS::GetOSXKicadUserDataDir().ToStdString() + "/PlugIns/ngspice",
437  PATHS::GetOSXKicadMachineDataDir().ToStdString() + "/PlugIns/ngspice",
438 
439  // when running kicad.app
440  stdPaths.GetPluginsDir().ToStdString() + "/sim",
441 
442  // when running eeschema.app
443  wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
444  "/../../../../../Contents/PlugIns/sim"
445  };
446 #else // Unix systems
447  const vector<string> dllPaths = { "/usr/local/lib" };
448 #endif
449 
450 #if defined(__WINDOWS__) || (__WXMAC__)
451  for( const auto& path : dllPaths )
452  {
453  dllFile.SetPath( path );
454  wxLogTrace( traceNgspice, "libngspice search path: %s", dllFile.GetFullPath() );
455  m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
456 
457  if( m_dll.IsLoaded() )
458  {
459  wxLogTrace( traceNgspice, "libngspice path found in: %s", dllFile.GetFullPath() );
460  break;
461  }
462  }
463 
464  if( !m_dll.IsLoaded() ) // try also the system libraries
465  m_dll.Load( wxDynamicLibrary::CanonicalizeName( "ngspice" ) );
466 #else
467  // First, try the system libraries
468  m_dll.Load( NGSPICE_DLL_FILE, wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
469 
470  // If failed, try some other paths:
471  if( !m_dll.IsLoaded() )
472  {
473  for( const auto& path : dllPaths )
474  {
475  dllFile.SetPath( path );
476  wxLogTrace( traceNgspice, "libngspice search path: %s", dllFile.GetFullPath() );
477  m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
478 
479  if( m_dll.IsLoaded() )
480  {
481  wxLogTrace( traceNgspice, "libngspice path found in: %s", dllFile.GetFullPath() );
482  break;
483  }
484  }
485  }
486 #endif
487 
488  if( !m_dll.IsLoaded() )
489  throw std::runtime_error( "Missing ngspice shared library" );
490 
491  m_error = false;
492 
493  // Obtain function pointers
494  m_ngSpice_Init = (ngSpice_Init) m_dll.GetSymbol( "ngSpice_Init" );
495  m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" );
496  m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" );
497  m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll.GetSymbol( "ngGet_Vec_Info" );
498  m_ngSpice_CurPlot = (ngSpice_CurPlot) m_dll.GetSymbol( "ngSpice_CurPlot" );
499  m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll.GetSymbol( "ngSpice_AllPlots" );
500  m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" );
501  m_ngSpice_Running = (ngSpice_Running) m_dll.GetSymbol( "ngSpice_running" ); // it is not a typo
502 
504  &cbBGThreadRunning, this );
505 
506  // Load a custom spinit file, to fix the problem with loading .cm files
507  // Switch to the executable directory, so the relative paths are correct
508  wxString cwd( wxGetCwd() );
509  wxFileName exeDir( stdPaths.GetExecutablePath() );
510  wxSetWorkingDirectory( exeDir.GetPath() );
511 
512  // Find *.cm files
513  string cmPath = findCmPath();
514 
515  // __CMPATH is used in custom spinit file to point to the codemodels directory
516  if( !cmPath.empty() )
517  Command( "set __CMPATH=\"" + cmPath + "\"" );
518 
519  // Possible relative locations for spinit file
520  const vector<string> spiceinitPaths =
521  {
522  ".",
523 #ifdef __WXMAC__
524  stdPaths.GetPluginsDir().ToStdString() + "/sim/ngspice/scripts",
525  wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
526  "/../../../../../Contents/PlugIns/sim/ngspice/scripts"
527 #endif
528  "../share/kicad",
529  "../share",
530  "../../share/kicad",
531  "../../share"
532  };
533 
534  bool foundSpiceinit = false;
535 
536  for( const auto& path : spiceinitPaths )
537  {
538  wxLogTrace( traceNgspice, "ngspice init script search path: %s", path );
539 
540  if( loadSpinit( path + "/spiceinit" ) )
541  {
542  wxLogTrace( traceNgspice, "ngspice path found in: %s", path );
543  foundSpiceinit = true;
544  break;
545  }
546  }
547 
548  // Last chance to load codemodel files, we have not found
549  // spiceinit file, but we know the path to *.cm files
550  if( !foundSpiceinit && !cmPath.empty() )
551  loadCodemodels( cmPath );
552 
553  // Restore the working directory
554  wxSetWorkingDirectory( cwd );
555 
556  // Workarounds to avoid hang ups on certain errors
557  // These commands have to be called, no matter what is in the spinit file
558  Command( "unset interactive" );
559  Command( "set noaskquit" );
560  Command( "set nomoremode" );
561 
562  m_initialized = true;
563 }
564 
565 
566 bool NGSPICE::loadSpinit( const string& aFileName )
567 {
568  if( !wxFileName::FileExists( aFileName ) )
569  return false;
570 
571  wxTextFile file;
572 
573  if( !file.Open( aFileName ) )
574  return false;
575 
576  for( auto cmd = file.GetFirstLine(); !file.Eof(); cmd = file.GetNextLine() )
577  Command( cmd.ToStdString() );
578 
579  return true;
580 }
581 
582 
583 string NGSPICE::findCmPath() const
584 {
585  const vector<string> cmPaths =
586  {
587 #ifdef __WXMAC__
588  "/Applications/ngspice/lib/ngspice",
589  "Contents/Frameworks",
590  wxStandardPaths::Get().GetPluginsDir().ToStdString() + "/sim/ngspice",
591  wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath().ToStdString() +
592  "/../../../../../Contents/PlugIns/sim/ngspice",
593  "../Plugins/sim/ngspice",
594 #endif
595  "../lib/ngspice",
596  "../../lib/ngspice",
597  "lib/ngspice",
598  "ngspice"
599  };
600 
601  for( const auto& path : cmPaths )
602  {
603  wxLogTrace( traceNgspice, "ngspice code models search path: %s", path );
604 
605  if( wxFileName::FileExists( path + "/spice2poly.cm" ) )
606  {
607  wxLogTrace( traceNgspice, "ngspice code models found in: %s", path );
608  return path;
609  }
610  }
611 
612  return string();
613 }
614 
615 
616 bool NGSPICE::loadCodemodels( const string& aPath )
617 {
618  wxArrayString cmFiles;
619  size_t count = wxDir::GetAllFiles( aPath, &cmFiles );
620 
621  for( const auto& cm : cmFiles )
622  Command( "codemodel " + cm.ToStdString() );
623 
624  return count != 0;
625 }
626 
627 
628 int NGSPICE::cbSendChar( char* aWhat, int aId, void* aUser )
629 {
630  NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
631 
632  if( sim->m_reporter )
633  {
634  // strip stdout/stderr from the line
635  if( ( strncasecmp( aWhat, "stdout ", 7 ) == 0 )
636  || ( strncasecmp( aWhat, "stderr ", 7 ) == 0 ) )
637  aWhat += 7;
638 
639  sim->m_reporter->Report( aWhat );
640  }
641 
642  return 0;
643 }
644 
645 
646 int NGSPICE::cbSendStat( char *aWhat, int aId, void* aUser )
647 {
648  return 0;
649 }
650 
651 
652 int NGSPICE::cbBGThreadRunning( NG_BOOL aFinished, int aId, void* aUser )
653 {
654  NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
655 
656  if( sim->m_reporter )
657  sim->m_reporter->OnSimStateChange( sim, aFinished ? SIM_IDLE : SIM_RUNNING );
658 
659  return 0;
660 }
661 
662 
663 int NGSPICE::cbControlledExit( int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId, void* aUser )
664 {
665  // Something went wrong, reload the dll
666  NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
667  sim->m_error = true;
668 
669  return 0;
670 }
671 
672 
674 {
675  if( m_error )
676  {
677  m_initialized = false;
678  init_dll();
679  }
680 }
681 
682 
683 bool NGSPICE::m_initialized = false;
std::vector< std::string > AllPlots() const override
Return a requested vector with complex values.
Definition: ngspice.cpp:92
static int cbBGThreadRunning(NG_BOOL aFinished, int aId, void *aUser)
Definition: ngspice.cpp:652
bool NG_BOOL
Definition: ngspice.h:41
virtual ~NGSPICE()
Definition: ngspice.cpp:75
bool Run() override
Halt the simulation.
Definition: ngspice.cpp:283
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:40
void validate()
Error flag indicating that ngspice needs to be reloaded.
Definition: ngspice.cpp:673
static const wxChar *const traceNgspice
Flag to enable debug output of Ngspice simulator.
Definition: ngspice.cpp:57
std::string findCmPath() const
Load codemodel files from a directory.
Definition: ngspice.cpp:583
SPICE_REPORTER * m_reporter
< Reporter object to receive simulation log.
std::shared_ptr< SPICE_SIMULATOR_SETTINGS > & Settings()
Return the simulator configuration settings.
Definition: bitmap.cpp:64
std::vector< double > GetRealPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with imaginary values.
Definition: ngspice.cpp:147
char **(* ngSpice_AllVecs)(char *plotname)
Definition: ngspice.h:110
wxDynamicLibrary m_dll
Execute commands from a file.
Definition: ngspice.h:123
bool loadCodemodels(const std::string &aPath)
Definition: ngspice.cpp:616
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
std::vector< double > GetImagPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with magnitude values.
Definition: ngspice.cpp:179
ngSpice_Running m_ngSpice_Running
Definition: ngspice.h:121
std::vector< double > GetMagPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with phase values.
Definition: ngspice.cpp:203
static bool m_initialized
Current netlist.
Definition: ngspice.h:149
static LIB_SYMBOL * dummy()
Used to draw a dummy shape when a LIB_SYMBOL is not found in library.
Definition: sch_symbol.cpp:72
void(* ngSpice_Init)(SendChar *, SendStat *, ControlledExit *, SendData *, SendInitData *, BGThreadRunning *, void *)
Definition: ngspice.h:103
virtual const std::string GetNetlist() const override
Return current SPICE netlist used by the simulator.
Definition: ngspice.cpp:408
NGSPICE()
Definition: ngspice.cpp:60
ngGet_Vec_Info m_ngGet_Vec_Info
Definition: ngspice.h:117
bool m_error
Ngspice should be initialized only once.
Definition: ngspice.h:146
void init_dll()
Definition: ngspice.cpp:414
SIM_TYPE
< Possible simulation types
Definition: sim_types.h:31
pvector_info(* ngGet_Vec_Info)(char *vecname)
Definition: ngspice.h:107
char *(* ngSpice_CurPlot)(void)
Definition: ngspice.h:108
std::vector< COMPLEX > GetPlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with real values.
Definition: ngspice.cpp:120
bool Stop() override
Check if simulation is running at the moment.
Definition: ngspice.cpp:307
ngSpice_Init m_ngSpice_Init
Definition: ngspice.h:114
std::string GetXAxis(SIM_TYPE aType) const override
Return a list with all vectors generated in current simulation.
Definition: ngspice.cpp:330
std::vector< double > GetPhasePlot(const std::string &aName, int aMaxLen=-1) override
Return a requested vector with phase values.
Definition: ngspice.cpp:230
int(* ngSpice_Command)(char *command)
Definition: ngspice.h:106
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void Init(const SPICE_SIMULATOR_SETTINGS *aSettings=nullptr) override
Load a netlist for the simulation.
Definition: ngspice.cpp:80
NGSPICE_MODEL_MODE GetModelMode() const
bool LoadNetlist(const std::string &aNetlist) override
Execute the simulation with currently loaded netlist.
Definition: ngspice.cpp:257
bool(* ngSpice_Running)(void)
Handle to DLL functions.
Definition: ngspice.h:111
Container for Ngspice simulator settings.
static int cbControlledExit(int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId, void *aUser)
Definition: ngspice.cpp:663
bool Command(const std::string &aCmd) override
Set a SPICE_REPORTER object to receive the simulation log.
Definition: ngspice.cpp:321
static int cbSendStat(char *what, int aId, void *aUser)
Definition: ngspice.cpp:646
bool IsRunning() override
Execute a Spice command as if it was typed into console.
Definition: ngspice.cpp:314
ngSpice_AllVecs m_ngSpice_AllVecs
Definition: ngspice.h:120
std::vector< std::string > GetSettingCommands() const override
Return current SPICE netlist used by the simulator.
Definition: ngspice.cpp:364
The common library.
virtual void OnSimStateChange(SPICE_SIMULATOR *aObject, SIM_STATE aNewState)=0
ngSpice_Command m_ngSpice_Command
Definition: ngspice.h:116
std::string m_netlist
Definition: ngspice.h:152
bool loadSpinit(const std::string &aFileName)
Check a few different locations for codemodel files and returns one if it exists.
Definition: ngspice.cpp:566
static int cbSendChar(char *what, int aId, void *aUser)
Definition: ngspice.cpp:628
ngSpice_Circ m_ngSpice_Circ
Definition: ngspice.h:115
ngSpice_CurPlot m_ngSpice_CurPlot
Definition: ngspice.h:118
ngSpice_AllPlots m_ngSpice_AllPlots
Definition: ngspice.h:119
char **(* ngSpice_AllPlots)(void)
Definition: ngspice.h:109
int(* ngSpice_Circ)(char **circarray)
Definition: ngspice.h:105
Storage for simulator specific settings.