luminarycloud 0.22.1__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.
- luminarycloud/_client/client.py +5 -3
- luminarycloud/_helpers/__init__.py +9 -0
- luminarycloud/_helpers/_inference_jobs.py +227 -0
- luminarycloud/_helpers/_parse_iso_datetime.py +54 -0
- luminarycloud/_helpers/proto_decorator.py +38 -7
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.py +45 -25
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.pyi +30 -0
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +118 -45
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +246 -2
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.py +34 -0
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.pyi +12 -0
- luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2.py +93 -33
- luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2.pyi +105 -0
- luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2_grpc.py +70 -0
- luminarycloud/_proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference_pb2_grpc.pyi +29 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.py +29 -7
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.pyi +39 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.py +36 -0
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.pyi +18 -0
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.py +70 -70
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.pyi +5 -5
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.py +163 -153
- luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.pyi +37 -3
- luminarycloud/_proto/client/simulation_pb2.py +356 -337
- luminarycloud/_proto/client/simulation_pb2.pyi +89 -3
- luminarycloud/_proto/physicsaiinferenceservice/physicsaiinferenceservice_pb2.py +9 -4
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2.py +6 -3
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.py +34 -0
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.pyi +12 -0
- luminarycloud/_wrapper.py +53 -7
- luminarycloud/feature_modification.py +25 -32
- luminarycloud/geometry.py +6 -6
- luminarycloud/outputs/__init__.py +2 -0
- luminarycloud/outputs/output_definitions.py +3 -3
- luminarycloud/outputs/stopping_conditions.py +94 -0
- luminarycloud/params/enum/_enum_wrappers.py +16 -0
- luminarycloud/params/geometry/shapes.py +33 -33
- luminarycloud/params/simulation/adaptive_mesh_refinement/__init__.py +1 -0
- luminarycloud/params/simulation/adaptive_mesh_refinement/active_region_.py +83 -0
- luminarycloud/params/simulation/adaptive_mesh_refinement/boundary_layer_profile_.py +1 -1
- luminarycloud/params/simulation/adaptive_mesh_refinement_.py +8 -1
- luminarycloud/physics_ai/__init__.py +7 -0
- luminarycloud/physics_ai/inference.py +166 -199
- luminarycloud/physics_ai/models.py +22 -0
- luminarycloud/pipelines/api.py +45 -9
- luminarycloud/project.py +56 -2
- luminarycloud/simulation.py +25 -0
- luminarycloud/types/__init__.py +2 -0
- luminarycloud/types/ids.py +2 -0
- luminarycloud/vis/__init__.py +1 -0
- luminarycloud/vis/filters.py +97 -0
- luminarycloud/vis/visualization.py +3 -0
- luminarycloud/volume_selection.py +6 -6
- luminarycloud/workflow_utils.py +149 -0
- {luminarycloud-0.22.1.dist-info → luminarycloud-0.22.2.dist-info}/METADATA +1 -1
- {luminarycloud-0.22.1.dist-info → luminarycloud-0.22.2.dist-info}/RECORD +59 -60
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.py +0 -61
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.pyi +0 -85
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2_grpc.py +0 -67
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2_grpc.pyi +0 -26
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.py +0 -69
- {luminarycloud-0.22.1.dist-info → luminarycloud-0.22.2.dist-info}/WHEEL +0 -0
|
@@ -9,6 +9,7 @@ import google.protobuf.internal.containers
|
|
|
9
9
|
import google.protobuf.internal.enum_type_wrapper
|
|
10
10
|
import google.protobuf.message
|
|
11
11
|
import luminarycloud._proto.base.base_pb2
|
|
12
|
+
import luminarycloud._proto.cad.shape_pb2
|
|
12
13
|
import luminarycloud._proto.client.entity_pb2
|
|
13
14
|
import luminarycloud._proto.entitygroup.entitygroup_pb2
|
|
14
15
|
import luminarycloud._proto.output.output_pb2
|
|
@@ -740,6 +741,14 @@ class _PtTableFluidEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._E
|
|
|
740
741
|
"""R410A."""
|
|
741
742
|
REAL_GAS_R507A: _PtTableFluid.ValueType # 56561
|
|
742
743
|
"""R507A."""
|
|
744
|
+
REAL_GAS_R513A: _PtTableFluid.ValueType # 13621
|
|
745
|
+
"""R513A."""
|
|
746
|
+
REAL_GAS_R513B: _PtTableFluid.ValueType # 5656
|
|
747
|
+
"""R513B."""
|
|
748
|
+
REAL_GAS_R515A: _PtTableFluid.ValueType # 55001
|
|
749
|
+
"""R515A."""
|
|
750
|
+
REAL_GAS_R515B: _PtTableFluid.ValueType # 5076
|
|
751
|
+
"""R515B."""
|
|
743
752
|
REAL_GAS_RC318: _PtTableFluid.ValueType # 66529
|
|
744
753
|
"""RC318."""
|
|
745
754
|
REAL_GAS_SES36: _PtTableFluid.ValueType # 14408
|
|
@@ -990,6 +999,14 @@ REAL_GAS_R410A: PtTableFluid.ValueType # 59981
|
|
|
990
999
|
"""R410A."""
|
|
991
1000
|
REAL_GAS_R507A: PtTableFluid.ValueType # 56561
|
|
992
1001
|
"""R507A."""
|
|
1002
|
+
REAL_GAS_R513A: PtTableFluid.ValueType # 13621
|
|
1003
|
+
"""R513A."""
|
|
1004
|
+
REAL_GAS_R513B: PtTableFluid.ValueType # 5656
|
|
1005
|
+
"""R513B."""
|
|
1006
|
+
REAL_GAS_R515A: PtTableFluid.ValueType # 55001
|
|
1007
|
+
"""R515A."""
|
|
1008
|
+
REAL_GAS_R515B: PtTableFluid.ValueType # 5076
|
|
1009
|
+
"""R515B."""
|
|
993
1010
|
REAL_GAS_RC318: PtTableFluid.ValueType # 66529
|
|
994
1011
|
"""RC318."""
|
|
995
1012
|
REAL_GAS_SES36: PtTableFluid.ValueType # 14408
|
|
@@ -4469,7 +4486,7 @@ class ReferenceValues(google.protobuf.message.Message):
|
|
|
4469
4486
|
global___ReferenceValues = ReferenceValues
|
|
4470
4487
|
|
|
4471
4488
|
class BoundaryLayerProfile(google.protobuf.message.Message):
|
|
4472
|
-
"""
|
|
4489
|
+
"""Boundary layer meshing parameters to apply to adapted meshes."""
|
|
4473
4490
|
|
|
4474
4491
|
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
4475
4492
|
|
|
@@ -4502,6 +4519,67 @@ class BoundaryLayerProfile(google.protobuf.message.Message):
|
|
|
4502
4519
|
|
|
4503
4520
|
global___BoundaryLayerProfile = BoundaryLayerProfile
|
|
4504
4521
|
|
|
4522
|
+
class ActiveRegion(google.protobuf.message.Message):
|
|
4523
|
+
"""Region(s) within which the mesh is adapted at full resolution. Outside
|
|
4524
|
+
of these regions the mesh is coarsened with increasing distance from the
|
|
4525
|
+
region.
|
|
4526
|
+
"""
|
|
4527
|
+
|
|
4528
|
+
DESCRIPTOR: google.protobuf.descriptor.Descriptor
|
|
4529
|
+
|
|
4530
|
+
ERROR_WEIGHT_FIELD_NUMBER: builtins.int
|
|
4531
|
+
MAX_DISTANCE_FIELD_NUMBER: builtins.int
|
|
4532
|
+
CUBE_FIELD_NUMBER: builtins.int
|
|
4533
|
+
ORIENTED_CUBE_FIELD_NUMBER: builtins.int
|
|
4534
|
+
CYLINDER_FIELD_NUMBER: builtins.int
|
|
4535
|
+
ANNULAR_CYLINDER_FIELD_NUMBER: builtins.int
|
|
4536
|
+
SPHERE_FIELD_NUMBER: builtins.int
|
|
4537
|
+
SPHERE_SHELL_FIELD_NUMBER: builtins.int
|
|
4538
|
+
@property
|
|
4539
|
+
def error_weight(self) -> luminarycloud._proto.base.base_pb2.AdFloatType:
|
|
4540
|
+
"""Error weighting from the active region at Max Distance. Local error
|
|
4541
|
+
weighting is 1.0 inside the region and decreases to Error Weight at the Max
|
|
4542
|
+
Distance.
|
|
4543
|
+
"""
|
|
4544
|
+
@property
|
|
4545
|
+
def max_distance(self) -> luminarycloud._proto.base.base_pb2.AdFloatType:
|
|
4546
|
+
"""Distance from the active regions at which to apply the full error factor."""
|
|
4547
|
+
@property
|
|
4548
|
+
def cube(self) -> luminarycloud._proto.cad.shape_pb2.Cube:
|
|
4549
|
+
"""Coordinate-aligned box."""
|
|
4550
|
+
@property
|
|
4551
|
+
def oriented_cube(self) -> luminarycloud._proto.cad.shape_pb2.OrientedCube:
|
|
4552
|
+
"""Box oriented along arbitrary axes."""
|
|
4553
|
+
@property
|
|
4554
|
+
def cylinder(self) -> luminarycloud._proto.cad.shape_pb2.Cylinder:
|
|
4555
|
+
"""Cylinder shape."""
|
|
4556
|
+
@property
|
|
4557
|
+
def annular_cylinder(self) -> luminarycloud._proto.cad.shape_pb2.AnnularCylinder:
|
|
4558
|
+
"""Cylinder with a hole along the axis."""
|
|
4559
|
+
@property
|
|
4560
|
+
def sphere(self) -> luminarycloud._proto.cad.shape_pb2.Sphere:
|
|
4561
|
+
"""Sphere shape."""
|
|
4562
|
+
@property
|
|
4563
|
+
def sphere_shell(self) -> luminarycloud._proto.cad.shape_pb2.SphereShell:
|
|
4564
|
+
"""Spherical shell shape."""
|
|
4565
|
+
def __init__(
|
|
4566
|
+
self,
|
|
4567
|
+
*,
|
|
4568
|
+
error_weight: luminarycloud._proto.base.base_pb2.AdFloatType | None = ...,
|
|
4569
|
+
max_distance: luminarycloud._proto.base.base_pb2.AdFloatType | None = ...,
|
|
4570
|
+
cube: luminarycloud._proto.cad.shape_pb2.Cube | None = ...,
|
|
4571
|
+
oriented_cube: luminarycloud._proto.cad.shape_pb2.OrientedCube | None = ...,
|
|
4572
|
+
cylinder: luminarycloud._proto.cad.shape_pb2.Cylinder | None = ...,
|
|
4573
|
+
annular_cylinder: luminarycloud._proto.cad.shape_pb2.AnnularCylinder | None = ...,
|
|
4574
|
+
sphere: luminarycloud._proto.cad.shape_pb2.Sphere | None = ...,
|
|
4575
|
+
sphere_shell: luminarycloud._proto.cad.shape_pb2.SphereShell | None = ...,
|
|
4576
|
+
) -> None: ...
|
|
4577
|
+
def HasField(self, field_name: typing_extensions.Literal["annular_cylinder", b"annular_cylinder", "cube", b"cube", "cylinder", b"cylinder", "error_weight", b"error_weight", "max_distance", b"max_distance", "oriented_cube", b"oriented_cube", "shape", b"shape", "sphere", b"sphere", "sphere_shell", b"sphere_shell"]) -> builtins.bool: ...
|
|
4578
|
+
def ClearField(self, field_name: typing_extensions.Literal["annular_cylinder", b"annular_cylinder", "cube", b"cube", "cylinder", b"cylinder", "error_weight", b"error_weight", "max_distance", b"max_distance", "oriented_cube", b"oriented_cube", "shape", b"shape", "sphere", b"sphere", "sphere_shell", b"sphere_shell"]) -> None: ...
|
|
4579
|
+
def WhichOneof(self, oneof_group: typing_extensions.Literal["shape", b"shape"]) -> typing_extensions.Literal["cube", "oriented_cube", "cylinder", "annular_cylinder", "sphere", "sphere_shell"] | None: ...
|
|
4580
|
+
|
|
4581
|
+
global___ActiveRegion = ActiveRegion
|
|
4582
|
+
|
|
4505
4583
|
class AdaptiveMeshRefinement(google.protobuf.message.Message):
|
|
4506
4584
|
"""Adaptive Mesh Refinement"""
|
|
4507
4585
|
|
|
@@ -4517,6 +4595,7 @@ class AdaptiveMeshRefinement(google.protobuf.message.Message):
|
|
|
4517
4595
|
ALL_TET_FIELD_NUMBER: builtins.int
|
|
4518
4596
|
USER_SCALING_FIELD_NUMBER: builtins.int
|
|
4519
4597
|
BOUNDARY_LAYER_PROFILE_FIELD_NUMBER: builtins.int
|
|
4598
|
+
ACTIVE_REGION_FIELD_NUMBER: builtins.int
|
|
4520
4599
|
@property
|
|
4521
4600
|
def refinement_iterations(self) -> luminarycloud._proto.base.base_pb2.Int:
|
|
4522
4601
|
"""Number of refinement iterations to perform."""
|
|
@@ -4546,7 +4625,13 @@ class AdaptiveMeshRefinement(google.protobuf.message.Message):
|
|
|
4546
4625
|
"""Scale factor between the geometry and the mesh."""
|
|
4547
4626
|
@property
|
|
4548
4627
|
def boundary_layer_profile(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___BoundaryLayerProfile]:
|
|
4549
|
-
"""
|
|
4628
|
+
"""Boundary layer meshing parameters to apply to adapted meshes."""
|
|
4629
|
+
@property
|
|
4630
|
+
def active_region(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[global___ActiveRegion]:
|
|
4631
|
+
"""Region(s) within which the mesh is adapted at full resolution. Outside
|
|
4632
|
+
of these regions the mesh is coarsened with increasing distance from the
|
|
4633
|
+
region.
|
|
4634
|
+
"""
|
|
4550
4635
|
def __init__(
|
|
4551
4636
|
self,
|
|
4552
4637
|
*,
|
|
@@ -4560,9 +4645,10 @@ class AdaptiveMeshRefinement(google.protobuf.message.Message):
|
|
|
4560
4645
|
all_tet: global___AllTet.ValueType = ...,
|
|
4561
4646
|
user_scaling: luminarycloud._proto.base.base_pb2.AdFloatType | None = ...,
|
|
4562
4647
|
boundary_layer_profile: collections.abc.Iterable[global___BoundaryLayerProfile] | None = ...,
|
|
4648
|
+
active_region: collections.abc.Iterable[global___ActiveRegion] | None = ...,
|
|
4563
4649
|
) -> None: ...
|
|
4564
4650
|
def HasField(self, field_name: typing_extensions.Literal["final_target_complexity", b"final_target_complexity", "initial_target_complexity", b"initial_target_complexity", "max_refinement_interval", b"max_refinement_interval", "refinement_dispatch_interval", b"refinement_dispatch_interval", "refinement_iterations", b"refinement_iterations", "target_cv_millions", b"target_cv_millions", "user_scaling", b"user_scaling"]) -> builtins.bool: ...
|
|
4565
|
-
def ClearField(self, field_name: typing_extensions.Literal["all_tet", b"all_tet", "boundary_layer_profile", b"boundary_layer_profile", "final_target_complexity", b"final_target_complexity", "initial_target_complexity", b"initial_target_complexity", "max_refinement_interval", b"max_refinement_interval", "meshing_method", b"meshing_method", "refinement_dispatch_interval", b"refinement_dispatch_interval", "refinement_iterations", b"refinement_iterations", "target_cv_millions", b"target_cv_millions", "user_scaling", b"user_scaling"]) -> None: ...
|
|
4651
|
+
def ClearField(self, field_name: typing_extensions.Literal["active_region", b"active_region", "all_tet", b"all_tet", "boundary_layer_profile", b"boundary_layer_profile", "final_target_complexity", b"final_target_complexity", "initial_target_complexity", b"initial_target_complexity", "max_refinement_interval", b"max_refinement_interval", "meshing_method", b"meshing_method", "refinement_dispatch_interval", b"refinement_dispatch_interval", "refinement_iterations", b"refinement_iterations", "target_cv_millions", b"target_cv_millions", "user_scaling", b"user_scaling"]) -> None: ...
|
|
4566
4652
|
|
|
4567
4653
|
global___AdaptiveMeshRefinement = AdaptiveMeshRefinement
|
|
4568
4654
|
|
|
@@ -12,11 +12,12 @@ from google.protobuf import symbol_database as _symbol_database
|
|
|
12
12
|
_sym_db = _symbol_database.Default()
|
|
13
13
|
|
|
14
14
|
|
|
15
|
-
from
|
|
15
|
+
from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2
|
|
16
16
|
from luminarycloud._proto.api.v0.luminarycloud.physicsaiinference import physicsaiinference_pb2 as proto_dot_api_dot_v0_dot_luminarycloud_dot_physicsaiinference_dot_physicsaiinference__pb2
|
|
17
|
+
from luminarycloud._proto.ratelimit import ratelimit_pb2 as proto_dot_ratelimit_dot_ratelimit__pb2
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n?proto/physicsaiinferenceservice/physicsaiinferenceservice.proto\x12(luminary.proto.physicsaiinferenceservice\x1a\
|
|
20
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n?proto/physicsaiinferenceservice/physicsaiinferenceservice.proto\x12(luminary.proto.physicsaiinferenceservice\x1a\x1bgoogle/protobuf/empty.proto\x1a\x46proto/api/v0/luminarycloud/physicsaiinference/physicsaiinference.proto\x1a\x1fproto/ratelimit/ratelimit.proto2\xb1\t\n\x19PhysicsAiInferenceService\x12\xd9\x01\n\x19\x43reateInferenceServiceJob\x12X.luminary.proto.api.v0.luminarycloud.physicsaiinference.CreateInferenceServiceJobRequest\x1aV.luminary.proto.api.v0.luminarycloud.physicsaiinference.GetInferenceServiceJobResponse\"\n\x8a\xb5\x18\x06\x08\n\x12\x02\x08\x01\x12\xde\x01\n\x1e\x43reateInferenceServiceJobAsync\x12X.luminary.proto.api.v0.luminarycloud.physicsaiinference.CreateInferenceServiceJobRequest\x1aV.luminary.proto.api.v0.luminarycloud.physicsaiinference.GetInferenceServiceJobResponse\"\n\x8a\xb5\x18\x06\x08\n\x12\x02\x08\x01\x12\xbb\x01\n\x12GetInferenceFields\x12Q.luminary.proto.api.v0.luminarycloud.physicsaiinference.GetInferenceFieldsRequest\x1aR.luminary.proto.api.v0.luminarycloud.physicsaiinference.GetInferenceFieldsResponse\x12\xc7\x01\n\x16GetInferenceServiceJob\x12U.luminary.proto.api.v0.luminarycloud.physicsaiinference.GetInferenceServiceJobRequest\x1aV.luminary.proto.api.v0.luminarycloud.physicsaiinference.GetInferenceServiceJobResponse\x12\xcd\x01\n\x18ListInferenceServiceJobs\x12W.luminary.proto.api.v0.luminarycloud.physicsaiinference.ListInferenceServiceJobsRequest\x1aX.luminary.proto.api.v0.luminarycloud.physicsaiinference.ListInferenceServiceJobsResponse\x12\x7f\n\x12\x44\x65leteInferenceJob\x12Q.luminary.proto.api.v0.luminarycloud.physicsaiinference.DeleteInferenceJobRequest\x1a\x16.google.protobuf.EmptyB8Z6luminarycloud.com/core/proto/physicsaiinferenceserviceb\x06proto3')
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
|
|
@@ -25,6 +26,10 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
|
25
26
|
|
|
26
27
|
DESCRIPTOR._options = None
|
|
27
28
|
DESCRIPTOR._serialized_options = b'Z6luminarycloud.com/core/proto/physicsaiinferenceservice'
|
|
28
|
-
_PHYSICSAIINFERENCESERVICE.
|
|
29
|
-
_PHYSICSAIINFERENCESERVICE.
|
|
29
|
+
_PHYSICSAIINFERENCESERVICE.methods_by_name['CreateInferenceServiceJob']._options = None
|
|
30
|
+
_PHYSICSAIINFERENCESERVICE.methods_by_name['CreateInferenceServiceJob']._serialized_options = b'\212\265\030\006\010\n\022\002\010\001'
|
|
31
|
+
_PHYSICSAIINFERENCESERVICE.methods_by_name['CreateInferenceServiceJobAsync']._options = None
|
|
32
|
+
_PHYSICSAIINFERENCESERVICE.methods_by_name['CreateInferenceServiceJobAsync']._serialized_options = b'\212\265\030\006\010\n\022\002\010\001'
|
|
33
|
+
_PHYSICSAIINFERENCESERVICE._serialized_start=244
|
|
34
|
+
_PHYSICSAIINFERENCESERVICE._serialized_end=1445
|
|
30
35
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -13,9 +13,10 @@ _sym_db = _symbol_database.Default()
|
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
from luminarycloud._proto.api.v0.luminarycloud.physics_ai import physics_ai_pb2 as proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2
|
|
16
|
+
from luminarycloud._proto.ratelimit import ratelimit_pb2 as proto_dot_ratelimit_dot_ratelimit__pb2
|
|
16
17
|
|
|
17
18
|
|
|
18
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n=proto/physicsaitrainingservice/physicsaitrainingservice.proto\x12\'luminary.proto.physicsaitrainingservice\x1a\x36proto/api/v0/luminarycloud/physics_ai/physics_ai.proto2\
|
|
19
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n=proto/physicsaitrainingservice/physicsaitrainingservice.proto\x12\'luminary.proto.physicsaitrainingservice\x1a\x36proto/api/v0/luminarycloud/physics_ai/physics_ai.proto\x1a\x1fproto/ratelimit/ratelimit.proto2\x9f\x04\n\x18PhysicsAiTrainingService\x12\x9e\x01\n\rCreateDataset\x12\x44.luminary.proto.api.v0.luminarycloud.physics_ai.CreateDatasetRequest\x1a\x45.luminary.proto.api.v0.luminarycloud.physics_ai.CreateDatasetResponse\"\x00\x12\xb4\x01\n\x11SubmitTrainingJob\x12H.luminary.proto.api.v0.luminarycloud.physics_ai.SubmitTrainingJobRequest\x1aI.luminary.proto.api.v0.luminarycloud.physics_ai.SubmitTrainingJobResponse\"\n\x8a\xb5\x18\x06\x08\x05\x12\x02\x08\x01\x12\xaa\x01\n\x11\x43\x61ncelTrainingJob\x12H.luminary.proto.api.v0.luminarycloud.physics_ai.CancelTrainingJobRequest\x1aI.luminary.proto.api.v0.luminarycloud.physics_ai.CancelTrainingJobResponse\"\x00\x42\x37Z5luminarycloud.com/core/proto/physicsaitrainingserviceb\x06proto3')
|
|
19
20
|
|
|
20
21
|
|
|
21
22
|
|
|
@@ -24,6 +25,8 @@ if _descriptor._USE_C_DESCRIPTORS == False:
|
|
|
24
25
|
|
|
25
26
|
DESCRIPTOR._options = None
|
|
26
27
|
DESCRIPTOR._serialized_options = b'Z5luminarycloud.com/core/proto/physicsaitrainingservice'
|
|
27
|
-
_PHYSICSAITRAININGSERVICE.
|
|
28
|
-
_PHYSICSAITRAININGSERVICE.
|
|
28
|
+
_PHYSICSAITRAININGSERVICE.methods_by_name['SubmitTrainingJob']._options = None
|
|
29
|
+
_PHYSICSAITRAININGSERVICE.methods_by_name['SubmitTrainingJob']._serialized_options = b'\212\265\030\006\010\005\022\002\010\001'
|
|
30
|
+
_PHYSICSAITRAININGSERVICE._serialized_start=196
|
|
31
|
+
_PHYSICSAITRAININGSERVICE._serialized_end=739
|
|
29
32
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -15,6 +15,11 @@ class PhysicsAiTrainingServiceStub(object):
|
|
|
15
15
|
Args:
|
|
16
16
|
channel: A grpc.Channel.
|
|
17
17
|
"""
|
|
18
|
+
self.CreateDataset = channel.unary_unary(
|
|
19
|
+
'/luminary.proto.physicsaitrainingservice.PhysicsAiTrainingService/CreateDataset',
|
|
20
|
+
request_serializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.CreateDatasetRequest.SerializeToString,
|
|
21
|
+
response_deserializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.CreateDatasetResponse.FromString,
|
|
22
|
+
)
|
|
18
23
|
self.SubmitTrainingJob = channel.unary_unary(
|
|
19
24
|
'/luminary.proto.physicsaitrainingservice.PhysicsAiTrainingService/SubmitTrainingJob',
|
|
20
25
|
request_serializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.SubmitTrainingJobRequest.SerializeToString,
|
|
@@ -31,6 +36,13 @@ class PhysicsAiTrainingServiceServicer(object):
|
|
|
31
36
|
"""PhysicsAiTrainingService provides training functionality for Physics AI
|
|
32
37
|
"""
|
|
33
38
|
|
|
39
|
+
def CreateDataset(self, request, context):
|
|
40
|
+
"""Create a Physics AI dataset
|
|
41
|
+
"""
|
|
42
|
+
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
|
|
43
|
+
context.set_details('Method not implemented!')
|
|
44
|
+
raise NotImplementedError('Method not implemented!')
|
|
45
|
+
|
|
34
46
|
def SubmitTrainingJob(self, request, context):
|
|
35
47
|
"""Submit a physics AI training job
|
|
36
48
|
"""
|
|
@@ -48,6 +60,11 @@ class PhysicsAiTrainingServiceServicer(object):
|
|
|
48
60
|
|
|
49
61
|
def add_PhysicsAiTrainingServiceServicer_to_server(servicer, server):
|
|
50
62
|
rpc_method_handlers = {
|
|
63
|
+
'CreateDataset': grpc.unary_unary_rpc_method_handler(
|
|
64
|
+
servicer.CreateDataset,
|
|
65
|
+
request_deserializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.CreateDatasetRequest.FromString,
|
|
66
|
+
response_serializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.CreateDatasetResponse.SerializeToString,
|
|
67
|
+
),
|
|
51
68
|
'SubmitTrainingJob': grpc.unary_unary_rpc_method_handler(
|
|
52
69
|
servicer.SubmitTrainingJob,
|
|
53
70
|
request_deserializer=proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.SubmitTrainingJobRequest.FromString,
|
|
@@ -69,6 +86,23 @@ class PhysicsAiTrainingService(object):
|
|
|
69
86
|
"""PhysicsAiTrainingService provides training functionality for Physics AI
|
|
70
87
|
"""
|
|
71
88
|
|
|
89
|
+
@staticmethod
|
|
90
|
+
def CreateDataset(request,
|
|
91
|
+
target,
|
|
92
|
+
options=(),
|
|
93
|
+
channel_credentials=None,
|
|
94
|
+
call_credentials=None,
|
|
95
|
+
insecure=False,
|
|
96
|
+
compression=None,
|
|
97
|
+
wait_for_ready=None,
|
|
98
|
+
timeout=None,
|
|
99
|
+
metadata=None):
|
|
100
|
+
return grpc.experimental.unary_unary(request, target, '/luminary.proto.physicsaitrainingservice.PhysicsAiTrainingService/CreateDataset',
|
|
101
|
+
proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.CreateDatasetRequest.SerializeToString,
|
|
102
|
+
proto_dot_api_dot_v0_dot_luminarycloud_dot_physics__ai_dot_physics__ai__pb2.CreateDatasetResponse.FromString,
|
|
103
|
+
options, channel_credentials,
|
|
104
|
+
insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
|
|
105
|
+
|
|
72
106
|
@staticmethod
|
|
73
107
|
def SubmitTrainingJob(request,
|
|
74
108
|
target,
|
|
@@ -10,6 +10,11 @@ class PhysicsAiTrainingServiceStub:
|
|
|
10
10
|
"""PhysicsAiTrainingService provides training functionality for Physics AI"""
|
|
11
11
|
|
|
12
12
|
def __init__(self, channel: grpc.Channel) -> None: ...
|
|
13
|
+
CreateDataset: grpc.UnaryUnaryMultiCallable[
|
|
14
|
+
luminarycloud._proto.api.v0.luminarycloud.physics_ai.physics_ai_pb2.CreateDatasetRequest,
|
|
15
|
+
luminarycloud._proto.api.v0.luminarycloud.physics_ai.physics_ai_pb2.CreateDatasetResponse,
|
|
16
|
+
]
|
|
17
|
+
"""Create a Physics AI dataset"""
|
|
13
18
|
SubmitTrainingJob: grpc.UnaryUnaryMultiCallable[
|
|
14
19
|
luminarycloud._proto.api.v0.luminarycloud.physics_ai.physics_ai_pb2.SubmitTrainingJobRequest,
|
|
15
20
|
luminarycloud._proto.api.v0.luminarycloud.physics_ai.physics_ai_pb2.SubmitTrainingJobResponse,
|
|
@@ -24,6 +29,13 @@ class PhysicsAiTrainingServiceStub:
|
|
|
24
29
|
class PhysicsAiTrainingServiceServicer(metaclass=abc.ABCMeta):
|
|
25
30
|
"""PhysicsAiTrainingService provides training functionality for Physics AI"""
|
|
26
31
|
|
|
32
|
+
@abc.abstractmethod
|
|
33
|
+
def CreateDataset(
|
|
34
|
+
self,
|
|
35
|
+
request: luminarycloud._proto.api.v0.luminarycloud.physics_ai.physics_ai_pb2.CreateDatasetRequest,
|
|
36
|
+
context: grpc.ServicerContext,
|
|
37
|
+
) -> luminarycloud._proto.api.v0.luminarycloud.physics_ai.physics_ai_pb2.CreateDatasetResponse:
|
|
38
|
+
"""Create a Physics AI dataset"""
|
|
27
39
|
@abc.abstractmethod
|
|
28
40
|
def SubmitTrainingJob(
|
|
29
41
|
self,
|
luminarycloud/_wrapper.py
CHANGED
|
@@ -103,20 +103,62 @@ class ProtoWrapper(Generic[P]):
|
|
|
103
103
|
def getter(field_name: str) -> Any:
|
|
104
104
|
return lambda self: getattr(self._proto, field_name)
|
|
105
105
|
|
|
106
|
-
def wrapped_getter(field_name: str, wrapper: type
|
|
107
|
-
|
|
106
|
+
def wrapped_getter(field_name: str, wrapper: type) -> Any:
|
|
107
|
+
def _get(self):
|
|
108
|
+
proto_value = getattr(self._proto, field_name)
|
|
109
|
+
|
|
110
|
+
# If it's a ProtoWrapperBase, use the standard pattern
|
|
111
|
+
if issubclass(wrapper, ProtoWrapperBase):
|
|
112
|
+
return wrapper(proto_value)
|
|
113
|
+
|
|
114
|
+
# If it's Vector3, use the conversion pattern
|
|
115
|
+
if wrapper is Vector3:
|
|
116
|
+
return Vector3(
|
|
117
|
+
x=float(proto_value.x), y=float(proto_value.y), z=float(proto_value.z)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# For other types, try the constructor directly
|
|
121
|
+
try:
|
|
122
|
+
return wrapper(proto_value)
|
|
123
|
+
except (TypeError, ValueError):
|
|
124
|
+
# Fallback: return the proto value as-is
|
|
125
|
+
return proto_value
|
|
126
|
+
|
|
127
|
+
return _get
|
|
108
128
|
|
|
109
129
|
# This binds the field name to the setter.
|
|
110
130
|
def setter(field_name: str) -> Callable[[C, Any], None]:
|
|
111
131
|
return lambda self, value: setattr(self._proto, field_name, value)
|
|
112
132
|
|
|
113
|
-
def wrapped_setter(
|
|
114
|
-
field_name: str, wrapper: type[ProtoWrapperBase]
|
|
115
|
-
) -> Callable[[C, Any], None]:
|
|
133
|
+
def wrapped_setter(field_name: str, wrapper: type) -> Callable[[C, Any], None]:
|
|
116
134
|
def _set(self: C, value: Any) -> None:
|
|
117
135
|
if not isinstance(value, wrapper):
|
|
118
136
|
raise TypeError(f"{field_name} should be a {wrapper.__name__}")
|
|
119
|
-
|
|
137
|
+
|
|
138
|
+
# If it's a ProtoWrapperBase, extract the _proto
|
|
139
|
+
if issubclass(wrapper, ProtoWrapperBase):
|
|
140
|
+
# For protobuf message fields, use CopyFrom instead of direct assignment
|
|
141
|
+
proto_field = getattr(self._proto, field_name)
|
|
142
|
+
proto_field.CopyFrom(value._proto)
|
|
143
|
+
|
|
144
|
+
# If it's Vector3, convert to protobuf Vector3
|
|
145
|
+
elif wrapper is Vector3:
|
|
146
|
+
proto_field = getattr(self._proto, field_name)
|
|
147
|
+
proto_field.x = float(value.x)
|
|
148
|
+
proto_field.y = float(value.y)
|
|
149
|
+
proto_field.z = float(value.z)
|
|
150
|
+
|
|
151
|
+
# For other types, try direct assignment or conversion
|
|
152
|
+
else:
|
|
153
|
+
try:
|
|
154
|
+
# Try using _to_proto method if it exists
|
|
155
|
+
if hasattr(value, "_to_proto"):
|
|
156
|
+
setattr(self._proto, field_name, value._to_proto())
|
|
157
|
+
else:
|
|
158
|
+
setattr(self._proto, field_name, value)
|
|
159
|
+
except (TypeError, ValueError, AttributeError):
|
|
160
|
+
# Fallback: direct assignment
|
|
161
|
+
setattr(self._proto, field_name, value)
|
|
120
162
|
|
|
121
163
|
return _set
|
|
122
164
|
|
|
@@ -148,7 +190,11 @@ class ProtoWrapper(Generic[P]):
|
|
|
148
190
|
pass
|
|
149
191
|
else:
|
|
150
192
|
try:
|
|
151
|
-
if
|
|
193
|
+
if (
|
|
194
|
+
issubclass(_type, Enum)
|
|
195
|
+
or issubclass(_type, ProtoWrapperBase)
|
|
196
|
+
or _type is Vector3
|
|
197
|
+
):
|
|
152
198
|
fget = wrapped_getter(field.name, _type)
|
|
153
199
|
fset = wrapped_setter(field.name, _type)
|
|
154
200
|
except TypeError:
|
|
@@ -148,6 +148,29 @@ def _update_repeated_field(
|
|
|
148
148
|
target_field.extend(new_values)
|
|
149
149
|
|
|
150
150
|
|
|
151
|
+
def _update_create_op_from_shape(create_op: gpb.Create, shape: Shape) -> None:
|
|
152
|
+
"""Helper function to replace the shape in a gpb.Create operation with a shape object.
|
|
153
|
+
|
|
154
|
+
Args:
|
|
155
|
+
create: The gpb.Create to modify
|
|
156
|
+
shape: The shape to add
|
|
157
|
+
"""
|
|
158
|
+
if isinstance(shape, Sphere):
|
|
159
|
+
create_op.sphere.CopyFrom(shape._to_proto())
|
|
160
|
+
elif isinstance(shape, Cube):
|
|
161
|
+
create_op.box.CopyFrom(shape._to_proto())
|
|
162
|
+
elif isinstance(shape, Cylinder):
|
|
163
|
+
create_op.cylinder.CopyFrom(shape._to_proto())
|
|
164
|
+
elif isinstance(shape, Torus):
|
|
165
|
+
create_op.torus.CopyFrom(shape._to_proto())
|
|
166
|
+
elif isinstance(shape, Cone):
|
|
167
|
+
create_op.cone.CopyFrom(shape._to_proto())
|
|
168
|
+
elif isinstance(shape, HalfSphere):
|
|
169
|
+
create_op.half_sphere.CopyFrom(shape._to_proto())
|
|
170
|
+
else:
|
|
171
|
+
raise TypeError(f"Unsupported shape type: {type(shape)}")
|
|
172
|
+
|
|
173
|
+
|
|
151
174
|
def modify_import(
|
|
152
175
|
feature: gpb.Feature,
|
|
153
176
|
geometry_url: Optional[str] = None,
|
|
@@ -205,22 +228,7 @@ def modify_create(
|
|
|
205
228
|
create_op = feature_copy.create
|
|
206
229
|
|
|
207
230
|
if shape is not None:
|
|
208
|
-
create_op
|
|
209
|
-
|
|
210
|
-
if isinstance(shape, Sphere):
|
|
211
|
-
create_op.sphere.CopyFrom(shape._to_proto()) # type: ignore
|
|
212
|
-
elif isinstance(shape, Cube):
|
|
213
|
-
create_op.box.CopyFrom(shape._to_proto()) # type: ignore
|
|
214
|
-
elif isinstance(shape, Cylinder):
|
|
215
|
-
create_op.cylinder.CopyFrom(shape._to_proto()) # type: ignore
|
|
216
|
-
elif isinstance(shape, Torus):
|
|
217
|
-
create_op.torus.CopyFrom(shape._to_proto()) # type: ignore
|
|
218
|
-
elif isinstance(shape, Cone):
|
|
219
|
-
create_op.cone.CopyFrom(shape._to_proto()) # type: ignore
|
|
220
|
-
elif isinstance(shape, HalfSphere):
|
|
221
|
-
create_op.half_sphere.CopyFrom(shape._to_proto()) # type: ignore
|
|
222
|
-
else:
|
|
223
|
-
raise TypeError(f"Unsupported shape type: {type(shape)}")
|
|
231
|
+
_update_create_op_from_shape(create_op, shape)
|
|
224
232
|
|
|
225
233
|
return gpb.Modification(
|
|
226
234
|
mod_type=gpb.Modification.ModificationType.MODIFICATION_TYPE_UPDATE_FEATURE,
|
|
@@ -719,22 +727,7 @@ def modify_farfield(
|
|
|
719
727
|
farfield_op = feature_copy.farfield
|
|
720
728
|
|
|
721
729
|
if shape is not None:
|
|
722
|
-
|
|
723
|
-
if isinstance(shape, Sphere):
|
|
724
|
-
create_op.sphere.CopyFrom(shape._to_proto()) # type: ignore
|
|
725
|
-
elif isinstance(shape, Cube):
|
|
726
|
-
create_op.box.CopyFrom(shape._to_proto()) # type: ignore
|
|
727
|
-
elif isinstance(shape, Cylinder):
|
|
728
|
-
create_op.cylinder.CopyFrom(shape._to_proto()) # type: ignore
|
|
729
|
-
elif isinstance(shape, Torus):
|
|
730
|
-
create_op.torus.CopyFrom(shape._to_proto()) # type: ignore
|
|
731
|
-
elif isinstance(shape, Cone):
|
|
732
|
-
create_op.cone.CopyFrom(shape._to_proto()) # type: ignore
|
|
733
|
-
elif isinstance(shape, HalfSphere):
|
|
734
|
-
create_op.half_sphere.CopyFrom(shape._to_proto()) # type: ignore
|
|
735
|
-
else:
|
|
736
|
-
raise TypeError(f"Unsupported shape type: {type(shape)}")
|
|
737
|
-
farfield_op.create.CopyFrom(create_op)
|
|
730
|
+
_update_create_op_from_shape(farfield_op.create, shape)
|
|
738
731
|
|
|
739
732
|
if volumes is not None:
|
|
740
733
|
vol_ids = _volumes_to_int_list(volumes)
|
luminarycloud/geometry.py
CHANGED
|
@@ -178,17 +178,17 @@ class Geometry(ProtoWrapperBase):
|
|
|
178
178
|
"""
|
|
179
179
|
create_proto = gpb.Create()
|
|
180
180
|
if isinstance(shape, shapes.Sphere):
|
|
181
|
-
create_proto.sphere.CopyFrom(shape._to_proto())
|
|
181
|
+
create_proto.sphere.CopyFrom(shape._to_proto())
|
|
182
182
|
elif isinstance(shape, shapes.Cube):
|
|
183
|
-
create_proto.box.CopyFrom(shape._to_proto())
|
|
183
|
+
create_proto.box.CopyFrom(shape._to_proto())
|
|
184
184
|
elif isinstance(shape, shapes.Cylinder):
|
|
185
|
-
create_proto.cylinder.CopyFrom(shape._to_proto())
|
|
185
|
+
create_proto.cylinder.CopyFrom(shape._to_proto())
|
|
186
186
|
elif isinstance(shape, shapes.Torus):
|
|
187
|
-
create_proto.torus.CopyFrom(shape._to_proto())
|
|
187
|
+
create_proto.torus.CopyFrom(shape._to_proto())
|
|
188
188
|
elif isinstance(shape, shapes.Cone):
|
|
189
|
-
create_proto.cone.CopyFrom(shape._to_proto())
|
|
189
|
+
create_proto.cone.CopyFrom(shape._to_proto())
|
|
190
190
|
elif isinstance(shape, shapes.HalfSphere):
|
|
191
|
-
create_proto.half_sphere.CopyFrom(shape._to_proto())
|
|
191
|
+
create_proto.half_sphere.CopyFrom(shape._to_proto())
|
|
192
192
|
else:
|
|
193
193
|
raise TypeError(f"Unsupported shape for farfield: {type(shape)}")
|
|
194
194
|
self._modify(
|
|
@@ -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
|
+
)
|