Accessing the results of the simulation via python scripting

I think I am doing something basic wrong. I have a smash file with multiple simulations and want to run things in python to avoid error.

-- coding: utf-8 --

import s4l_v1.document as document
import XSimulator as simulator
import s4l_v1.simulation as simulation

file= 'C:\Users\will\Documents\EMS2N2_EFieldSims\RedoneSims\XYZBodyModels\XYZBodyModels.smash'
print('Hello strange world')

nsims = simulator.NumberOfSimulations()
print 'Running ', nsims,' simulations'
sims = list(document.AllSimulations)

for n in range(nsims):
sim = simulator.GetSimulation(n)
test = sim.HasResults(1)

if test == 1:
	print 'Doing analysis'
	#Get the results
	res = sim.Results()

The list of simulations does nothing, and the last statement returns an error. Though the examples I found on the forum indicate it should return an extractor, that I could use to do things with....

Hello strange world
Running 32 simulations
Doing analysis
Traceback (most recent call last):
File "C:\Users\will\Documents\EMS2N2_EFieldSims\RedoneSims\XYZBodyModels\", line 25, in <module>
res = sim.Results()
AttributeError: 'XObject' object has no attribute or child object named 'Results'

If I understand the API browser then the simulation should be an ElectroQuasiStaticSimulation object, and the Results() method should give me an extractor, with the field sensor data in it......

Any help appreciated.


Try this instead. I normally use document.AllSimulations to get simulations and their results, not XSimulator. And you don't need to turn that into a list since it's already iterable and can be indexed either by name or index (document.AllSimulations[0] or ['Simulation Name'].

nsims = simulator.NumberOfSimulations()
print 'Running ', nsims,' simulations'

for sim in document.AllSimulations:
     if sim.HasResults() == True:
          print 'Doing analysis'
          #Get the results
          res = sim.Results()

Inside postpro you can also do what you want and then right right the final output (for example, a slice field viewer) and select 'To Python..' This would give a good starting point to know how to extract data and fields.

Thanks so much, I will give it a try,

I tried your method, and it is the same as when I tried the other way, it fails on the last line when I try to get the results. Is it different for quasi static simulations? I know the results are there because I can do it by hand.

I tell a lie, it did work. Thanks so much! If you get the sim from the simulator you cannot access the results! It should be the same object so I am not sure hwat is going on there.

As I understand it (and I might be misremembering), the Python interface that you find under s4l_v1 (s4l_v1.document, s4l_v1.AllSimulations, etc..) should be used when possible as the ones that start with X (XSimulator, XPostProcessing) are rather old and might not have been updated. Unfortunately, it seems that not all the functionality from these X* have been ported to s4l_v1.

Not sure what you're trying to do, but some sample code to extract the field and data is below (should apply to anything with a rectilinear grid, but it's from Acoustic simulations):

sim = document.AllSimulations[simulation_idx]
simulation_extractor = sim.Results()
sim_sensor_extractor = simulation_extractor["Overall Field"] # Sensor Name
sim_field_extractor = sim_sensor_extractor.Outputs["Intensity"] # Field Name
d_sim = sim_field_extractor.Data
out = d_sim_ref.Field(0) # 3D Field is extracted as a 1D array. 
# 0 corresponds to the snapshot (typically, time or frequency) 
# If you need this as a 3D array then use 
# out_3d = np.reshape(out, grid_dims, order='F')	
# once you have 'grid_dims' which I show how to get below
# important to remember order = 'F' because of the way that 3D arrays are unrolled into 1D (Fortran style) 
sim_field_extractor.Update() # Just to be safe, I add this update step a few more times than needed

# Get grid: axes, dimensions
x = d_sim.Grid.XAxis
y = d_sim.Grid.YAxis
z = d_sim.Grid.ZAxis

# Careful: Simulations in S4L have grids defined at the nodes, and values (the field) defined at cell centers
# Therefore if you want the 'grid' used for the values in your field, you'll need to probably get the midpoints of the grid and reduce the grid dimensions by one in each direction. 
# Something like: x_mid = (x[1:]+x[:-1]) / 2

grid = d_sim_ref.Grid.Dimensions