luminarycloud 0.22.0__py3-none-any.whl → 0.22.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. luminarycloud/_client/authentication_plugin.py +49 -0
  2. luminarycloud/_client/client.py +38 -11
  3. luminarycloud/_client/http_client.py +1 -1
  4. luminarycloud/_client/retry_interceptor.py +64 -2
  5. luminarycloud/_helpers/__init__.py +9 -0
  6. luminarycloud/_helpers/_inference_jobs.py +227 -0
  7. luminarycloud/_helpers/_parse_iso_datetime.py +54 -0
  8. luminarycloud/_helpers/download.py +11 -0
  9. luminarycloud/_helpers/proto_decorator.py +38 -7
  10. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.py +152 -132
  11. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.pyi +66 -8
  12. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.py +34 -0
  13. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.pyi +12 -0
  14. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +142 -39
  15. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +300 -3
  16. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.py +34 -0
  17. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.pyi +12 -0
  18. luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2.py +255 -0
  19. luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2.pyi +466 -0
  20. luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2_grpc.py +242 -0
  21. luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2_grpc.pyi +95 -0
  22. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.py +29 -7
  23. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.pyi +39 -0
  24. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.py +36 -0
  25. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.pyi +18 -0
  26. luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.py +88 -65
  27. luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.pyi +42 -0
  28. luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2_grpc.py +34 -0
  29. luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2_grpc.pyi +12 -0
  30. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.py +163 -153
  31. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.pyi +37 -3
  32. luminarycloud/_proto/base/base_pb2.py +7 -6
  33. luminarycloud/_proto/base/base_pb2.pyi +4 -0
  34. luminarycloud/_proto/client/simulation_pb2.py +358 -339
  35. luminarycloud/_proto/client/simulation_pb2.pyi +89 -3
  36. luminarycloud/_proto/physicsaiinferenceservice/physicsaiinferenceservice_pb2.py +35 -0
  37. luminarycloud/_proto/physicsaiinferenceservice/physicsaiinferenceservice_pb2.pyi +7 -0
  38. luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2.py +6 -3
  39. luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.py +68 -0
  40. luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.pyi +24 -0
  41. luminarycloud/_wrapper.py +53 -7
  42. luminarycloud/enum/vis_enums.py +6 -0
  43. luminarycloud/feature_modification.py +25 -32
  44. luminarycloud/geometry.py +10 -6
  45. luminarycloud/geometry_version.py +4 -0
  46. luminarycloud/mesh.py +4 -0
  47. luminarycloud/meshing/mesh_generation_params.py +5 -6
  48. luminarycloud/meshing/sizing_strategy/sizing_strategies.py +1 -2
  49. luminarycloud/outputs/__init__.py +2 -0
  50. luminarycloud/outputs/output_definitions.py +3 -3
  51. luminarycloud/outputs/stopping_conditions.py +94 -0
  52. luminarycloud/params/enum/_enum_wrappers.py +16 -0
  53. luminarycloud/params/geometry/shapes.py +33 -33
  54. luminarycloud/params/simulation/adaptive_mesh_refinement/__init__.py +1 -0
  55. luminarycloud/params/simulation/adaptive_mesh_refinement/active_region_.py +83 -0
  56. luminarycloud/params/simulation/adaptive_mesh_refinement/boundary_layer_profile_.py +1 -1
  57. luminarycloud/params/simulation/adaptive_mesh_refinement_.py +8 -1
  58. luminarycloud/physics_ai/__init__.py +7 -0
  59. luminarycloud/physics_ai/inference.py +166 -199
  60. luminarycloud/physics_ai/models.py +22 -0
  61. luminarycloud/physics_ai/solution.py +4 -0
  62. luminarycloud/pipelines/api.py +143 -16
  63. luminarycloud/pipelines/core.py +1 -1
  64. luminarycloud/pipelines/stages.py +22 -9
  65. luminarycloud/project.py +61 -8
  66. luminarycloud/simulation.py +25 -0
  67. luminarycloud/types/__init__.py +2 -0
  68. luminarycloud/types/ids.py +2 -0
  69. luminarycloud/types/vector3.py +1 -2
  70. luminarycloud/vis/__init__.py +1 -0
  71. luminarycloud/vis/data_extraction.py +7 -7
  72. luminarycloud/vis/filters.py +97 -0
  73. luminarycloud/vis/interactive_report.py +163 -7
  74. luminarycloud/vis/report.py +113 -1
  75. luminarycloud/vis/visualization.py +3 -0
  76. luminarycloud/volume_selection.py +16 -8
  77. luminarycloud/workflow_utils.py +149 -0
  78. {luminarycloud-0.22.0.dist-info → luminarycloud-0.22.2.dist-info}/METADATA +1 -1
  79. {luminarycloud-0.22.0.dist-info → luminarycloud-0.22.2.dist-info}/RECORD +80 -76
  80. {luminarycloud-0.22.0.dist-info → luminarycloud-0.22.2.dist-info}/WHEEL +1 -1
  81. luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.py +0 -61
  82. luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.pyi +0 -85
  83. luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2_grpc.py +0 -67
  84. luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2_grpc.pyi +0 -26
  85. luminarycloud/_proto/inferenceservice/inferenceservice_pb2.py +0 -69
  86. luminarycloud/pipeline_util/dictable.py +0 -27
@@ -16,11 +16,10 @@ from ..params.geometry import (
16
16
  )
17
17
  from ..types import Vector3
18
18
  from .sizing_strategy import MaxCount, Minimal, MinimalCount, SizingStrategy, TargetCount
19
- from ..pipeline_util.dictable import PipelineDictable
20
19
 
21
20
 
22
21
  @dataclass(kw_only=True)
23
- class VolumeMeshingParams(PipelineDictable):
22
+ class VolumeMeshingParams:
24
23
  """Volume meshing parameters."""
25
24
 
26
25
  volumes: list[Volume]
@@ -39,7 +38,7 @@ class VolumeMeshingParams(PipelineDictable):
39
38
 
40
39
 
41
40
  @dataclass(kw_only=True)
42
- class ModelMeshingParams(PipelineDictable):
41
+ class ModelMeshingParams:
43
42
  """Model meshing parameters."""
44
43
 
45
44
  surfaces: Sequence[Surface | str]
@@ -62,7 +61,7 @@ class ModelMeshingParams(PipelineDictable):
62
61
 
63
62
 
64
63
  @dataclass(kw_only=True)
65
- class BoundaryLayerParams(PipelineDictable):
64
+ class BoundaryLayerParams:
66
65
  """Boundary layer meshing parameters."""
67
66
 
68
67
  surfaces: Sequence[Surface | str]
@@ -88,7 +87,7 @@ class BoundaryLayerParams(PipelineDictable):
88
87
 
89
88
 
90
89
  @dataclass(kw_only=True)
91
- class RefinementRegion(PipelineDictable):
90
+ class RefinementRegion:
92
91
  """Refinement region parameters."""
93
92
 
94
93
  name: str
@@ -138,7 +137,7 @@ class RefinementRegion(PipelineDictable):
138
137
 
139
138
 
140
139
  @dataclass(kw_only=True)
141
- class MeshGenerationParams(PipelineDictable):
140
+ class MeshGenerationParams:
142
141
  """Mesh generation parameters."""
143
142
 
144
143
  geometry_id: str
@@ -1,11 +1,10 @@
1
1
  from dataclasses import dataclass
2
2
 
3
3
  from luminarycloud._helpers.warnings.deprecated import deprecated
4
- from ...pipeline_util.dictable import PipelineDictable
5
4
 
6
5
 
7
6
  @dataclass
8
- class SizingStrategy(PipelineDictable):
7
+ class SizingStrategy:
9
8
  """Sizing strategy parameters."""
10
9
 
11
10
  pass
@@ -19,6 +19,8 @@ from .output_definitions import (
19
19
 
20
20
  from .stopping_conditions import (
21
21
  StoppingCondition as StoppingCondition,
22
+ StoppingConditionResult as StoppingConditionResult,
23
+ StoppingConditionStatusResult as StoppingConditionStatusResult,
22
24
  GeneralStoppingConditions as GeneralStoppingConditions,
23
25
  create_or_update_stopping_condition as create_or_update_stopping_condition,
24
26
  get_stopping_condition as get_stopping_condition,
@@ -125,7 +125,7 @@ class SurfaceAverageOutputDefinition(CodeRepr):
125
125
  space_averaging_type: SpaceAveragingType = SpaceAveragingType.AREA
126
126
  "Type of spatial averaging to use."
127
127
  vector_component: Vector3Component = Vector3Component.UNSPECIFIED
128
- "For vector quantities, the component to measure."
128
+ "For vector quantities, the component to measure must be specified (X, Y, or Z)."
129
129
 
130
130
  def _to_proto(self) -> feoutputpb.OutputNode:
131
131
  proto = feoutputpb.OutputNode(
@@ -309,7 +309,7 @@ class PointProbeOutputDefinition(CodeRepr):
309
309
  include: OutputDefinitionInclusions = field(default_factory=OutputDefinitionInclusions)
310
310
  "Configuration for what values to include."
311
311
  vector_component: Vector3Component = Vector3Component.UNSPECIFIED
312
- "For vector quantities, the component to measure."
312
+ "For vector quantities, the component to measure must be specified (X, Y, or Z)."
313
313
 
314
314
  def _to_proto(self) -> feoutputpb.OutputNode:
315
315
  proto = feoutputpb.OutputNode(
@@ -356,7 +356,7 @@ class VolumeReductionOutputDefinition(CodeRepr):
356
356
  volume_reduction_type: VolumeReductionType = VolumeReductionType.AVERAGE
357
357
  "Type of reduction to perform for each volume."
358
358
  vector_component: Vector3Component = Vector3Component.UNSPECIFIED
359
- "For vector quantities, the component to measure."
359
+ "For vector quantities, the component to measure must be specified (X, Y, or Z)."
360
360
 
361
361
  def _to_proto(self) -> feoutputpb.OutputNode:
362
362
  proto = feoutputpb.OutputNode(
@@ -2,6 +2,7 @@
2
2
 
3
3
  from .._client import get_default_client
4
4
  from .._proto.api.v0.luminarycloud.stopping_condition import stopping_condition_pb2 as stopcondpb
5
+ from .._proto.api.v0.luminarycloud.simulation import simulation_pb2 as simulationpb
5
6
  from .._proto.output import output_pb2 as outputpb
6
7
  from dataclasses import dataclass
7
8
 
@@ -213,3 +214,96 @@ def update_general_stopping_conditions(
213
214
  )
214
215
  res = get_default_client().UpdateBasicStoppingConditions(req)
215
216
  return GeneralStoppingConditions._from_proto(res.basic_stopping_conditions)
217
+
218
+
219
+ @dataclass
220
+ class StoppingConditionResult:
221
+ """
222
+ Result of evaluating a single stopping condition.
223
+
224
+ Attributes
225
+ ----------
226
+ output_name : str
227
+ Name of the output being monitored.
228
+ threshold : float
229
+ The threshold value for this condition.
230
+ value : float
231
+ The actual value of the monitored output.
232
+ satisfied : bool
233
+ Whether this condition was satisfied.
234
+ is_force_condition : bool
235
+ Whether this is a force-stop condition (e.g., max iterations, max time).
236
+ Force conditions cause immediate termination regardless of other conditions.
237
+ """
238
+
239
+ output_name: str
240
+ threshold: float
241
+ value: float
242
+ satisfied: bool
243
+ is_force_condition: bool
244
+
245
+
246
+ @dataclass
247
+ class StoppingConditionStatusResult:
248
+ """
249
+ Status of all stopping conditions for a simulation.
250
+
251
+ This represents the evaluation of stopping conditions against the final
252
+ simulation results.
253
+
254
+ Attributes
255
+ ----------
256
+ overall_success : bool
257
+ Whether the overall stopping criteria were met (excluding force-stop conditions).
258
+ force_stopped : bool
259
+ Whether a force-stop condition was triggered.
260
+ condition_results : list[StoppingConditionResult]
261
+ Results for each individual stopping condition.
262
+ """
263
+
264
+ overall_success: bool
265
+ force_stopped: bool
266
+ condition_results: list[StoppingConditionResult]
267
+
268
+ @classmethod
269
+ def _from_proto(
270
+ cls, proto: simulationpb.GetStoppingConditionStatusResponse
271
+ ) -> "StoppingConditionStatusResult":
272
+ condition_results = []
273
+ for i, condition in enumerate(proto.conditions):
274
+ # Get the value from the status with bounds checking
275
+ value = (
276
+ proto.status.value[i].values[0].value
277
+ if i < len(proto.status.value) and proto.status.value[i].values
278
+ else float("nan")
279
+ )
280
+
281
+ # Get the threshold, checking for field presence (not truthiness)
282
+ threshold = condition.threshold.value if condition.HasField("threshold") else 0.0
283
+
284
+ # Check if this is a force condition
285
+ is_force = condition.op == outputpb.STOP_COND_OP_FORCE
286
+
287
+ # Get output name with field presence check
288
+ output_name = condition.output.name if condition.HasField("output") else ""
289
+
290
+ # Get satisfied status with bounds checking
291
+ satisfied = (
292
+ proto.status.cond_success[i] if i < len(proto.status.cond_success) else False
293
+ )
294
+
295
+ condition_results.append(
296
+ StoppingConditionResult(
297
+ output_name=output_name,
298
+ threshold=threshold,
299
+ value=value,
300
+ satisfied=satisfied,
301
+ is_force_condition=is_force,
302
+ )
303
+ )
304
+
305
+ return cls(
306
+ overall_success=proto.status.success,
307
+ force_stopped=proto.status.force_stop,
308
+ condition_results=condition_results,
309
+ )
@@ -747,6 +747,14 @@ class PtTableFluid(_IntEnum):
747
747
  R410A.
748
748
  REAL_GAS_R507A
749
749
  R507A.
750
+ REAL_GAS_R513A
751
+ R513A.
752
+ REAL_GAS_R513B
753
+ R513B.
754
+ REAL_GAS_R515A
755
+ R515A.
756
+ REAL_GAS_R515B
757
+ R515B.
750
758
  REAL_GAS_RC318
751
759
  RC318.
752
760
  REAL_GAS_SES36
@@ -883,6 +891,10 @@ class PtTableFluid(_IntEnum):
883
891
  >>> PtTableFluid.REAL_GAS_R41
884
892
  >>> PtTableFluid.REAL_GAS_R410A
885
893
  >>> PtTableFluid.REAL_GAS_R507A
894
+ >>> PtTableFluid.REAL_GAS_R513A
895
+ >>> PtTableFluid.REAL_GAS_R513B
896
+ >>> PtTableFluid.REAL_GAS_R515A
897
+ >>> PtTableFluid.REAL_GAS_R515B
886
898
  >>> PtTableFluid.REAL_GAS_RC318
887
899
  >>> PtTableFluid.REAL_GAS_SES36
888
900
  >>> PtTableFluid.REAL_GAS_SULFUR_DIOXIDE
@@ -1009,6 +1021,10 @@ class PtTableFluid(_IntEnum):
1009
1021
  REAL_GAS_R41 = _clientpb.REAL_GAS_R41
1010
1022
  REAL_GAS_R410A = _clientpb.REAL_GAS_R410A
1011
1023
  REAL_GAS_R507A = _clientpb.REAL_GAS_R507A
1024
+ REAL_GAS_R513A = _clientpb.REAL_GAS_R513A
1025
+ REAL_GAS_R513B = _clientpb.REAL_GAS_R513B
1026
+ REAL_GAS_R515A = _clientpb.REAL_GAS_R515A
1027
+ REAL_GAS_R515B = _clientpb.REAL_GAS_R515B
1012
1028
  REAL_GAS_RC318 = _clientpb.REAL_GAS_RC318
1013
1029
  REAL_GAS_SES36 = _clientpb.REAL_GAS_SES36
1014
1030
  REAL_GAS_SULFUR_DIOXIDE = _clientpb.REAL_GAS_SULFUR_DIOXIDE
@@ -1,84 +1,84 @@
1
1
  # Copyright 2024 Luminary Cloud, Inc. All Rights Reserved.
2
- from dataclasses import dataclass
2
+ from dataclasses import dataclass, field
3
3
 
4
- from luminarycloud.types import Vector3
5
- from luminarycloud._helpers.proto_decorator import proto_decorator
4
+ from luminarycloud._helpers.proto_decorator import ProtoConvertible, proto_decorator
6
5
  from luminarycloud._proto.cad import shape_pb2 as shapepb
6
+ from luminarycloud.types import Vector3
7
7
 
8
8
 
9
- class Shape:
9
+ class Shape(ProtoConvertible):
10
10
  pass
11
11
 
12
12
 
13
13
  @dataclass(kw_only=True)
14
14
  @proto_decorator(shapepb.Sphere)
15
15
  class Sphere(Shape):
16
- center: Vector3
17
- radius: float
16
+ center: Vector3 = field(default_factory=Vector3)
17
+ radius: float = 0.0
18
18
 
19
19
 
20
20
  @dataclass(kw_only=True)
21
21
  @proto_decorator(shapepb.SphereShell)
22
22
  class SphereShell(Shape):
23
- center: Vector3
24
- radius: float
25
- radius_inner: float
23
+ center: Vector3 = field(default_factory=Vector3)
24
+ radius: float = 0.0
25
+ radius_inner: float = 0.0
26
26
 
27
27
 
28
28
  @dataclass(kw_only=True)
29
29
  @proto_decorator(shapepb.HalfSphere)
30
30
  class HalfSphere(Shape):
31
- center: Vector3
32
- radius: float
33
- normal: Vector3
31
+ center: Vector3 = field(default_factory=Vector3)
32
+ radius: float = 0.0
33
+ normal: Vector3 = field(default_factory=Vector3)
34
34
 
35
35
 
36
36
  @dataclass(kw_only=True)
37
37
  @proto_decorator(shapepb.Cube)
38
38
  class Cube(Shape):
39
- min: Vector3
40
- max: Vector3
39
+ min: Vector3 = field(default_factory=Vector3)
40
+ max: Vector3 = field(default_factory=Vector3)
41
41
 
42
42
 
43
43
  @dataclass(kw_only=True)
44
44
  @proto_decorator(shapepb.OrientedCube)
45
45
  class OrientedCube(Shape):
46
- min: Vector3
47
- max: Vector3
48
- origin: Vector3
49
- x_axis: Vector3
50
- y_axis: Vector3
46
+ min: Vector3 = field(default_factory=Vector3)
47
+ max: Vector3 = field(default_factory=Vector3)
48
+ origin: Vector3 = field(default_factory=Vector3)
49
+ x_axis: Vector3 = field(default_factory=Vector3)
50
+ y_axis: Vector3 = field(default_factory=Vector3)
51
51
 
52
52
 
53
53
  @dataclass(kw_only=True)
54
54
  @proto_decorator(shapepb.Cylinder)
55
55
  class Cylinder(Shape):
56
- start: Vector3
57
- end: Vector3
58
- radius: float
56
+ start: Vector3 = field(default_factory=Vector3)
57
+ end: Vector3 = field(default_factory=Vector3)
58
+ radius: float = 0.0
59
59
 
60
60
 
61
61
  @dataclass(kw_only=True)
62
62
  @proto_decorator(shapepb.AnnularCylinder)
63
63
  class AnnularCylinder(Shape):
64
- start: Vector3
65
- end: Vector3
66
- radius: float
67
- radius_inner: float
64
+ start: Vector3 = field(default_factory=Vector3)
65
+ end: Vector3 = field(default_factory=Vector3)
66
+ radius: float = 0.0
67
+ radius_inner: float = 0.0
68
68
 
69
69
 
70
70
  @dataclass(kw_only=True)
71
71
  @proto_decorator(shapepb.Torus)
72
72
  class Torus(Shape):
73
- center: Vector3
74
- normal: Vector3
75
- major_radius: float
76
- minor_radius: float
73
+ center: Vector3 = field(default_factory=Vector3)
74
+ normal: Vector3 = field(default_factory=Vector3)
75
+ major_radius: float = 0.0
76
+ minor_radius: float = 0.0
77
77
 
78
78
 
79
79
  @dataclass(kw_only=True)
80
80
  @proto_decorator(shapepb.Cone)
81
81
  class Cone(Shape):
82
- apex: Vector3
83
- base_center: Vector3
84
- base_radius: float
82
+ apex: Vector3 = field(default_factory=Vector3)
83
+ base_center: Vector3 = field(default_factory=Vector3)
84
+ base_radius: float = 0.0
@@ -1 +1,2 @@
1
+ from .active_region_ import ActiveRegion
1
2
  from .boundary_layer_profile_ import BoundaryLayerProfile
@@ -0,0 +1,83 @@
1
+ # Generated by generate_sdk_wrappers.py. DO NOT EDIT
2
+
3
+ from abc import ABC, ABCMeta
4
+ from dataclasses import dataclass, field
5
+ from typing import Any
6
+ from uuid import uuid4
7
+
8
+ from google.protobuf.message import Message as _Message
9
+ from luminarycloud.tables import RectilinearTable, _param_name_to_table_type
10
+ from luminarycloud.types import Vector3, LcFloat
11
+ from luminarycloud.types.adfloat import _to_ad_proto, _from_ad_proto
12
+ from luminarycloud._helpers._entity_identifier import _create_entity_identifier
13
+ from luminarycloud._proto.client import simulation_pb2 as clientpb
14
+ from luminarycloud._proto.client.entity_pb2 import EntityIdentifier
15
+ from luminarycloud._helpers import CodeRepr
16
+ import luminarycloud.params.enum._enum_wrappers as enum
17
+
18
+ from luminarycloud.params.simulation._lib import ParamGroupWrapper, create_unique_id
19
+
20
+ from luminarycloud.params.geometry import shapes
21
+
22
+
23
+ @dataclass(kw_only=True)
24
+ class ActiveRegion(CodeRepr, ParamGroupWrapper[clientpb.ActiveRegion]):
25
+ """Region(s) within which the mesh is adapted at full resolution. Outside of these regions the mesh is coarsened with increasing distance from the region."""
26
+
27
+ error_weight: LcFloat = 1.0
28
+ "Error weighting from the active region at Max Distance. Local error weighting is 1.0 inside the region and decreases to Error Weight at the Max Distance."
29
+ max_distance: LcFloat = 0.0
30
+ "Distance from the active regions at which to apply the full error factor."
31
+ cube: shapes.Cube | None = None
32
+ "Coordinate-aligned box."
33
+ oriented_cube: shapes.OrientedCube | None = None
34
+ "Box oriented along arbitrary axes."
35
+ cylinder: shapes.Cylinder | None = None
36
+ "Cylinder shape."
37
+ annular_cylinder: shapes.AnnularCylinder | None = None
38
+ "Cylinder with a hole along the axis."
39
+ sphere: shapes.Sphere | None = None
40
+ "Sphere shape."
41
+ sphere_shell: shapes.SphereShell | None = None
42
+ "Spherical shell shape."
43
+
44
+ def _to_proto(self) -> clientpb.ActiveRegion:
45
+ _proto = clientpb.ActiveRegion()
46
+ _proto.error_weight.CopyFrom(_to_ad_proto(self.error_weight))
47
+ _proto.max_distance.CopyFrom(_to_ad_proto(self.max_distance))
48
+ if self.cube is not None:
49
+ _proto.cube.CopyFrom(self.cube._to_proto())
50
+ if self.oriented_cube is not None:
51
+ _proto.oriented_cube.CopyFrom(self.oriented_cube._to_proto())
52
+ if self.cylinder is not None:
53
+ _proto.cylinder.CopyFrom(self.cylinder._to_proto())
54
+ if self.annular_cylinder is not None:
55
+ _proto.annular_cylinder.CopyFrom(self.annular_cylinder._to_proto())
56
+ if self.sphere is not None:
57
+ _proto.sphere.CopyFrom(self.sphere._to_proto())
58
+ if self.sphere_shell is not None:
59
+ _proto.sphere_shell.CopyFrom(self.sphere_shell._to_proto())
60
+ return _proto
61
+
62
+ def _from_proto(self, proto: clientpb.ActiveRegion) -> None:
63
+ self.error_weight = _from_ad_proto(proto.error_weight)
64
+ self.max_distance = _from_ad_proto(proto.max_distance)
65
+ if proto.cube.ByteSize() > 0:
66
+ self.cube = shapes.Cube()
67
+ self.cube._from_proto(proto.cube)
68
+ if proto.oriented_cube.ByteSize() > 0:
69
+ self.oriented_cube = shapes.OrientedCube()
70
+ self.oriented_cube._from_proto(proto.oriented_cube)
71
+ if proto.cylinder.ByteSize() > 0:
72
+ self.cylinder = shapes.Cylinder()
73
+ self.cylinder._from_proto(proto.cylinder)
74
+ if proto.annular_cylinder.ByteSize() > 0:
75
+ self.annular_cylinder = shapes.AnnularCylinder()
76
+ self.annular_cylinder._from_proto(proto.annular_cylinder)
77
+ if proto.sphere.ByteSize() > 0:
78
+ self.sphere = shapes.Sphere()
79
+ self.sphere._from_proto(proto.sphere)
80
+ if proto.sphere_shell.ByteSize() > 0:
81
+ self.sphere_shell = shapes.SphereShell()
82
+ self.sphere_shell._from_proto(proto.sphere_shell)
83
+ return None
@@ -20,7 +20,7 @@ from luminarycloud.params.simulation._lib import ParamGroupWrapper, create_uniqu
20
20
 
21
21
  @dataclass(kw_only=True)
22
22
  class BoundaryLayerProfile(CodeRepr, ParamGroupWrapper[clientpb.BoundaryLayerProfile]):
23
- """"""
23
+ """Boundary layer meshing parameters to apply to adapted meshes."""
24
24
 
25
25
  n_layers: int = 40
26
26
  "Maximum number of prism layers within a boundary layer mesh."
@@ -17,6 +17,8 @@ import luminarycloud.params.enum._enum_wrappers as enum
17
17
 
18
18
  from luminarycloud.params.simulation._lib import ParamGroupWrapper, create_unique_id
19
19
 
20
+ from luminarycloud.params.simulation.adaptive_mesh_refinement.active_region_ import ActiveRegion
21
+ from luminarycloud.params.simulation.adaptive_mesh_refinement.active_region_ import *
20
22
  from luminarycloud.params.simulation.adaptive_mesh_refinement.boundary_layer_profile_ import (
21
23
  BoundaryLayerProfile,
22
24
  )
@@ -46,7 +48,9 @@ class AdaptiveMeshRefinement(CodeRepr, ParamGroupWrapper[clientpb.AdaptiveMeshRe
46
48
  user_scaling: LcFloat = 1.0
47
49
  "Scale factor between the geometry and the mesh."
48
50
  boundary_layer_profile: list[BoundaryLayerProfile] = field(default_factory=list)
49
- ""
51
+ "Boundary layer meshing parameters to apply to adapted meshes."
52
+ active_region: list[ActiveRegion] = field(default_factory=list)
53
+ "Region(s) within which the mesh is adapted at full resolution. Outside of these regions the mesh is coarsened with increasing distance from the region."
50
54
 
51
55
  def _to_proto(self) -> clientpb.AdaptiveMeshRefinement:
52
56
  _proto = clientpb.AdaptiveMeshRefinement()
@@ -61,6 +65,8 @@ class AdaptiveMeshRefinement(CodeRepr, ParamGroupWrapper[clientpb.AdaptiveMeshRe
61
65
  _proto.user_scaling.CopyFrom(_to_ad_proto(self.user_scaling))
62
66
  if self.boundary_layer_profile is not None:
63
67
  _proto.boundary_layer_profile.extend(v._to_proto() for v in self.boundary_layer_profile)
68
+ if self.active_region is not None:
69
+ _proto.active_region.extend(v._to_proto() for v in self.active_region)
64
70
  return _proto
65
71
 
66
72
  def _from_proto(self, proto: clientpb.AdaptiveMeshRefinement) -> None:
@@ -76,4 +82,5 @@ class AdaptiveMeshRefinement(CodeRepr, ParamGroupWrapper[clientpb.AdaptiveMeshRe
76
82
  self.boundary_layer_profile = [
77
83
  BoundaryLayerProfile.from_proto(v) for v in proto.boundary_layer_profile
78
84
  ]
85
+ self.active_region = [ActiveRegion.from_proto(v) for v in proto.active_region]
79
86
  return None
@@ -12,3 +12,10 @@ from .models import (
12
12
  from .solution import (
13
13
  _download_processed_solution_physics_ai as _download_processed_solution_physics_ai,
14
14
  )
15
+
16
+ from .inference import (
17
+ InferenceJob as InferenceJob,
18
+ SurfaceForInference as SurfaceForInference,
19
+ VisualizationExport as VisualizationExport,
20
+ NumericResult as NumericResult,
21
+ )