Scripted transient thermal: how to extract end-of-step temperatures? (ThermoSensorExtractor.Results is None)
-
I’m running everything via Python scripts (no UI). To reproduce liver motion, I move the organ geometry at each time step in both the EMLF simulation (to generate Phantom_Liver_i / Overall Field) and the transient thermal simulation. My goal is to use the final temperature at step i as the initial condition of step i+1—but I can’t retrieve temperatures programmatically.
Current behavior (brief):
Thermal sim runs, voxels created, .sab saved.
I attach a thermal.TransientFieldSensorSettings() (Temperature) to Overall Field, enable available store/write flags, and set snapshot times (0–5 s) on both Setup and sensor.
In simulation.Results(), I see ThermoSensorExtractor, but after Update() its Results is always None.
Log excerpt:
[DBG] ThermoExtractor ...
[DBG] Overall Field.Results type=<class 'NoneType'>I tried various other methods to obtain the temperature, but they all failed.
Questions:
In the current API, what is the supported script-only method to obtain temperature values (per entity or field) at the last snapshot of a transient run?
Which exact settings/flags are required so that ThermoSensorExtractor (or an alternative extractor) returns non-None results?
Is there a minimal example showing how to:
attach the correct temperature sensor(s) to the right component,
trigger result generation,
and export the final-step temperatures for reuse as the next step’s initial condition?
I can share the script, logs, and .sab files if helpful.
Thank you!Best regards
-
This is a simplified example (partly generated using the "To Python" action in the context menu). The example does the following
- creates an EM simulation as heat source
- creates a thermal simulation
- creates a "continue" simulation using the thermal distribution from the first simulation
- extracts the temperature field
from pathlib import Path import numpy as np import s4l_v1.document as document import s4l_v1.materials.database as database import s4l_v1.model as model import s4l_v1.simulation.emfdtd as emfdtd import s4l_v1.simulation.thermal as thermal import s4l_v1.units as units from s4l_v1 import Unit def create_emfdtd_simulation(): simulation = emfdtd.Simulation() entity__lines1 = model.AllEntities()["Edge Source"] entity__sphere1 = model.AllEntities()["Sphere 1"] material_settings = simulation.AddMaterialSettings([entity__sphere1]) simulation.LinkMaterialWithDatabase(material_settings, database["IT'IS LF 5.0"]["Liver"]) edge_source_settings = emfdtd.EdgeSourceSettings() simulation.Add(edge_source_settings, [entity__lines1]) edge_sensor_settings = emfdtd.EdgeSensorSettings() simulation.Add(edge_sensor_settings, [entity__lines1]) automatic_grid_settings = [x for x in simulation.AllSettings if isinstance(x, emfdtd.AutomaticGridSettings) and x.Name == "Automatic"][0] simulation.Add(automatic_grid_settings, [entity__lines1, entity__sphere1]) automatic_voxeler_settings = [x for x in simulation.AllSettings if isinstance(x, emfdtd.AutomaticVoxelerSettings) and x.Name == "Automatic Voxeler Settings"][0] simulation.Add(automatic_voxeler_settings, [entity__lines1, entity__sphere1]) simulation.UpdateAllMaterials() simulation.UpdateGrid() return simulation def create_thermal_transient(em_overall_field): simulation = thermal.TransientSimulation() entity__sphere1 = model.AllEntities()["Sphere 1"] material_settings = simulation.AddMaterialSettings([entity__sphere1]) simulation.LinkMaterialWithDatabase(material_settings, database["IT'IS LF 5.0"]["Liver"]) initial_condition_settings = thermal.InitialConditionSettings() initial_condition_settings.InitialTemperature = 37.0, Unit("C") simulation.Add(initial_condition_settings, [entity__sphere1]) transient_heat_source_settings = simulation.AddHeatSourceSettings([em_overall_field]) automatic_grid_settings = [x for x in simulation.AllSettings if isinstance(x, thermal.AutomaticGridSettings) and x.Name == "Automatic"][0] simulation.Add(automatic_grid_settings, [entity__sphere1]) automatic_voxeler_settings = [x for x in simulation.AllSettings if isinstance(x, thermal.AutomaticVoxelerSettings) and x.Name == "Automatic Voxeler Settings"][0] simulation.Add(automatic_voxeler_settings, [entity__sphere1]) simulation.UpdateAllMaterials() simulation.UpdateGrid() return simulation if __name__ == "__main__": # create dummy model line = model.CreatePolyLine([model.Vec3(0,0,20), model.Vec3(5,0,20)]) line.Name = "Edge Source" sphere = model.CreateSolidSphere(model.Vec3(0,0,0), radius=15) sphere.Name = "Sphere 1" sphere.MaterialName = "Liver" # create heat source em_sim = create_emfdtd_simulation() em_sim.Name = "EM Heat Source" document.AllSimulations.Add( em_sim ) # setup initial thermal simulation th_sim = create_thermal_transient(em_sim.AllComponents["Overall Field"]) th_sim.Name = "T Initial Simulation" document.AllSimulations.Add( th_sim ) # setup simulation using result from previous simulation th_continue = th_sim.CloneWithDiscretization() th_continue.Name = "T Continue Simulation" init_cond_settings = th_continue.GlobalInitialConditionSettings init_cond_settings.InitializationOptions = init_cond_settings.InitializationOptions.enum.ContinueSimulation init_cond_settings.InputSensor = "Overall Field" init_cond_settings.InputSimulation = th_sim.Name document.AllSimulations.Add( th_continue ) # run simulations project_file_path = Path.home() / "t_continue.smash" em_sim.CreateVoxels(project_file_path) em_sim.RunSimulation() th_sim.CreateVoxels(project_file_path) th_sim.RunSimulation() th_continue.CreateVoxels(project_file_path) th_continue.RunSimulation() # extract some results th_continue_extractor = th_continue.Results() th_sensor_extractor = th_continue_extractor["Overall Field"] th_sensor_extractor.Outputs["T(x,y,z,t)"].Update() field = th_sensor_extractor.Outputs["T(x,y,z,t)"].Data print(field) -
Thank you for your response.
Additionally, I would appreciate it if you could tell me how to output the temperatures from the thermal simulation results to text files, spreadsheets, Excel, etc.
Ideally, I would like to be able to extract the temperatures at specified coordinates or average values for each model (Lung, Spleen, etc.).
If specifying the model is difficult, it would also be acceptable to obtain the post-simulation temperature at specified coordinates.