Skip to main content

PsimSimulate

Usage

psim.PsimSimulate();

Python Help

py.help(psim.PsimSimulate)

Python def

def PsimSimulate(self, schFilePath_or_Obj, graphFilePath, **kwargs) -> PSIM_result:
res = None
try:
simview_flag = 0
NameValueList, simview_flag = PSIM.__private_kwargs_to_List(self, simview_flag, **kwargs)

res = PSIM.__private_Simulate2(self, 0, schFilePath_or_Obj, graphFilePath, simview_flag, NameValueList)
except Exception as e:
print(f"Error: {e}")
return res

def __private_kwargs_to_List(self, simview_flag, **kwargs):
res = None
try:
NameValueList = []
for key, value in kwargs.items():
if key.lower() == "simview":
try:
if "." in str(value):
i1 = int(float(value))
else:
i1 = int(value)
except (ValueError, TypeError) as e:
i1 = 1

if( i1 == -1):
simview_flag = 1 + 4 # Don't Write graph and don't run simview
elif ( i1 == 0):
simview_flag = 1 # Write graph but don't run simview
else:
simview_flag = 0 # Write graph and run simview

else:
NameValueList.append(key)
NameValueList.append(str(value))
except Exception as e:
print(f"Error: {e}")
return NameValueList, simview_flag

def __private_Simulate2(self, simType, schFilePath_or_Obj, graphFilePath, simview_flag, NameValueList) -> PSIM_result:
#simType: 0:PSIM 11:HYPERSPICE 12:LT_SPICE
result = PSIM_result(self)

try:
if not self.IsValid():
result.ErrorMessage = "PSIM object was not loaded."
result.Result = 0;
result.IsError = 1;
return result;

#simview_flag = 0 # RUN_SIMVIEW and WRITE_GRAPH
error_message = ""

sch_closeFile = False
schHandle = 0
schFilePath = ""
#is schFilePath a filePath or schematicID?
if isinstance(schFilePath_or_Obj, PSIM_schematic):
schHandle = schFilePath_or_Obj.value
elif isinstance(schFilePath_or_Obj, str):
schFilePath = schFilePath_or_Obj
SimOpenSchematicFileW = getattr(self.psimHandle, "SimOpenSchematicFileW")
if not SimOpenSchematicFileW:
raise AttributeError(self.VersionErrorMessage)

SimOpenSchematicFileW.restype = ctypes.c_int
# int SimOpenSchematicFileW(const wchar_t * szFileName, UINT nFlag)
schHandle = SimOpenSchematicFileW(ctypes.c_wchar_p(schFilePath), ctypes.c_int (1)); #returns 0 on error
if schHandle == 0 :
result.ErrorMessage = "Unable to open schematic file " + schFilePath
result.Result = 0;
result.IsError = 1;
return result;
sch_closeFile =True
elif schFilePath_or_Obj is None:
print("in Simulate function, schFilePath_or_Obj is None")
else:
print("in Simulate function, schFilePath_or_Obj is of an unknown type")


# Convert Python list to array of wchar_t*
# w_strings = [ctypes.c_wchar_p(s) for s in NameValueList]
# w_array = (ctypes.c_wchar_p * len(w_strings))(*w_strings)
# NameValList_size = len(NameValueList)


array_type = ctypes.c_wchar_p * len(NameValueList)
w_array = array_type()
i = 0
for item in NameValueList:
w_array[i] = ctypes.c_wchar_p(str(item))
i = i+1
NameValList_size = len(NameValueList)
#[ctypes.c_wchar_p(s) for s in my_list]

Simulation_Init = None
if(simType == 0):
# # This is only for PsimSimulate
# int EXPORT SimulationInit2(int nID, DWORD dwOptions, const wchar_t* szSimviewPath, wchar_t** pszError, wchar_t* arr[], int size)
# Define the function prototype
Simulation_Init = getattr(self.psimHandle, "SimulationInit2")
if not Simulation_Init:
raise AttributeError(self.VersionErrorMessage)
Simulation_Init.argtypes = [
ctypes.c_int, # nID : schematic file identifier
ctypes.c_uint32, # dwOptions (DWORD)
ctypes.c_wchar_p, # szSimviewPath
ctypes.POINTER(ctypes.c_wchar_p), # pszError
ctypes.POINTER(ctypes.c_wchar_p),
ctypes.c_int
]
Simulation_Init.restype = ctypes.c_int
# call Simulation_Init
dwOptions = simview_flag
pszError = ctypes.c_wchar_p()
nThreadIndex = Simulation_Init(schHandle, ctypes.c_uint32(dwOptions), ctypes.c_wchar_p(graphFilePath), ctypes.byref(pszError), w_array, NameValList_size)
error_message = pszError.value

elif(simType == 11):
# # This is only for HyperSpiceSimulate
# int EXPORT Simulation2_HyperSpice(int nID, DWORD dwOptions, const wchar_t* szSimviewPath, wchar_t** pszError)
# Define the function prototype
Simulation_HyperSpice = getattr(self.psimHandle, "Simulation2_HyperSpice")
if not Simulation_HyperSpice:
raise AttributeError(self.VersionErrorMessage)
Simulation_HyperSpice.argtypes = [
ctypes.c_int, # nID : schematic file identifier
ctypes.c_uint32, # dwOptions (DWORD)
ctypes.c_wchar_p, # szSimviewPath
ctypes.POINTER(ctypes.c_wchar_p), # pszError
ctypes.POINTER(ctypes.c_wchar_p),
ctypes.c_int
]
Simulation_HyperSpice.restype = ctypes.c_int
# call Simulation_Init
dwOptions = simview_flag
pszError = ctypes.c_wchar_p()
nThreadIndex = Simulation_HyperSpice(schHandle, ctypes.c_uint32(dwOptions), ctypes.c_wchar_p(graphFilePath), ctypes.byref(pszError), w_array, NameValList_size)
error_message = pszError.value

elif(simType == 12):
# # This is only for LTSpiceSimulate
# int Simulation2_LTSpice(int nID, DWORD dwOptions, const wchar_t* szSimviewPath, wchar_t* pszError, wchar_t** pszOutputFilePath)
# Define the function prototype
Simulation_LTSpice = getattr(self.psimHandle, "Simulation2_LTSpice")
if not Simulation_LTSpice:
raise AttributeError(self.VersionErrorMessage)
Simulation_LTSpice.argtypes = [
ctypes.c_int, # nID : schematic file identifier
ctypes.c_uint32, # dwOptions (DWORD)
ctypes.c_wchar_p, # szSimviewPath
ctypes.POINTER(ctypes.c_wchar_p), # pszError
ctypes.POINTER(ctypes.c_wchar_p),
ctypes.c_int,
ctypes.POINTER(ctypes.c_wchar_p) # pszOutputFilePath
]
Simulation_LTSpice.restype = ctypes.c_int
dwOptions = simview_flag
pszError = ctypes.c_wchar_p()
pszOutputFilePath = ctypes.c_wchar_p()
sim_result = Simulation_LTSpice(schHandle, ctypes.c_uint32(dwOptions), ctypes.c_wchar_p(graphFilePath), ctypes.byref(pszError), w_array, NameValList_size, ctypes.byref(pszOutputFilePath))
error_message = pszError.value
if(pszOutputFilePath.value):
graphFilePath = pszOutputFilePath.value





if((simType == 0) or (simType == 11)):
if (nThreadIndex == 0):
if error_message:
result.ErrorMessage = "Simulation failed for file: " + schFilePath + "\n" + error_message
else:
result.ErrorMessage = "Simulation failed for file: " + schFilePath
result.Result = 0;
result.IsError = 1;
return result;
elif(simType == 12):
#LT_Spice Simulation_Init returns the result flag not the ThreadIndex
nThreadIndex = 0;



if(simType == 0):
# # This is only for PsimSimulate
Thread_Simulation_Do = getattr(self.psimHandle, "Thread_Simulation_Do")
if not Thread_Simulation_Do:
raise AttributeError(self.VersionErrorMessage)
Thread_Simulation_Do(nThreadIndex)


if((simType == 0) or (simType == 11)):
#LT_Spice function returns sim_result not nThreadIndex, PsimSimulation and HyperSpice return ThreadIndex. We need to get sim_result from ThreadIndex
GetSimulationResult = getattr(self.psimHandle, "GetSimulationResult")
if not GetSimulationResult:
raise AttributeError(self.VersionErrorMessage)
GetSimulationResult.restype = ctypes.c_int
sim_result = GetSimulationResult(ctypes.c_int(nThreadIndex))
while sim_result == 4: #Simulation still in progress
sim_result = GetSimulationResult(ctypes.c_int(nThreadIndex))


result.Result = sim_result;

if(sim_result == 1):
# get a pointer to C++ graph object
nFlag = 0;


GetSimulationGraphRef = getattr(self.psimHandle, "GetSimulationGraphRef")
if not GetSimulationGraphRef:
raise AttributeError(self.VersionErrorMessage)
GetSimulationGraphRef.restype = ctypes.c_int


Graph_GetColCount = getattr(self.psimHandle, "Graph_GetColCount")
if not Graph_GetColCount:
raise AttributeError(self.VersionErrorMessage)

Graph_GetRowCount = getattr(self.psimHandle, "Graph_GetRowCount")
if not Graph_GetRowCount:
raise AttributeError(self.VersionErrorMessage)

Graph_GetColInfo = getattr(self.psimHandle, "Graph_GetColInfo")
if not Graph_GetColInfo:
raise AttributeError(self.VersionErrorMessage)


Graph_GetColCount.restype = ctypes.c_int
Graph_GetRowCount.restype = ctypes.c_int

Graph_GetColInfo.argtypes = [ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.POINTER(ctypes.POINTER(ctypes.c_wchar)), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.POINTER(ctypes.c_double)), ctypes.POINTER(ctypes.POINTER(ctypes.c_byte))]
Graph_GetColInfo.restype = ctypes.c_int

pnRows = ctypes.c_int(0)
pnIncDec = ctypes.c_int(0)


if((simType == 0) or (simType == 11)):
grf = GetSimulationGraphRef(ctypes.c_int(nThreadIndex))
elif(simType == 12):
# LTSpice
grf = PSIM.__private_OpenGraphFile(self, graphFilePath)

if(grf > 0):
result.graphHandle = grf

# int Graph_GetColCount(int nGraphRef)
numberOfCol = Graph_GetColCount(ctypes.c_int(grf))
#print("Number of curves in this file: ", numberOfCol)

# int Graph_GetRowCount(int nGraphRef)
numberOfRows = Graph_GetRowCount(ctypes.c_int(grf))
#print("Number of rows for each curve: ", numberOfRows)


# BOOL Graph_GetColInfo(int nGraphRef, int nFlag, int nColIndex, LPTSTR * ptrName, int * pnRows, int * pnIncDec, double ** ppValues, BYTE ** ppValidState)
# ptrName : name of the curve
# ppValues: values
# ppValidState: flag for each value 0:missing 1:valid 2:invalid
# pnRows : number of rows


for col in range(0 , numberOfCol):
# read one curve at a time
#print("Reading curve number ", col+1)

ppValues1_B = (ctypes.c_double * numberOfRows)()
ppValidState1_B = (ctypes.c_byte * numberOfRows)()

ppValues = ctypes.cast(ppValues1_B, ctypes.POINTER(ctypes.c_double))
ppValidState = ctypes.cast(ppValidState1_B, ctypes.POINTER(ctypes.c_byte))

ptrName1 = (ctypes.c_wchar * 100)()
ptrName = ctypes.cast(ptrName1, ctypes.POINTER(ctypes.c_wchar))

b = Graph_GetColInfo(ctypes.c_int(grf), ctypes.c_int (0), ctypes.c_int(col), ctypes.byref(ptrName), ctypes.byref(pnRows), ctypes.byref(pnIncDec), ctypes.byref(ppValues), ctypes.byref(ppValidState))


ptrName3 = ctypes.cast(ptrName, ctypes.POINTER(ctypes.c_wchar * 100))

#print(ptrName3.contents.value)
#print(ppValues[10])


crv = PSIM_curve(pnRows.value, ptrName3.contents.value, ppValues, ppValidState)
result.Graph.add_curve(crv)

result.ErrorMessage = error_message
result.IsError = 0
else:
result.IsError = 1
if(error_message and (len(error_message) > 0)):
result.ErrorMessage = error_message + "\n"

#int Get_SimErrorMessages(int nThreadIndex, int& nErrorCount, int& nErrorSize, wchar_t* ptrErrors)
Get_SimErrorMessages = getattr(self.psimHandle, "Get_SimErrorMessages")
if not Get_SimErrorMessages:
raise AttributeError(self.VersionErrorMessage)

Get_SimErrorMessages.argtypes = [
ctypes.c_int, # nThreadIndex
ctypes.POINTER(ctypes.c_int), # Reference to nErrorCount
ctypes.POINTER(ctypes.c_int), # Reference to nErrorSize
ctypes.POINTER(ctypes.c_wchar) # ptrErrors
]
Get_SimErrorMessages.restype = ctypes.c_int

nErrorCount = ctypes.c_int(0)
nErrorSize = ctypes.c_int(0)

ret = Get_SimErrorMessages(ctypes.c_int(nThreadIndex), ctypes.byref(nErrorCount), ctypes.byref(nErrorSize), None)
if((nErrorCount.value > 0) and (nErrorSize.value > 0)):
ptrErrors = ctypes.create_unicode_buffer(nErrorSize.value+100) # Allocate memory for ptrErrors, wchar_t
ret = Get_SimErrorMessages(ctypes.c_int(nThreadIndex), ctypes.byref(nErrorCount), ctypes.byref(nErrorSize), ptrErrors)
result.ErrorMessage += ptrErrors.value


if sch_closeFile:
CloseSchematicFile = getattr(self.psimHandle, "SimCloseSchematicFile")
if not CloseSchematicFile:
raise AttributeError(self.VersionErrorMessage)

CloseSchematicFile.restype = ctypes.c_int
# int SimCloseSchematicFile(int nSchematicID)
res = CloseSchematicFile(schHandle); #returns 0 on error

except Exception as e:
print(f"Error: {e}")
result.IsError = 1
result.Result = 0
result.ErrorMessage += f"Error: {e}"

return result;