# # How to create a component # # This tutorial demonstrates how to create a component feature. # # Component feature includes: lightbox import. # ## Prerequisites # # ### Perform imports import json from pathlib import Path from ansys.speos.core import OptProp, Project, Speos, launcher from ansys.speos.core.component import LightBox, LightBoxFileInstance from ansys.speos.core.kernel.client import ( default_docker_channel, ) from ansys.speos.core.simulation import SimulationDirect from ansys.speos.core.source import SourceSurface # ### Define constants # # The constants help ensure consistency and avoid repetition throughout the example. # + 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. FILES = "CameraInputFiles" # - # ### Define helper functions # # These helpers keep LightBox output concise for documentation. # Detailed nested content is truncated because it is not the focus of this example. # + def _truncate_json_value(value, *, max_depth=3, max_list_items=8, max_dict_items=12, _depth=0): """Truncate nested JSON-like data for readable output. Parameters ---------- value : Any Input value to truncate. max_depth : int, default: 3 Maximum nesting depth to keep. max_list_items : int, default: 8 Maximum number of items kept per list. max_dict_items : int, default: 12 Maximum number of keys kept per dictionary. _depth : int, default: 0 Current recursion depth. This parameter is for internal use. Returns ------- Any Truncated representation of the input value. """ if _depth >= max_depth: if isinstance(value, dict): return {"...": f"{len(value)} keys hidden"} if isinstance(value, list): return [f"... {len(value)} items hidden"] return value if isinstance(value, dict): items = list(value.items()) out = { key: _truncate_json_value( sub_value, max_depth=max_depth, max_list_items=max_list_items, max_dict_items=max_dict_items, _depth=_depth + 1, ) for key, sub_value in items[:max_dict_items] } hidden = len(items) - max_dict_items if hidden > 0: out["..."] = f"{hidden} more keys" return out if isinstance(value, list): out = [ _truncate_json_value( item, max_depth=max_depth, max_list_items=max_list_items, max_dict_items=max_dict_items, _depth=_depth + 1, ) for item in value[:max_list_items] ] hidden = len(value) - max_list_items if hidden > 0: out.append(f"... {hidden} more items") return out return value def print_lightbox_compact(lightbox, *, max_depth=3, max_list_items=8): """Print a compact LightBox representation. Parameters ---------- lightbox : ansys.speos.core.component.LightBox LightBox feature to print. max_depth : int, default: 3 Maximum nesting depth kept in the printed JSON payload. max_list_items : int, default: 8 Maximum number of items shown per list in the printed payload. Returns ------- None This function prints formatted output and returns nothing. Notes ----- The optional ``"local: "`` prefix from ``str(lightbox)`` is preserved. """ out_str = str(lightbox) prefix = "" payload = out_str if out_str.startswith("local: "): prefix = "local: " payload = out_str[len(prefix) :] try: payload_dict = json.loads(payload) except json.JSONDecodeError: # Fallback to default string output if it is not valid JSON. print(out_str) return compact_payload = _truncate_json_value( payload_dict, max_depth=max_depth, max_list_items=max_list_items, ) print(prefix + json.dumps(compact_payload, indent=4)) # - # ## Model Setup # # ### Load assets # The assets used to run this example are available in the # [PySpeos repository](https://github.com/ansys/pyspeos/) on GitHub. # # > **Note:** Make sure you have downloaded the simulation assets and set # > ``assets_data_path`` to point to the assets' folder. 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. The launch_local_speos_rpc_method can # be used to start a local instance of the service. if USE_DOCKER: speos = Speos(channel=default_docker_channel()) else: speos = launcher.launch_local_speos_rpc_server(port=GRPC_PORT) # ## Create a new project # # The only way to create a lightbox import, is to create it from a project. p = Project(speos=speos) print(p) # ## Create # # Create locally # # The mention "local: " is added when printing the lightbox lightbox = p.create_lightbox( name="Light Box Import.1", lightbox=LightBoxFileInstance( file=assets_data_path / "lightbox" / "Light Box Export.2.SPEOSLightBox", password="" ), ) print_lightbox_compact(lightbox) # ## Push it to the server. # # Now that it is committed to the server, the mention "local: " is no more present when printing # the lightbox. lightbox.commit() print_lightbox_compact(lightbox) # ## Read # # ### Lightbox Instance # # Properties methods provided are used to retrieve or modify the information of lightbox. # + print(lightbox.name) print(lightbox.axis_system) print(lightbox.source_paths) lightbox.axis_system = [100, 50, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1] print_lightbox_compact(lightbox) # - # Commit the modification to the server # + lightbox.commit() print_lightbox_compact(lightbox) # - # ### Source and Bodies instance inside Lightbox # # Find method is provided to select the features, e.g. sources, bodies inside lightbox. # # Example source in lightbox: # + lightbox_source = lightbox.find(name=".*", name_regex=True, feature_type=SourceSurface)[0] print(lightbox_source) # - # Example material property in lightbox: # + lightbox_material = lightbox.find(name=".*", name_regex=True, feature_type=OptProp)[0] print(lightbox_material) # - # ## Modify lightbox features # # ### feature instance modify method # # The Lightbox contains features that can be modified via feature commit. # + lightbox_source = lightbox.find(name=".*", name_regex=True, feature_type=SourceSurface)[0] print(lightbox_source) lightbox_source.flux.value = 30 lightbox_source.commit() print(lightbox_source) # - # ### lightbox instance as global modify method # # The Lightbox contains features that can be modified via lightbox commit. # + lightbox_material = lightbox.find(name=".*", name_regex=True, feature_type=OptProp)[0] print(lightbox_material) lightbox_material.sop_mirror.reflectance = 85 print(lightbox_source) lightbox_source.intensity.set_cos().total_angle = 20 lightbox.commit() print(lightbox_material) print(lightbox_source) # - # ## Delete lightbox_source.delete() # ## Lightbox sources in simulation # # The project contains two lightbox features. # source_paths are in format of lightbox_name/source_name. # + p2 = Project( speos=speos, path=assets_data_path / "lightbox" / "Direct.1.speos", ) lightboxes = p2.find(name=".*", name_regex=True, feature_type=LightBox) lightbox_1 = lightboxes[0] lightbox_2 = lightboxes[1] print(lightbox_1.source_paths) print(lightbox_2.source_paths) # - # ## Adding lightbox sources in simulation # # User can add all the sources from lightbox using source_paths method # Alternatively, user can choose to add selected features # + sim = p2.find(name=".*", name_regex=True, feature_type=SimulationDirect)[0] sim.source_paths = lightbox_2.source_paths sim.commit() lightbox_source = lightbox_2.find(name=".*", name_regex=True, feature_type=SourceSurface)[0] sim.source_paths = [lightbox_source] sim.commit() # - # ## Black Lightbox # # The Black Lightbox is a lightbox which does not show any features' information. # All sources, geometries, materials information cannot be viewed and cannot be edited. # + lightbox2 = p.create_lightbox( name="Light Box Import.2", lightbox=LightBoxFileInstance( file=assets_data_path / "lightbox" / "BlackLightBox.SPEOSLightBox", password="" ), ) print_lightbox_compact(lightbox2) print(lightbox2.name) print(lightbox2.source_paths) # - # Add a black lightbox to simulation needs to add lightbox to the source paths. # + lightbox_3 = p2.create_lightbox( name="Black Light Box Import", lightbox=LightBoxFileInstance( file=assets_data_path / "lightbox" / "BlackLightBox.SPEOSLightBox", password="" ), ) lightbox_3.commit() sim.source_paths = [lightbox_3.name] sim.commit() # -