KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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-2022 CERN
5 * Copyright (C) 2018-2024 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 <common.h>
30#include <locale_io.h>
31#include <fmt/core.h>
32#include <paths.h>
33
34#include "spice_circuit_model.h"
35#include "ngspice.h"
36#include "simulator_reporter.h"
37#include "spice_settings.h"
38
39#include <wx/stdpaths.h>
40#include <wx/dir.h>
41#include <wx/log.h>
42
43#include <stdexcept>
44#include <algorithm>
45
46
54static const wxChar* const traceNgspice = wxT( "KICAD_NGSPICE" );
55
56
58 m_ngSpice_Init( nullptr ),
59 m_ngSpice_Circ( nullptr ),
60 m_ngSpice_Command( nullptr ),
61 m_ngGet_Vec_Info( nullptr ),
62 m_ngCM_Input_Path( nullptr ),
63 m_ngSpice_CurPlot( nullptr ),
64 m_ngSpice_AllPlots( nullptr ),
65 m_ngSpice_AllVecs( nullptr ),
66 m_ngSpice_Running( nullptr ),
67 m_ngSpice_LockRealloc( nullptr ),
68 m_ngSpice_UnlockRealloc( nullptr ),
69 m_error( false )
70{
71 init_dll();
72}
73
74
75NGSPICE::~NGSPICE() = default;
76
77
79{
80 for( const std::string& command : GetSettingCommands() )
81 {
82 wxLogTrace( traceNgspice, "Sending Ngspice configuration command '%s'.", command );
83 Command( command );
84 }
85}
86
87
88void NGSPICE::Init( const SPICE_SETTINGS* aSettings )
89{
90 Command( "reset" );
92}
93
94
96{
97 return wxString( m_ngSpice_CurPlot() );
98}
99
100
101std::vector<std::string> NGSPICE::AllVectors() const
102{
103 LOCALE_IO c_locale; // ngspice works correctly only with C locale
104 char* currentPlot = m_ngSpice_CurPlot();
105 char** allVectors = m_ngSpice_AllVecs( currentPlot );
106 int noOfVectors = 0;
107
108 std::vector<std::string> retVal;
109
110 if( allVectors != nullptr )
111 {
112 for( char** plot = allVectors; *plot != nullptr; plot++ )
113 noOfVectors++;
114
115 retVal.reserve( noOfVectors );
116
117 for( int i = 0; i < noOfVectors; i++, allVectors++ )
118 {
119 std::string vec = *allVectors;
120 retVal.push_back( vec );
121 }
122 }
123
124
125 return retVal;
126}
127
128
129std::vector<COMPLEX> NGSPICE::GetComplexVector( const std::string& aName, int aMaxLen )
130{
131 LOCALE_IO c_locale; // ngspice works correctly only with C locale
132 std::vector<COMPLEX> data;
133 NGSPICE_LOCK_REALLOC lock( this );
134
135 if( aMaxLen == 0 )
136 return data;
137
138 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
139 {
140 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
141 data.reserve( length );
142
143 if( vi->v_realdata )
144 {
145 for( int i = 0; i < length; i++ )
146 data.emplace_back( vi->v_realdata[i], 0.0 );
147 }
148 else if( vi->v_compdata )
149 {
150 for( int i = 0; i < length; i++ )
151 data.emplace_back( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag );
152 }
153 }
154
155 return data;
156}
157
158
159std::vector<double> NGSPICE::GetRealVector( const std::string& aName, int aMaxLen )
160{
161 LOCALE_IO c_locale; // ngspice works correctly only with C locale
162 std::vector<double> data;
163 NGSPICE_LOCK_REALLOC lock( this );
164
165 if( aMaxLen == 0 )
166 return data;
167
168 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
169 {
170 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
171 data.reserve( length );
172
173 if( vi->v_realdata )
174 {
175 for( int i = 0; i < length; i++ )
176 data.push_back( vi->v_realdata[i] );
177 }
178 else if( vi->v_compdata )
179 {
180 for( int i = 0; i < length; i++ )
181 {
182 wxASSERT( vi->v_compdata[i].cx_imag == 0.0 );
183 data.push_back( vi->v_compdata[i].cx_real );
184 }
185 }
186 }
187
188 return data;
189}
190
191
192std::vector<double> NGSPICE::GetImaginaryVector( const std::string& aName, int aMaxLen )
193{
194 LOCALE_IO c_locale; // ngspice works correctly only with C locale
195 std::vector<double> data;
196 NGSPICE_LOCK_REALLOC lock( this );
197
198 if( aMaxLen == 0 )
199 return data;
200
201 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
202 {
203 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
204 data.reserve( length );
205
206 if( vi->v_compdata )
207 {
208 for( int i = 0; i < length; i++ )
209 data.push_back( vi->v_compdata[i].cx_imag );
210 }
211 }
212
213 return data;
214}
215
216
217std::vector<double> NGSPICE::GetGainVector( const std::string& aName, int aMaxLen )
218{
219 LOCALE_IO c_locale; // ngspice works correctly only with C locale
220 std::vector<double> data;
221 NGSPICE_LOCK_REALLOC lock( this );
222
223 if( aMaxLen == 0 )
224 return data;
225
226 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
227 {
228 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
229 data.reserve( length );
230
231 if( vi->v_realdata )
232 {
233 for( int i = 0; i < length; i++ )
234 data.push_back( vi->v_realdata[i] );
235 }
236 else if( vi->v_compdata )
237 {
238 for( int i = 0; i < length; i++ )
239 data.push_back( hypot( vi->v_compdata[i].cx_real, vi->v_compdata[i].cx_imag ) );
240 }
241 }
242
243 return data;
244}
245
246
247std::vector<double> NGSPICE::GetPhaseVector( const std::string& aName, int aMaxLen )
248{
249 LOCALE_IO c_locale; // ngspice works correctly only with C locale
250 std::vector<double> data;
251 NGSPICE_LOCK_REALLOC lock( this );
252
253 if( aMaxLen == 0 )
254 return data;
255
256 if( vector_info* vi = m_ngGet_Vec_Info( (char*) aName.c_str() ) )
257 {
258 int length = aMaxLen < 0 ? vi->v_length : std::min( aMaxLen, vi->v_length );
259 data.reserve( length );
260
261 if( vi->v_realdata )
262 {
263 for( int i = 0; i < length; i++ )
264 data.push_back( 0.0 ); // well, that's life
265 }
266 else if( vi->v_compdata )
267 {
268 for( int i = 0; i < length; i++ )
269 data.push_back( atan2( vi->v_compdata[i].cx_imag, vi->v_compdata[i].cx_real ) );
270 }
271 }
272
273 return data;
274}
275
276
277bool NGSPICE::Attach( const std::shared_ptr<SIMULATION_MODEL>& aModel, const wxString& aSimCommand,
278 unsigned aSimOptions, const wxString& aInputPath, REPORTER& aReporter )
279{
280 SPICE_CIRCUIT_MODEL* model = dynamic_cast<SPICE_CIRCUIT_MODEL*>( aModel.get() );
281 STRING_FORMATTER formatter;
282
283 setCodemodelsInputPath( aInputPath.ToStdString() );
284
285 if( model && model->GetNetlist( aSimCommand, aSimOptions, &formatter, aReporter ) )
286 {
287 SIMULATOR::Attach( aModel, aSimCommand, aSimOptions, aInputPath, aReporter );
289 LoadNetlist( formatter.GetString() );
290
292 {
293 Command( "echo Command: esave none" );
294 Command( "esave none" );
295 }
296
297 return true;
298 }
299 else
300 {
301 SIMULATOR::Attach( nullptr, wxEmptyString, 0, wxEmptyString, aReporter );
302 return false;
303 }
304}
305
306
307bool NGSPICE::LoadNetlist( const std::string& aNetlist )
308{
309 LOCALE_IO c_locale; // ngspice works correctly only with C locale
310 std::vector<char*> lines;
311 std::stringstream ss( aNetlist );
312
313 m_netlist.erase();
314
315 for( std::string line; std::getline( ss, line ); )
316 {
317 lines.push_back( strdup( line.data() ) );
318 m_netlist += line;
319 m_netlist += '\n';
320 }
321
322 lines.push_back( nullptr ); // sentinel, as requested in ngSpice_Circ description
323
324 Command( "remcirc" );
325 bool success = !m_ngSpice_Circ( lines.data() );
326
327 for( char* line : lines )
328 free( line );
329
330 return success;
331}
332
333
335{
336 LOCALE_IO toggle; // ngspice works correctly only with C locale
337 return Command( "bg_run" ); // bg_* commands execute in a separate thread
338}
339
340
342{
343 LOCALE_IO c_locale; // ngspice works correctly only with C locale
344 return Command( "bg_halt" ); // bg_* commands execute in a separate thread
345}
346
347
349{
350 // No need to use C locale here
351 return m_ngSpice_Running();
352}
353
354
355bool NGSPICE::Command( const std::string& aCmd )
356{
357 LOCALE_IO c_locale; // ngspice works correctly only with C locale
358 validate();
359 return !m_ngSpice_Command( (char*) aCmd.c_str() );
360}
361
362
363wxString NGSPICE::GetXAxis( SIM_TYPE aType ) const
364{
365 switch( aType )
366 {
367 case ST_AC:
368 case ST_SP:
369 case ST_NOISE:
370 case ST_FFT:
371 return wxS( "frequency" );
372
373 case ST_DC:
374 // find plot, which ends with "-sweep"
375 for( wxString vector : AllVectors() )
376 {
377 if( vector.Lower().EndsWith( wxS( "-sweep" ) ) )
378 return vector;
379 }
380
381 return wxS( "sweep" );
382
383 case ST_TRAN:
384 return wxS( "time" );
385
386 default:
387 return wxEmptyString;
388 }
389}
390
391
392std::vector<std::string> NGSPICE::GetSettingCommands() const
393{
394 const NGSPICE_SETTINGS* settings = dynamic_cast<const NGSPICE_SETTINGS*>( Settings().get() );
395
396 std::vector<std::string> commands;
397
398 wxCHECK( settings, commands );
399
400 switch( settings->GetCompatibilityMode() )
401 {
402 case NGSPICE_COMPATIBILITY_MODE::USER_CONFIG: break;
403 case NGSPICE_COMPATIBILITY_MODE::NGSPICE: commands.emplace_back( "unset ngbehavior" ); break;
404 case NGSPICE_COMPATIBILITY_MODE::PSPICE: commands.emplace_back( "set ngbehavior=psa" ); break;
405 case NGSPICE_COMPATIBILITY_MODE::LTSPICE: commands.emplace_back( "set ngbehavior=lta" ); break;
406 case NGSPICE_COMPATIBILITY_MODE::LT_PSPICE: commands.emplace_back( "set ngbehavior=ltpsa" ); break;
407 case NGSPICE_COMPATIBILITY_MODE::HSPICE: commands.emplace_back( "set ngbehavior=hsa" ); break;
408 default: wxFAIL_MSG( wxString::Format( "Undefined NGSPICE_COMPATIBILITY_MODE %d.",
409 settings->GetCompatibilityMode() ) ); break;
410 }
411
412 return commands;
413}
414
415
416const std::string NGSPICE::GetNetlist() const
417{
418 return m_netlist;
419}
420
421
423{
424 if( m_initialized )
425 return;
426
427 LOCALE_IO c_locale; // ngspice works correctly only with C locale
428 const wxStandardPaths& stdPaths = wxStandardPaths::Get();
429
430 if( m_dll.IsLoaded() ) // enable force reload
431 m_dll.Unload();
432
433 // Extra effort to find libngspice
434 // @todo Shouldn't we be using the normal KiCad path searching mechanism here?
435 wxFileName dllFile( "", NGSPICE_DLL_FILE );
436#if defined(__WINDOWS__)
437 #if defined( _MSC_VER )
438 const std::vector<std::string> dllPaths = { "" };
439 #else
440 const std::vector<std::string> dllPaths = { "", "/mingw64/bin", "/mingw32/bin" };
441 #endif
442#elif defined(__WXMAC__)
443 const std::vector<std::string> dllPaths = {
444 PATHS::GetOSXKicadUserDataDir().ToStdString() + "/PlugIns/ngspice",
445 PATHS::GetOSXKicadMachineDataDir().ToStdString() + "/PlugIns/ngspice",
446
447 // when running kicad.app
448 stdPaths.GetPluginsDir().ToStdString() + "/sim",
449
450 // when running eeschema.app
451 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
452 "/../../../../../Contents/PlugIns/sim"
453 };
454#else // Unix systems
455 const std::vector<std::string> dllPaths = { "/usr/local/lib" };
456#endif
457
458#if defined(__WINDOWS__) || (__WXMAC__)
459 for( const auto& path : dllPaths )
460 {
461 dllFile.SetPath( path );
462 wxLogTrace( traceNgspice, "libngspice search path: %s", dllFile.GetFullPath() );
463 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
464
465 if( m_dll.IsLoaded() )
466 {
467 wxLogTrace( traceNgspice, "libngspice path found in: %s", dllFile.GetFullPath() );
468 break;
469 }
470 }
471
472 if( !m_dll.IsLoaded() ) // try also the system libraries
473 m_dll.Load( wxDynamicLibrary::CanonicalizeName( "ngspice" ) );
474#else
475 // First, try the system libraries
476 m_dll.Load( NGSPICE_DLL_FILE, wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
477
478 // If failed, try some other paths:
479 if( !m_dll.IsLoaded() )
480 {
481 for( const auto& path : dllPaths )
482 {
483 dllFile.SetPath( path );
484 wxLogTrace( traceNgspice, "libngspice search path: %s", dllFile.GetFullPath() );
485 m_dll.Load( dllFile.GetFullPath(), wxDL_VERBATIM | wxDL_QUIET | wxDL_NOW );
486
487 if( m_dll.IsLoaded() )
488 {
489 wxLogTrace( traceNgspice, "libngspice path found in: %s", dllFile.GetFullPath() );
490 break;
491 }
492 }
493 }
494#endif
495
496 if( !m_dll.IsLoaded() )
497 throw std::runtime_error( "Missing ngspice shared library" );
498
499 m_error = false;
500
501 // Obtain function pointers
502 m_ngSpice_Init = (ngSpice_Init) m_dll.GetSymbol( "ngSpice_Init" );
503 m_ngSpice_Circ = (ngSpice_Circ) m_dll.GetSymbol( "ngSpice_Circ" );
504 m_ngSpice_Command = (ngSpice_Command) m_dll.GetSymbol( "ngSpice_Command" );
505 m_ngGet_Vec_Info = (ngGet_Vec_Info) m_dll.GetSymbol( "ngGet_Vec_Info" );
506 m_ngCM_Input_Path = (ngCM_Input_Path) m_dll.GetSymbol( "ngCM_Input_Path" );
507 m_ngSpice_CurPlot = (ngSpice_CurPlot) m_dll.GetSymbol( "ngSpice_CurPlot" );
508 m_ngSpice_AllPlots = (ngSpice_AllPlots) m_dll.GetSymbol( "ngSpice_AllPlots" );
509 m_ngSpice_AllVecs = (ngSpice_AllVecs) m_dll.GetSymbol( "ngSpice_AllVecs" );
510 m_ngSpice_Running = (ngSpice_Running) m_dll.GetSymbol( "ngSpice_running" ); // it is not a typo
511
512 if( m_dll.HasSymbol( "ngSpice_LockRealloc" ) )
513 {
514 m_ngSpice_LockRealloc = (ngSpice_LockRealloc) m_dll.GetSymbol( "ngSpice_LockRealloc" );
515 m_ngSpice_UnlockRealloc = (ngSpice_UnlockRealloc) m_dll.GetSymbol( "ngSpice_UnlockRealloc" );
516 }
517
519 &cbBGThreadRunning, this );
520
521 // Load a custom spinit file, to fix the problem with loading .cm files
522 // Switch to the executable directory, so the relative paths are correct
523 wxString cwd( wxGetCwd() );
524 wxFileName exeDir( stdPaths.GetExecutablePath() );
525 wxSetWorkingDirectory( exeDir.GetPath() );
526
527 // Find *.cm files
528 std::string cmPath = findCmPath();
529
530 // __CMPATH is used in custom spinit file to point to the codemodels directory
531 if( !cmPath.empty() )
532 Command( "set __CMPATH=\"" + cmPath + "\"" );
533
534 // Possible relative locations for spinit file
535 const std::vector<std::string> spiceinitPaths =
536 {
537 ".",
538#ifdef __WXMAC__
539 stdPaths.GetPluginsDir().ToStdString() + "/sim/ngspice/scripts",
540 wxFileName( stdPaths.GetExecutablePath() ).GetPath().ToStdString() +
541 "/../../../../../Contents/PlugIns/sim/ngspice/scripts"
542#endif
543 "../share/kicad",
544 "../share",
545 "../../share/kicad",
546 "../../share"
547 };
548
549 bool foundSpiceinit = false;
550
551 for( const auto& path : spiceinitPaths )
552 {
553 wxLogTrace( traceNgspice, "ngspice init script search path: %s", path );
554
555 if( loadSpinit( path + "/spiceinit" ) )
556 {
557 wxLogTrace( traceNgspice, "ngspice path found in: %s", path );
558 foundSpiceinit = true;
559 break;
560 }
561 }
562
563 // Last chance to load codemodel files, we have not found
564 // spiceinit file, but we know the path to *.cm files
565 if( !foundSpiceinit && !cmPath.empty() )
566 loadCodemodels( cmPath );
567
568 // Restore the working directory
569 wxSetWorkingDirectory( cwd );
570
571 // Workarounds to avoid hang ups on certain errors
572 // These commands have to be called, no matter what is in the spinit file
573 // We have to allow interactive for user-defined signals. Hopefully whatever bug this was
574 // meant to address has gone away in the last 5 years...
575 //Command( "unset interactive" );
576 Command( "set noaskquit" );
577 Command( "set nomoremode" );
578
579 // reset and remcirc give an error if no circuit is loaded, so load an empty circuit at the
580 // start.
581
582 std::vector<char*> lines;
583 lines.push_back( strdup( "*" ) );
584 lines.push_back( strdup( ".end" ) );
585 lines.push_back( nullptr ); // Sentinel.
586
587 m_ngSpice_Circ( lines.data() );
588
589 for( auto line : lines )
590 free( line );
591
592 m_initialized = true;
593}
594
595
596bool NGSPICE::loadSpinit( const std::string& aFileName )
597{
598 if( !wxFileName::FileExists( aFileName ) )
599 return false;
600
601 wxTextFile file;
602
603 if( !file.Open( aFileName ) )
604 return false;
605
606 for( wxString& cmd = file.GetFirstLine(); !file.Eof(); cmd = file.GetNextLine() )
607 Command( cmd.ToStdString() );
608
609 return true;
610}
611
612
613std::string NGSPICE::findCmPath() const
614{
615 const std::vector<std::string> cmPaths =
616 {
617#ifdef __WXMAC__
618 "/Applications/ngspice/lib/ngspice",
619 "Contents/Frameworks",
620 wxStandardPaths::Get().GetPluginsDir().ToStdString() + "/sim/ngspice",
621 wxFileName( wxStandardPaths::Get().GetExecutablePath() ).GetPath().ToStdString() +
622 "/../../../../../Contents/PlugIns/sim/ngspice",
623 "../Plugins/sim/ngspice",
624#endif
625 "../eeschema/ngspice",
626 "../lib/ngspice",
627 "../../lib/ngspice",
628 "lib/ngspice",
629 "ngspice"
630 };
631
632 for( const auto& path : cmPaths )
633 {
634 wxLogTrace( traceNgspice, "ngspice code models search path: %s", path );
635
636 if( wxFileName::FileExists( path + "/spice2poly.cm" ) )
637 {
638 wxLogTrace( traceNgspice, "ngspice code models found in: %s", path );
639 return path;
640 }
641 }
642
643 return std::string();
644}
645
646
647bool NGSPICE::setCodemodelsInputPath( const std::string& aPath )
648{
649 if( !m_ngCM_Input_Path )
650 return false;
651
652 LOCALE_IO c_locale; // ngspice works correctly only with C locale
653
654 m_ngCM_Input_Path( aPath.c_str() );
655
656 return true;
657}
658
659
660bool NGSPICE::loadCodemodels( const std::string& aPath )
661{
662 wxArrayString cmFiles;
663 size_t count = wxDir::GetAllFiles( aPath, &cmFiles );
664
665 for( const auto& cm : cmFiles )
666 Command( fmt::format( "codemodel '{}'", cm.ToStdString() ) );
667
668 return count != 0;
669}
670
671
672int NGSPICE::cbSendChar( char* aWhat, int aId, void* aUser )
673{
674 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
675
676 if( sim->m_reporter )
677 {
678 // strip stdout/stderr from the line
679 if( ( strncasecmp( aWhat, "stdout ", 7 ) == 0 )
680 || ( strncasecmp( aWhat, "stderr ", 7 ) == 0 ) )
681 {
682 aWhat += 7;
683 }
684
685 sim->m_reporter->Report( aWhat );
686 }
687
688 return 0;
689}
690
691
692int NGSPICE::cbSendStat( char *aWhat, int aId, void* aUser )
693{
694 return 0;
695}
696
697
698int NGSPICE::cbBGThreadRunning( NG_BOOL aFinished, int aId, void* aUser )
699{
700 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
701
702 if( sim->m_reporter )
703 sim->m_reporter->OnSimStateChange( sim, aFinished ? SIM_IDLE : SIM_RUNNING );
704
705 return 0;
706}
707
708
709int NGSPICE::cbControlledExit( int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId,
710 void* aUser )
711{
712 // Something went wrong, reload the dll
713 NGSPICE* sim = reinterpret_cast<NGSPICE*>( aUser );
714 sim->m_error = true;
715
716 return 0;
717}
718
719
721{
722 if( m_error )
723 {
724 m_initialized = false;
725 init_dll();
726 }
727}
728
729
731{
732 Command( "destroy all" );
733}
734
735
736bool NGSPICE::m_initialized = false;
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: locale_io.h:49
Execute commands from a file.
Definition: ngspice.h:148
Container for Ngspice simulator settings.
NGSPICE_COMPATIBILITY_MODE GetCompatibilityMode() const
std::vector< std::string > AllVectors() const override final
Return a requested vector with complex values.
Definition: ngspice.cpp:101
ngSpice_Circ m_ngSpice_Circ
Definition: ngspice.h:134
bool Command(const std::string &aCmd) override final
Set a SIMULATOR_REPORTER object to receive the simulation log.
Definition: ngspice.cpp:355
char **(* ngSpice_AllVecs)(char *plotname)
Definition: ngspice.h:127
ngSpice_AllPlots m_ngSpice_AllPlots
Definition: ngspice.h:139
static int cbControlledExit(int aStatus, NG_BOOL aImmediate, NG_BOOL aExitOnQuit, int aId, void *aUser)
Definition: ngspice.cpp:709
int(* ngSpice_Circ)(char **circarray)
Definition: ngspice.h:121
ngSpice_UnlockRealloc m_ngSpice_UnlockRealloc
Definition: ngspice.h:143
char **(* ngSpice_AllPlots)(void)
Definition: ngspice.h:126
bool IsRunning() override final
Execute a Spice command as if it was typed into console.
Definition: ngspice.cpp:348
std::vector< double > GetImaginaryVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with magnitude values.
Definition: ngspice.cpp:192
virtual const std::string GetNetlist() const override final
Cleans simulation data (i.e.
Definition: ngspice.cpp:416
char *(* ngSpice_CurPlot)(void)
Definition: ngspice.h:125
ngSpice_Init m_ngSpice_Init
Definition: ngspice.h:133
void updateNgspiceSettings()
Check a few different locations for codemodel files and returns one if it exists.
Definition: ngspice.cpp:78
ngSpice_Command m_ngSpice_Command
Definition: ngspice.h:135
int(* ngSpice_LockRealloc)(void)
Definition: ngspice.h:129
void(* ngSpice_Init)(SendChar *, SendStat *, ControlledExit *, SendData *, SendInitData *, BGThreadRunning *, void *)
Definition: ngspice.h:118
bool setCodemodelsInputPath(const std::string &aPath)
Load codemodel files from a directory.
Definition: ngspice.cpp:647
wxString GetXAxis(SIM_TYPE aType) const override final
Definition: ngspice.cpp:363
wxString CurrentPlotName() const override final
Definition: ngspice.cpp:95
ngGet_Vec_Info m_ngGet_Vec_Info
Definition: ngspice.h:136
bool m_error
Error flag indicating that ngspice needs to be reloaded.
Definition: ngspice.h:192
ngCM_Input_Path m_ngCM_Input_Path
Definition: ngspice.h:137
std::vector< double > GetPhaseVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with phase values.
Definition: ngspice.cpp:247
virtual ~NGSPICE()
ngSpice_LockRealloc m_ngSpice_LockRealloc
Definition: ngspice.h:142
ngSpice_CurPlot m_ngSpice_CurPlot
Definition: ngspice.h:138
void init_dll()
Definition: ngspice.cpp:422
bool loadSpinit(const std::string &aFileName)
Definition: ngspice.cpp:596
bool Run() override final
Halt the simulation.
Definition: ngspice.cpp:334
bool LoadNetlist(const std::string &aNetlist) override final
Execute the simulation with currently loaded netlist.
Definition: ngspice.cpp:307
static int cbBGThreadRunning(NG_BOOL aFinished, int aId, void *aUser)
Definition: ngspice.cpp:698
std::vector< double > GetGainVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with phase values.
Definition: ngspice.cpp:217
bool Stop() override final
Check if simulation is running at the moment.
Definition: ngspice.cpp:341
int(* ngSpice_Command)(char *command)
Definition: ngspice.h:122
static bool m_initialized
Ngspice should be initialized only once.
Definition: ngspice.h:194
static int cbSendStat(char *what, int aId, void *aUser)
Definition: ngspice.cpp:692
static int cbSendChar(char *what, int aId, void *aUser)
Definition: ngspice.cpp:672
std::vector< double > GetRealVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with imaginary values.
Definition: ngspice.cpp:159
char *(* ngCM_Input_Path)(const char *path)
Definition: ngspice.h:124
std::vector< std::string > GetSettingCommands() const override final
Return current SPICE netlist used by the simulator.
Definition: ngspice.cpp:392
std::string m_netlist
Current netlist.
Definition: ngspice.h:196
ngSpice_AllVecs m_ngSpice_AllVecs
Definition: ngspice.h:140
int(* ngSpice_UnlockRealloc)(void)
Handle to DLL functions.
Definition: ngspice.h:130
pvector_info(* ngGet_Vec_Info)(char *vecname)
Definition: ngspice.h:123
ngSpice_Running m_ngSpice_Running
Definition: ngspice.h:141
void Clean() override final
Cleans simulation data (i.e.
Definition: ngspice.cpp:730
bool(* ngSpice_Running)(void)
Definition: ngspice.h:128
wxDynamicLibrary m_dll
Definition: ngspice.h:145
NGSPICE()
Definition: ngspice.cpp:57
void Init(const SPICE_SETTINGS *aSettings=nullptr) override final
Point out the model that will be used in future simulations.
Definition: ngspice.cpp:88
bool Attach(const std::shared_ptr< SIMULATION_MODEL > &aModel, const wxString &aSimCommand, unsigned aSimOptions, const wxString &aInputPath, REPORTER &aReporter) override final
Load a netlist for the simulation.
Definition: ngspice.cpp:277
void validate()
Definition: ngspice.cpp:720
std::string findCmPath() const
Send additional search path for codemodels to ngspice.
Definition: ngspice.cpp:613
bool loadCodemodels(const std::string &aPath)
Definition: ngspice.cpp:660
std::vector< COMPLEX > GetComplexVector(const std::string &aName, int aMaxLen=-1) override final
Return a requested vector with real values.
Definition: ngspice.cpp:129
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:71
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
virtual void OnSimStateChange(SIMULATOR *aObject, SIM_STATE aNewState)=0
virtual bool Attach(const std::shared_ptr< SIMULATION_MODEL > &aModel, const wxString &aSimCommand, unsigned aSimOptions, const wxString &aInputPath, REPORTER &aReporter)
Point out the model that will be used in future simulations.
Definition: simulator.h:61
Special netlist exporter flavor that allows one to override simulation commands.
bool GetNetlist(const wxString &aCommand, unsigned aOptions, OUTPUTFORMATTER *aFormatter, REPORTER &aReporter)
Storage for simulator specific settings.
std::shared_ptr< SPICE_SETTINGS > & Settings()
Return the simulator configuration settings.
SIMULATOR_REPORTER * m_reporter
< Reporter object to receive simulation log.
Implement an OUTPUTFORMATTER to a memory buffer.
Definition: richio.h:433
const std::string & GetString()
Definition: richio.h:456
The common library.
static const wxChar *const traceNgspice
Flag to enable debug output of Ngspice simulator.
Definition: ngspice.cpp:54
bool NG_BOOL
Definition: ngspice.h:46
SIM_TYPE
< Possible simulation types
Definition: sim_types.h:32
@ ST_SP
Definition: sim_types.h:43
@ ST_TRAN
Definition: sim_types.h:42
@ ST_NOISE
Definition: sim_types.h:37
@ ST_AC
Definition: sim_types.h:34
@ ST_DC
Definition: sim_types.h:35
@ ST_FFT
Definition: sim_types.h:44
@ SIM_IDLE
@ SIM_RUNNING