How to create a simulation#

This tutorial demonstrates how to create a simulation.

What is a simulation?#

A simulation contains selected sensors, sources to model ray-trace in space.

Prerequisites#

Perform imports#

[1]:
from pathlib import Path

from ansys.speos.core import GeoRef, Project, Speos
from ansys.speos.core.simulation import SimulationInteractive, SimulationInverse

Define constants#

The constants help ensure consistency and avoid repetition throughout the example.

[2]:
HOSTNAME = "localhost"
GRPC_PORT = 50098  # Be sure the Speos GRPC Server has been started on this port.
USE_DOCKER = True  # Set to False if you're running this example locally as a Notebook.
SOURCE_NAME = "Surface.1"
SENSOR_NAME = "Irradiance.1"

Model Setup#

Load assets#

The assets used to run this example are available in the PySpeos repository on GitHub.

Note: Make sure you have downloaded simulation assets and set assets_data_path to point to the assets folder.

[3]:
if USE_DOCKER:  # Running on the remote server.
    assets_data_path = Path("/app") / "assets"
else:
    assets_data_path = Path("/path/to/your/download/assets/directory")

Connect to the RPC Server#

This Python client connects to a server where the Speos engine is running as a service. In this example, the server and client are the same machine.

[4]:
speos = Speos(host="localhost", port=50098)

Create a new project#

The only way to create a simulation using the core layer, is to create it from a project. The Project class is instantiated by passing a Speos instance.

[5]:
p = Project(speos=speos)
print(p)
{
    "name": "",
    "description": "",
    "metadata": {},
    "part_guid": "",
    "sources": [],
    "sensors": [],
    "simulations": [],
    "materials": [],
    "scenes": []
}

Prepare prerequisites#

Create the necessary elements for a simulation: Sensor, source, root part, optical property are prerequisites.

Prepare the root part#

[6]:
root_part = p.create_root_part()
root_part.create_body(name="Body.1").create_face(name="Face.1").set_vertices(
    [0, 1, 2, 0, 2, 2, 1, 2, 2]
).set_facets([0, 1, 2]).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
root_part.commit()
[6]:
<ansys.speos.core.part.Part at 0x7f5b9ada7850>

Prepare an optical property#

Create Optical Property

[7]:
opt_prop = p.create_optical_property("Material.1")
opt_prop.set_volume_opaque().set_surface_mirror()
[7]:
<ansys.speos.core.opt_prop.OptProp at 0x7f5b9ada7040>

Choose the geometry for this optical property : Body.1

[8]:
opt_prop.set_geometries(geometries=[GeoRef.from_native_link(geopath="Body.1")])
opt_prop.commit()
[8]:
<ansys.speos.core.opt_prop.OptProp at 0x7f5b9ada7040>

Prepare an irradiance sensor#

[9]:
sensor1 = p.create_sensor(name=SENSOR_NAME)
# set type to colorimetric or spectral so that the sensor can be used both in
# direct and inverse simulation
sensor1.set_type_colorimetric()
sensor1.commit()
[9]:
<ansys.speos.core.sensor.SensorIrradiance at 0x7f5b9ada6ef0>

Prepare a surface source#

[10]:
source1 = p.create_source(name=SOURCE_NAME)
source1.set_exitance_constant(geometries=[(GeoRef.from_native_link(geopath="Body.1/Face.1"), True)])
# define a spectrum which is not monochromatic so it can be used in both direct and inverse
# simulation
source1.set_spectrum().set_blackbody()
source1.commit()
[10]:
<ansys.speos.core.source.SourceSurface at 0x7f5b95704460>

Create a simulation#

[11]:
simulation1 = p.create_simulation(name="Simulation.1")
simulation1.set_sensor_paths([SENSOR_NAME]).set_source_paths([SOURCE_NAME])
print(simulation1)
simulation1.commit()
print(simulation1)
local: {
    "name": "Simulation.1",
    "sensor_paths": [
        "Irradiance.1"
    ],
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "metadata": {},
    "simulation_guid": "",
    "simulation": {
        "direct_mc_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 100,
            "weight": {
                "minimum_energy_percentage": 0.005
            },
            "dispersion": true,
            "colorimetric_standard": "CIE_1931",
            "fast_transmission_gathering": false,
            "ambient_material_uri": "",
            "stop_condition_rays_number": "200000",
            "automatic_save_frequency": 1800
        },
        "name": "Simulation.1",
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.1",
        "job_type": "CPU"
    }
}
{
    "name": "Simulation.1",
    "metadata": {
        "UniqueId": "a25508ec-fd26-4826-ab61-82275f9370ec"
    },
    "simulation_guid": "8a3431ee-8140-47a1-963f-5c9f9eb32f61",
    "sensor_paths": [
        "Irradiance.1"
    ],
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "simulation": {
        "direct_mc_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 100,
            "weight": {
                "minimum_energy_percentage": 0.005
            },
            "dispersion": true,
            "colorimetric_standard": "CIE_1931",
            "fast_transmission_gathering": false,
            "ambient_material_uri": "",
            "stop_condition_rays_number": "200000",
            "automatic_save_frequency": 1800
        },
        "name": "Simulation.1",
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.1",
        "job_type": "CPU"
    }
}

Set simulation characteristics#

Simulation is defined with the same default values as the GUI speos.

If the user would like to modify the simulation characteristics, it is possible to do so by setting the simulation characteristics as below.

[12]:
simulation2_direct = p.create_simulation(name="Simulation.2")
simulation2_direct.set_ambient_material_file_uri(
    uri=str(assets_data_path / "AIR.material")
).set_colorimetric_standard_CIE_1964().set_weight_none().set_geom_distance_tolerance(
    0.01
).set_max_impact(200).set_dispersion(False)
simulation2_direct.set_sensor_paths([SENSOR_NAME]).set_source_paths([SOURCE_NAME]).commit()
print(simulation2_direct)
{
    "name": "Simulation.2",
    "metadata": {
        "UniqueId": "fb1f9c9b-e574-413f-8c7d-ae78b1e74904"
    },
    "simulation_guid": "6cc9917f-ed0f-4a18-b65a-00405b87714a",
    "sensor_paths": [
        "Irradiance.1"
    ],
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "simulation": {
        "direct_mc_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 200,
            "colorimetric_standard": "CIE_1964",
            "ambient_material_uri": "/app/assets/AIR.material",
            "dispersion": false,
            "fast_transmission_gathering": false,
            "stop_condition_rays_number": "200000",
            "automatic_save_frequency": 1800
        },
        "name": "Simulation.2",
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.2",
        "job_type": "CPU"
    }
}

Read information#

Read simulation information

[13]:
print(simulation1)
{
    "name": "Simulation.1",
    "metadata": {
        "UniqueId": "a25508ec-fd26-4826-ab61-82275f9370ec"
    },
    "simulation_guid": "8a3431ee-8140-47a1-963f-5c9f9eb32f61",
    "sensor_paths": [
        "Irradiance.1"
    ],
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "simulation": {
        "direct_mc_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 100,
            "weight": {
                "minimum_energy_percentage": 0.005
            },
            "dispersion": true,
            "colorimetric_standard": "CIE_1931",
            "fast_transmission_gathering": false,
            "ambient_material_uri": "",
            "stop_condition_rays_number": "200000",
            "automatic_save_frequency": 1800
        },
        "name": "Simulation.1",
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.1",
        "job_type": "CPU"
    }
}

Read project information

[14]:
print(p)
{
    "part_guid": "c8cf75f3-e670-4744-9e6c-fe5d8702f90b",
    "sources": [
        {
            "name": "Surface.1",
            "metadata": {
                "UniqueId": "4a7f2163-5989-4b8c-839b-0e78b842db78"
            },
            "source_guid": "3a515c14-4cad-4cd9-8ccd-b2fc8222ca6b",
            "description": "",
            "source": {
                "name": "Surface.1",
                "surface": {
                    "luminous_flux": {
                        "luminous_value": 683.0
                    },
                    "intensity_guid": "42f309ac-57b9-4a6a-b59a-be0c0d22a63d",
                    "exitance_constant": {
                        "geo_paths": [
                            {
                                "geo_path": "Body.1/Face.1",
                                "reverse_normal": true
                            }
                        ]
                    },
                    "spectrum_guid": "64007b26-4132-46d2-8bb2-8183f3b15321",
                    "intensity": {
                        "name": "Surface.1.Intensity",
                        "cos": {
                            "N": 1.0,
                            "total_angle": 180.0
                        },
                        "description": "",
                        "metadata": {}
                    },
                    "spectrum": {
                        "name": "Surface.1.Spectrum",
                        "blackbody": {
                            "temperature": 2856.0
                        },
                        "description": "",
                        "metadata": {}
                    }
                },
                "description": "",
                "metadata": {}
            }
        }
    ],
    "sensors": [
        {
            "name": "Irradiance.1",
            "metadata": {
                "UniqueId": "a37bcc6e-1adc-4acf-9bbd-df0fb7227628"
            },
            "sensor_guid": "a3147c78-0e05-4d85-9b7b-dccfd53c3d4f",
            "description": "",
            "result_file_name": "",
            "sensor": {
                "irradiance_sensor_template": {
                    "sensor_type_colorimetric": {
                        "wavelengths_range": {
                            "w_start": 400.0,
                            "w_end": 700.0,
                            "w_sampling": 13
                        }
                    },
                    "illuminance_type_planar": {},
                    "dimensions": {
                        "x_start": -50.0,
                        "x_end": 50.0,
                        "x_sampling": 100,
                        "y_start": -50.0,
                        "y_end": 50.0,
                        "y_sampling": 100
                    },
                    "axis_system": [
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0,
                        0.0,
                        0.0,
                        0.0,
                        1.0
                    ],
                    "layer_type_none": {},
                    "ray_file_type": "RayFileNone",
                    "integration_direction": []
                },
                "name": "Irradiance.1",
                "description": "",
                "metadata": {}
            }
        }
    ],
    "simulations": [
        {
            "name": "Simulation.1",
            "metadata": {
                "UniqueId": "a25508ec-fd26-4826-ab61-82275f9370ec"
            },
            "simulation_guid": "8a3431ee-8140-47a1-963f-5c9f9eb32f61",
            "sensor_paths": [
                "Irradiance.1"
            ],
            "source_paths": [
                "Surface.1"
            ],
            "description": "",
            "simulation": {
                "direct_mc_simulation_template": {
                    "geom_distance_tolerance": 0.01,
                    "max_impact": 100,
                    "weight": {
                        "minimum_energy_percentage": 0.005
                    },
                    "dispersion": true,
                    "colorimetric_standard": "CIE_1931",
                    "fast_transmission_gathering": false,
                    "ambient_material_uri": "",
                    "stop_condition_rays_number": "200000",
                    "automatic_save_frequency": 1800
                },
                "name": "Simulation.1",
                "description": "",
                "metadata": {},
                "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
                "simulation_path": "Simulation.1",
                "job_type": "CPU"
            }
        },
        {
            "name": "Simulation.2",
            "metadata": {
                "UniqueId": "fb1f9c9b-e574-413f-8c7d-ae78b1e74904"
            },
            "simulation_guid": "6cc9917f-ed0f-4a18-b65a-00405b87714a",
            "sensor_paths": [
                "Irradiance.1"
            ],
            "source_paths": [
                "Surface.1"
            ],
            "description": "",
            "simulation": {
                "direct_mc_simulation_template": {
                    "geom_distance_tolerance": 0.01,
                    "max_impact": 200,
                    "colorimetric_standard": "CIE_1964",
                    "ambient_material_uri": "/app/assets/AIR.material",
                    "dispersion": false,
                    "fast_transmission_gathering": false,
                    "stop_condition_rays_number": "200000",
                    "automatic_save_frequency": 1800
                },
                "name": "Simulation.2",
                "description": "",
                "metadata": {},
                "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
                "simulation_path": "Simulation.2",
                "job_type": "CPU"
            }
        }
    ],
    "materials": [
        {
            "name": "Material.1",
            "metadata": {
                "UniqueId": "e5bb8cca-45d2-4e7f-aa65-91663e24486a"
            },
            "vop_guid": "e7c14a1d-0a19-4bc1-88fc-1130807e355e",
            "sop_guids": [
                "bcd60179-5379-4d2f-be78-95cb0dab7729"
            ],
            "geometries": {
                "geo_paths": [
                    "Body.1"
                ]
            },
            "description": "",
            "vop": {
                "name": "Material.1.VOP",
                "opaque": {},
                "description": "",
                "metadata": {}
            },
            "sops": [
                {
                    "name": "Material.1.SOP",
                    "mirror": {
                        "reflectance": 100.0
                    },
                    "description": "",
                    "metadata": {}
                }
            ]
        }
    ],
    "name": "",
    "description": "",
    "metadata": {},
    "scenes": []
}

Update simulation settings#

If you are manipulating a simulation already committed, remember to commit your changes.

If you don’t, you will still only watch what is committed on the server.

[15]:
simulation1.set_ambient_material_file_uri(uri=str(assets_data_path / "AIR.material"))
simulation1.commit()
print(simulation1)
{
    "name": "Simulation.1",
    "metadata": {
        "UniqueId": "a25508ec-fd26-4826-ab61-82275f9370ec"
    },
    "simulation_guid": "8a3431ee-8140-47a1-963f-5c9f9eb32f61",
    "sensor_paths": [
        "Irradiance.1"
    ],
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "simulation": {
        "direct_mc_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 100,
            "weight": {
                "minimum_energy_percentage": 0.005
            },
            "dispersion": true,
            "ambient_material_uri": "/app/assets/AIR.material",
            "colorimetric_standard": "CIE_1931",
            "fast_transmission_gathering": false,
            "stop_condition_rays_number": "200000",
            "automatic_save_frequency": 1800
        },
        "name": "Simulation.1",
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.1",
        "job_type": "CPU"
    }
}

Reset#

Possibility to reset local values from the one available in the server.

[16]:
simulation1.set_max_impact(1000)  # adjust max impact but no commit
simulation1.reset()  # reset -> this will apply the server value to the local value
simulation1.delete()  # delete (to display the local value with the below print)
print(simulation1)
local: {
    "name": "Simulation.1",
    "sensor_paths": [
        "Irradiance.1"
    ],
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "metadata": {},
    "simulation_guid": "",
    "simulation": {
        "direct_mc_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 100,
            "weight": {
                "minimum_energy_percentage": 0.005
            },
            "dispersion": true,
            "ambient_material_uri": "/app/assets/AIR.material",
            "colorimetric_standard": "CIE_1931",
            "fast_transmission_gathering": false,
            "stop_condition_rays_number": "200000",
            "automatic_save_frequency": 1800
        },
        "name": "Simulation.1",
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.1",
        "job_type": "CPU"
    }
}

Other simulation examples#

Inverse simulation#

[17]:
simulation3 = p.create_simulation(name="Simulation.3", feature_type=SimulationInverse)
simulation3.set_sensor_paths(sensor_paths=[SENSOR_NAME]).set_source_paths(
    source_paths=[SOURCE_NAME]
).commit()
print(simulation3)
{
    "name": "Simulation.3",
    "metadata": {
        "UniqueId": "561f4479-8f2e-4859-b4e3-a3faed65268e"
    },
    "simulation_guid": "1b240dae-7977-4fb0-974a-6969e3f25dd1",
    "sensor_paths": [
        "Irradiance.1"
    ],
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "simulation": {
        "inverse_mc_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 100,
            "weight": {
                "minimum_energy_percentage": 0.005
            },
            "number_of_gathering_rays_per_source": 1,
            "colorimetric_standard": "CIE_1931",
            "dispersion": false,
            "splitting": false,
            "maximum_gathering_error": 0,
            "maximum_gathering_error_percentage": 0.0,
            "fast_transmission_gathering": false,
            "ambient_material_uri": "",
            "optimized_propagation_none": {
                "stop_condition_passes_number": 5
            },
            "automatic_save_frequency": 1800
        },
        "name": "Simulation.3",
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.3",
        "job_type": "CPU"
    }
}

Interactive simulation#

[18]:
simulation4 = p.create_simulation(name="Simulation.4", feature_type=SimulationInteractive)
simulation4.set_source_paths(source_paths=[SOURCE_NAME]).commit()
print(simulation4)
{
    "name": "Simulation.4",
    "metadata": {
        "UniqueId": "cb059798-d012-49e8-9896-e073b963706d"
    },
    "simulation_guid": "d92959f1-502e-446a-a124-6342d67ef464",
    "source_paths": [
        "Surface.1"
    ],
    "description": "",
    "sensor_paths": [],
    "simulation": {
        "name": "Simulation.4",
        "interactive_simulation_template": {
            "geom_distance_tolerance": 0.01,
            "max_impact": 100,
            "weight": {
                "minimum_energy_percentage": 0.005
            },
            "colorimetric_standard": "CIE_1931",
            "ambient_material_uri": "",
            "rays_number_per_sources": [],
            "light_expert": false,
            "impact_report": false
        },
        "description": "",
        "metadata": {},
        "scene_guid": "cd7a908b-0941-4e23-b4d8-1fae502b6e7f",
        "simulation_path": "Simulation.4",
        "job_type": "CPU"
    }
}