Skip to content

Commit 56380df

Browse files
StefanThoenepyansys-ci-botechambla
authored
fix: improve examples and tests due to more errors raised by the new SpeosRPC server (#546)
## Description Adapt to new Speos RPC server behavior. More errors are raised when objects committed are not correct. ## Issue linked **Please mention the issue number or describe the problem this pull request addresses.** ## Checklist - [x] I have tested my changes locally. - [x] I have added necessary documentation or updated existing documentation. - [x] I have followed the coding style guidelines of this project. - [x] I have added appropriate tests (unit, integration, system). - [x] I have reviewed my changes before submitting this pull request. - [x] I have linked the issue or issues that are solved by the PR if any. - [x] I have assigned this PR to myself. - [x] I have made sure that the title of my PR follows [Conventional commits style](https://www.conventionalcommits.org/en/v1.0.0/#summary) (e.g. ``feat: add optical property``) - [x] I have agreed with the Contributor License Agreement ([CLA](https://developer.ansys.com/form/cla-acceptance)). --------- Co-authored-by: pyansys-ci-bot <[email protected]> Co-authored-by: Elodie Chamblas <[email protected]>
1 parent 9064b19 commit 56380df

File tree

14 files changed

+334
-111
lines changed

14 files changed

+334
-111
lines changed

doc/changelog.d/546.fixed.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
improve examples and tests due to more errors raised by the new SpeosRPC server

examples/core/opt-prop.py

Lines changed: 77 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,82 @@
88
# the surface optical property (SOP) and the volume optical property (VOP).
99

1010
# The property is then applied to a geometry (like bodies, faces).
11+
#
12+
# ## Prerequisites
13+
#
14+
# ### Perform imports
1115

12-
# +
1316
from pathlib import Path
1417

1518
from ansys.speos.core import GeoRef, Project, Speos
1619

17-
# If using docker container
18-
assets_data_path = Path("/app") / "assets"
19-
# If using local server
20-
# assets_data_path = Path().resolve().parent.parent / "tests" / "assets"
21-
# If using a different path
22-
# assets_data_path = Path("path/to/downloaded/example/assets")
23-
# -
20+
# ### Define constants
21+
# Constants help ensure consistency and avoid repetition throughout the example.
2422

25-
# ## Create connection with speos rpc server
23+
HOSTNAME = "localhost"
24+
GRPC_PORT = 50098 # Be sure the Speos GRPC Server has been started on this port.
25+
USE_DOCKER = True # Set to False if you're running this example locally as a Notebook.
2626

27-
# +
28-
speos = Speos(host="localhost", port=50098)
29-
# -
27+
# ### Define helper functions
3028

31-
# ## New Project
3229

33-
# The only way to create an optical property is to create it from a project.
30+
def create_helper_geometries(project: Project):
31+
"""Create bodies and faces."""
32+
33+
def create_face(body):
34+
(
35+
body.create_face(name="TheFaceF")
36+
.set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0])
37+
.set_facets([0, 1, 2])
38+
.set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
39+
.commit()
40+
)
41+
42+
root_part = project.create_root_part().commit()
43+
body_b1 = root_part.create_body(name="TheBodyB").commit()
44+
body_b2 = root_part.create_body(name="TheBodyC").commit()
45+
body_b3 = root_part.create_body(name="TheBodyD").commit()
46+
body_b4 = root_part.create_body(name="TheBodyE").commit()
47+
for b in [body_b1, body_b2, body_b3, body_b4]:
48+
create_face(b)
49+
50+
51+
# ## Model Setup
52+
#
53+
# ### Load assets
54+
# The assets used to run this example are available in the
55+
# [PySpeos repository](https://github.com/ansys/pyspeos/) on GitHub.
56+
#
57+
# > **Note:** Make sure you
58+
# > have downloaded simulation assets and set ``assets_data_path``
59+
# > to point to the assets folder.
60+
61+
if USE_DOCKER: # Running on the remote server.
62+
assets_data_path = Path("/app") / "assets"
63+
else:
64+
assets_data_path = Path("/path/to/your/download/assets/directory")
65+
66+
# ### Connect to the RPC Server
67+
# This Python client connects to a server where the Speos engine
68+
# is running as a service. In this example, the server and
69+
# client are the same machine.
70+
71+
speos = Speos(host=HOSTNAME, port=GRPC_PORT)
72+
73+
# ### Create a new project
74+
#
75+
# The only way to create an optical property using the core layer, is to create it from a project.
76+
# The ``Project`` class is instantiated by passing a ``Speos`` instance
3477

35-
# +
3678
p = Project(speos=speos)
3779
print(p)
38-
# -
80+
create_helper_geometries(p)
3981

4082
# ## Create VOP (volume optical property)
41-
83+
#
4284
# Create locally.
43-
4485
# The mention "local: " is added when printing the optical property.
4586

46-
# +
4787
op1 = p.create_optical_property(name="Material.1")
4888
op1.set_surface_mirror(reflectance=80) # SOP : mirror
4989
op1.set_volume_opaque() # VOP : opaque
@@ -55,23 +95,20 @@
5595
]
5696
)
5797
print(op1)
58-
# -
5998

60-
# ## Push it to the server.
6199

100+
# ## Push it to the server.
101+
#
62102
# Now that it is committed to the server,
63103
# the mention "local: " is no more present when printing the optical property.
64104

65-
# +
66105
op1.commit()
67106
print(op1)
68-
# -
69107

70108
# ## Another example.
71-
109+
#
72110
# Setting several more characteristics.
73111

74-
# +
75112
op2 = p.create_optical_property(name="Material.2")
76113
op2.set_surface_opticalpolished() # SOP : optical polished
77114
op2.set_volume_library(
@@ -86,41 +123,35 @@
86123
)
87124
op2.commit()
88125
print(op2)
89-
# -
90126

91-
# ## Create FOP (face optical property)
92127

128+
# ## Create FOP (face optical property)
129+
#
93130
# Sometimes it is needed to create property but only for surface.
94-
131+
#
95132
# In this case, no call for set_volume_xxx function is needed, and we will select a face for the
96133
# geometries.
97134

98-
# +
99135
op3 = p.create_optical_property(name="Material.FOP")
100136
op3.set_surface_mirror(reflectance=90) # SOP : mirror
101137
# This optical property will be applied a face from TheBodyD named : "TheFaceF".
102138
op3.set_geometries(geometries=[GeoRef.from_native_link(geopath="TheBodyD/TheFaceF")])
103139
op3.commit()
104140
print(op3)
105-
# -
106141

107142
# ## Default values
108-
143+
#
109144
# Some default values are available when applicable in every methods and class.
110145

111-
# +
112146
op4 = p.create_optical_property(name="Material.3").commit()
113147
print(op4)
114-
# -
115148

116149
# ## Read
117150
# ### Material Instance Information
118-
151+
#
119152
# A mention "local: " is added if it is not yet committed to the server.
120153

121-
# +
122154
print(op1)
123-
# -
124155

125156
# The get methods allows you to get some properties of your feature
126157

@@ -158,47 +189,43 @@
158189
# ### Project Information
159190
# Committed feature information will appear inside a project information.
160191

161-
# +
162192
print(p)
163-
# -
164193

165194
# ## Update
166-
195+
#
167196
# Tipp: if you are manipulating an optical property already committed, don't forget to commit your
168197
# changes.
169-
198+
#
170199
# If you don't, you will still only watch what is committed on the server.
171200

172-
# +
201+
173202
print("op1 surface type before update: {}".format(op1.get(key="sops")[0]))
174203
op1.set_volume_optic().set_surface_opticalpolished().commit()
175204
print(op1)
176205
print("op1 surface type after update: {}".format(op1.get(key="sops")[0]))
177-
# -
178206

179-
# ## Reset
180207

208+
# ## Reset
209+
#
181210
# Possibility to reset local values from the one available in the server.
182211

183-
# +
184212
op1.set_surface_mirror() # set surface as a mirror but no commit
185213
op1.reset() # reset -> this will apply the server value to the local value
186214
op1.delete() # delete (to display the local value with the below print)
187215
print(op1)
188-
# -
189216

190-
# ## Delete
191217

218+
# ## Delete
219+
#
192220
# Once the data is deleted from the server, you can still work with local data and maybe commit
193221
# later.
194222

195-
# +
223+
196224
op2.delete()
197225
print(op2)
198-
# -
199226

200-
# +
227+
# Clean up all Optical properties
228+
201229
op1.delete()
202230
op3.delete()
203231
op4.delete()
204-
# -

examples/core/project.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
from ansys.speos.core import Project, Speos
1818
from ansys.speos.core.sensor import SensorIrradiance
1919
from ansys.speos.core.simulation import SimulationDirect
20-
from ansys.speos.core.source import SourceSurface
20+
from ansys.speos.core.source import SourceLuminaire, SourceSurface
2121

2222
# If using docker container
2323
assets_data_path = Path("/app") / "assets"
@@ -45,7 +45,8 @@
4545
# create feature - e.g. source
4646

4747
# +
48-
source1 = p.create_source(name="Source.1", feature_type=SourceSurface)
48+
source1 = p.create_source(name="Source.1", feature_type=SourceLuminaire)
49+
source1.set_intensity_file_uri(uri=str(assets_data_path / "IES_C_DETECTOR.ies"))
4950
source1.commit()
5051
# -
5152

@@ -99,7 +100,7 @@
99100
# Here a wrong type is given: no source is called Sensor.1 in the project
100101

101102
# +
102-
features = p.find(name="Sensor.1", feature_type=SourceSurface)
103+
features = p.find(name="Sensor.1", feature_type=SourceLuminaire)
103104
print(features)
104105
# -
105106

@@ -177,6 +178,7 @@
177178

178179
# +
179180
features = p2.find(name=".*", name_regex=True, feature_type=SourceSurface)
181+
print(features)
180182
for feat in features:
181183
print(str(type(feat)) + " : name=" + feat._name)
182184
src = features[1]

examples/core/sensor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@
180180
# -
181181

182182
# +
183-
sensor3.set_type_colorimetric()
183+
sensor3.set_type_radiometric()
184184
sensor3.set_layer_type_polarization()
185185
sensor3.commit()
186186
print(sensor3)

examples/core/source.py

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,30 @@
2828
USE_DOCKER = True # Set to False if you're running this example locally as a Notebook.
2929
IES = "IES_C_DETECTOR.ies"
3030

31+
# ### Define helper functions
32+
33+
34+
def create_helper_geometries(project: Project):
35+
"""Create bodies and faces."""
36+
37+
def create_face(body):
38+
(
39+
body.create_face(name="TheFaceF")
40+
.set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0])
41+
.set_facets([0, 1, 2])
42+
.set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
43+
.commit()
44+
)
45+
46+
root_part = project.create_root_part().commit()
47+
body_b1 = root_part.create_body(name="TheBodyB").commit()
48+
body_b2 = root_part.create_body(name="TheBodyC").commit()
49+
body_b3 = root_part.create_body(name="TheBodyD").commit()
50+
body_b4 = root_part.create_body(name="TheBodyE").commit()
51+
for b in [body_b1, body_b2, body_b3, body_b4]:
52+
create_face(b)
53+
54+
3155
# ## Model Setup
3256
#
3357
# ### Load assets
@@ -168,11 +192,12 @@
168192
# ### Surface source
169193

170194
# +
195+
create_helper_geometries(p)
171196
source4 = p.create_source(name="Surface.1", feature_type=SourceSurface)
172197
source4.set_exitance_constant(
173198
geometries=[
174199
(GeoRef.from_native_link("TheBodyB/TheFaceF"), False),
175-
(GeoRef.from_native_link("TheBodyB/TheFaceG"), True),
200+
(GeoRef.from_native_link("TheBodyC/TheFaceF"), True),
176201
]
177202
)
178203
source4.commit()

src/ansys/speos/core/project.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,7 @@ def _fill_features(self):
747747
op_feature._fill(mat_inst=mat_inst)
748748

749749
for src_inst in scene_data.sources:
750+
src_feat = None
750751
if src_inst.HasField("rayfile_properties"):
751752
src_feat = SourceRayFile(
752753
project=self,
@@ -768,7 +769,8 @@ def _fill_features(self):
768769
source_instance=src_inst,
769770
default_values=False,
770771
)
771-
self._features.append(src_feat)
772+
if src_feat is not None:
773+
self._features.append(src_feat)
772774

773775
for ssr_inst in scene_data.sensors:
774776
if ssr_inst.HasField("irradiance_properties"):

src/ansys/speos/core/source.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,7 @@ def __init__(
791791

792792
if default_values:
793793
# Default values
794+
self._exitance_variable.SetInParent()
794795
self.set_axis_plane()
795796

796797
def set_xmp_file_uri(self, uri: str) -> SourceSurface.ExitanceVariable:

tests/core/test_opt_prop.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ def test_reset_optical_property(speos: Speos):
146146
"""Test reset of optical property."""
147147
p = Project(speos=speos)
148148

149+
root_part = p.create_root_part()
150+
body_b = root_part.create_body(name="TheBodyB")
151+
body_b.create_face(name="TheFaceF").set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0]).set_facets(
152+
[0, 1, 2]
153+
).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
154+
root_part.commit()
155+
149156
# Create + commit
150157
op1 = (
151158
p.create_optical_property(name="Material.1")
@@ -185,6 +192,13 @@ def test_delete_optical_property(speos: Speos):
185192
"""Test delete of optical property."""
186193
p = Project(speos=speos)
187194

195+
root_part = p.create_root_part()
196+
body_b = root_part.create_body(name="TheBodyB")
197+
body_b.create_face(name="TheFaceF").set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0]).set_facets(
198+
[0, 1, 2]
199+
).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
200+
root_part.commit()
201+
188202
# Create + commit
189203
op1 = (
190204
p.create_optical_property(name="Material.1")
@@ -216,6 +230,18 @@ def test_delete_optical_property(speos: Speos):
216230
def test_get_optical_property(speos: Speos, capsys):
217231
"""Test get of an optical property."""
218232
p = Project(speos=speos)
233+
234+
root_part = p.create_root_part()
235+
body_a = root_part.create_body(name="TheBodyA")
236+
body_a.create_face(name="TheFaceF").set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0]).set_facets(
237+
[0, 1, 2]
238+
).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
239+
body_b = root_part.create_body(name="TheBodyB")
240+
body_b.create_face(name="TheFaceF").set_vertices([0, 0, 0, 1, 0, 0, 0, 1, 0]).set_facets(
241+
[0, 1, 2]
242+
).set_normals([0, 0, 1, 0, 0, 1, 0, 0, 1])
243+
root_part.commit()
244+
219245
op1 = (
220246
p.create_optical_property(name="Material.1")
221247
.set_volume_opaque()

0 commit comments

Comments
 (0)