luminarycloud 0.18.1__py3-none-any.whl → 0.19.1__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 +21 -5
- luminarycloud/_client/http_client.py +168 -0
- luminarycloud/_client/rpc_error.py +1 -0
- luminarycloud/_client/tracing.py +72 -22
- luminarycloud/_helpers/_wait_for_mesh.py +5 -7
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.py +8 -8
- luminarycloud/_proto/api/v0/luminarycloud/inference/inference_pb2.pyi +9 -8
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +83 -25
- luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +214 -0
- 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/simulation/simulation_pb2.py +60 -60
- luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.pyi +5 -1
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.py +70 -40
- luminarycloud/_proto/api/v0/luminarycloud/thirdpartyintegration/onshape/onshape_pb2.pyi +64 -3
- luminarycloud/_proto/client/simulation_pb2.py +347 -332
- luminarycloud/_proto/client/simulation_pb2.pyi +55 -9
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.py +10 -10
- luminarycloud/_proto/inferenceservice/inferenceservice_pb2.pyi +9 -8
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2.py +29 -0
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2.pyi +7 -0
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.py +70 -0
- luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.pyi +30 -0
- luminarycloud/enum/quantity_type.py +13 -0
- luminarycloud/exceptions.py +6 -0
- luminarycloud/params/enum/_enum_wrappers.py +28 -2
- luminarycloud/params/simulation/material/material_solid_.py +15 -1
- luminarycloud/params/simulation/sliding_interfaces_.py +8 -0
- luminarycloud/physics_ai/architectures.py +58 -0
- luminarycloud/physics_ai/inference.py +30 -25
- luminarycloud/physics_ai/training_jobs.py +37 -0
- luminarycloud/pipelines/api.py +50 -102
- luminarycloud/project.py +15 -43
- luminarycloud/simulation.py +2 -0
- luminarycloud/simulation_template.py +2 -1
- luminarycloud/tables.py +14 -15
- luminarycloud/vis/visualization.py +2 -2
- {luminarycloud-0.18.1.dist-info → luminarycloud-0.19.1.dist-info}/METADATA +1 -1
- {luminarycloud-0.18.1.dist-info → luminarycloud-0.19.1.dist-info}/RECORD +40 -39
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2.py +0 -246
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2.pyi +0 -420
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2_grpc.py +0 -240
- luminarycloud/_proto/api/v0/luminarycloud/pipelines/pipelines_pb2_grpc.pyi +0 -90
- luminarycloud/enum/pipeline_job_status.py +0 -23
- {luminarycloud-0.18.1.dist-info → luminarycloud-0.19.1.dist-info}/WHEEL +0 -0
|
@@ -51,8 +51,8 @@ def external_aero_inference(
|
|
|
51
51
|
project: Project,
|
|
52
52
|
stl_file: str,
|
|
53
53
|
artifact_url: str,
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
conditions: Optional[Dict[str, Any]] = None,
|
|
55
|
+
settings: Optional[Dict[str, Any]] = None,
|
|
56
56
|
write_visualization_data=False,
|
|
57
57
|
) -> ExtAeroInferenceResult:
|
|
58
58
|
"""Performs an inference job returning external aerodynamic results.
|
|
@@ -64,10 +64,10 @@ def external_aero_inference(
|
|
|
64
64
|
Fullpath the STL file to be used for inference.
|
|
65
65
|
artifact_url : str
|
|
66
66
|
Fullpath of the model artifact directory to be used for inference.
|
|
67
|
-
|
|
68
|
-
Dictionary of
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
conditions : Dict[str, Any], optional
|
|
68
|
+
Dictionary of conditions to be passed to the inference service (e.g., alpha, beta, etc.).
|
|
69
|
+
settings : Dict[str, Any], optional
|
|
70
|
+
Dictionary of settings to be passed to inference service (e.g., stencil_size)
|
|
71
71
|
write_visualization_data : bool, optional
|
|
72
72
|
Whether to write LC visualization data for visualization by Luminary.
|
|
73
73
|
|
|
@@ -80,7 +80,7 @@ def external_aero_inference(
|
|
|
80
80
|
"""
|
|
81
81
|
|
|
82
82
|
result = perform_inference(
|
|
83
|
-
project, stl_file, artifact_url,
|
|
83
|
+
project, stl_file, artifact_url, conditions, settings, write_visualization_data
|
|
84
84
|
)
|
|
85
85
|
return ExtAeroInferenceResult(result)
|
|
86
86
|
|
|
@@ -89,8 +89,8 @@ def perform_inference(
|
|
|
89
89
|
project: Project,
|
|
90
90
|
stl_file: str,
|
|
91
91
|
artifact_url: str,
|
|
92
|
-
|
|
93
|
-
|
|
92
|
+
conditions: Optional[Dict[str, Any]] = None,
|
|
93
|
+
settings: Optional[Dict[str, Any]] = None,
|
|
94
94
|
write_visualization_data=False,
|
|
95
95
|
) -> dict[str, Any]:
|
|
96
96
|
"""Creates an inference service job.
|
|
@@ -102,10 +102,10 @@ def perform_inference(
|
|
|
102
102
|
Fullpath the STL file to be used for inference.
|
|
103
103
|
artifact_url : str
|
|
104
104
|
Fullpath of the model artifact directory to be used for inference.
|
|
105
|
-
|
|
106
|
-
Dictionary of
|
|
107
|
-
|
|
108
|
-
|
|
105
|
+
conditions : Dict[str, Any], optional
|
|
106
|
+
Dictionary of conditions to be passed to the inference service (e.g., alpha, beta, etc.).
|
|
107
|
+
settings : Dict[str, Any], optional
|
|
108
|
+
Dictionary of settings to be passed to inference service (e.g., stencil_size)
|
|
109
109
|
write_visualization_data : bool, optional
|
|
110
110
|
Whether to write LC visualization data for visualization by Luminary.
|
|
111
111
|
|
|
@@ -142,7 +142,7 @@ def perform_inference(
|
|
|
142
142
|
stl_url = upload_if_file(stl_file)
|
|
143
143
|
|
|
144
144
|
raw = start_inference_job(
|
|
145
|
-
project, stl_url, artifact_url,
|
|
145
|
+
project, stl_url, artifact_url, conditions, settings, write_visualization_data
|
|
146
146
|
)
|
|
147
147
|
currated: dict[str, Any] = {}
|
|
148
148
|
for k, v in raw.items():
|
|
@@ -163,8 +163,8 @@ def start_inference_job(
|
|
|
163
163
|
project: Project,
|
|
164
164
|
stl_url: str,
|
|
165
165
|
artifact_url: str,
|
|
166
|
-
|
|
167
|
-
|
|
166
|
+
conditions: Optional[Dict[str, Any]] = None,
|
|
167
|
+
settings: Optional[Dict[str, Any]] = None,
|
|
168
168
|
write_visualization_data=False,
|
|
169
169
|
) -> dict[str, Any]:
|
|
170
170
|
"""Creates an inference service job.
|
|
@@ -176,10 +176,10 @@ def start_inference_job(
|
|
|
176
176
|
URL of the STL file to be used for inference.
|
|
177
177
|
artifact_url : str
|
|
178
178
|
URL of the model artifact directory to be used for inference.
|
|
179
|
-
|
|
180
|
-
Dictionary of
|
|
181
|
-
|
|
182
|
-
|
|
179
|
+
conditions : Dict[str, Any], optional
|
|
180
|
+
Dictionary of conditions to be passed to the inference service (e.g., alpha, beta, etc.).
|
|
181
|
+
settings : Dict[str, Any], optional
|
|
182
|
+
Dictionary of settings to be passed to inference service (e.g., stencil_size)
|
|
183
183
|
write_visualization_data : bool, optional
|
|
184
184
|
Whether to write LC visualization data for visualization by Luminary.
|
|
185
185
|
|
|
@@ -191,16 +191,21 @@ def start_inference_job(
|
|
|
191
191
|
warning:: This feature is experimental and may change or be removed without notice.
|
|
192
192
|
"""
|
|
193
193
|
|
|
194
|
+
# Embed settings and store as bytes
|
|
195
|
+
settings_bytes = b""
|
|
196
|
+
if settings is not None:
|
|
197
|
+
settings_bytes = json_dumps(settings).encode("utf-8")
|
|
198
|
+
|
|
194
199
|
# Convert parameters dict to bytes if provided
|
|
195
|
-
|
|
196
|
-
if
|
|
197
|
-
|
|
200
|
+
conditions_bytes = b""
|
|
201
|
+
if conditions is not None:
|
|
202
|
+
conditions_bytes = json_dumps(conditions).encode("utf-8")
|
|
198
203
|
|
|
199
204
|
req = inferencepb.CreateInferenceServiceJobRequest(
|
|
200
205
|
stl_url=stl_url,
|
|
201
206
|
artifact_url=artifact_url,
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
conditions=conditions_bytes,
|
|
208
|
+
settings=settings_bytes,
|
|
204
209
|
project_id=project.id,
|
|
205
210
|
write_visualization_data=write_visualization_data,
|
|
206
211
|
)
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Copyright 2025 Luminary Cloud, Inc. All Rights Reserved.
|
|
2
|
+
from typing import List, Optional
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
|
|
5
|
+
from .._client import get_default_client
|
|
6
|
+
from .._proto.api.v0.luminarycloud.physics_ai import physics_ai_pb2 as physaipb
|
|
7
|
+
from .._proto.base import base_pb2 as basepb
|
|
8
|
+
from .._wrapper import ProtoWrapper, ProtoWrapperBase
|
|
9
|
+
from ..types.ids import PhysicsAiArchitectureVersionID
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@ProtoWrapper(physaipb.PhysicsAiTrainingJob)
|
|
13
|
+
class PhysicsAiTrainingJob(ProtoWrapperBase):
|
|
14
|
+
"""
|
|
15
|
+
Represents a Physics AI training job.
|
|
16
|
+
|
|
17
|
+
.. warning:: This feature is experimental and may change or be removed without notice.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
id: str
|
|
21
|
+
architecture_version_id: PhysicsAiArchitectureVersionID
|
|
22
|
+
user_id: str
|
|
23
|
+
training_config: str
|
|
24
|
+
training_data_source_type: physaipb.TrainingDataSourceType
|
|
25
|
+
training_description: str
|
|
26
|
+
external_dataset_uri: str
|
|
27
|
+
initialization_type: physaipb.ModelInitializationType
|
|
28
|
+
base_model_version_id: str
|
|
29
|
+
status: basepb.JobStatus
|
|
30
|
+
error_message: str
|
|
31
|
+
output_model_version_id: str
|
|
32
|
+
creation_time: datetime
|
|
33
|
+
update_time: datetime
|
|
34
|
+
_proto: physaipb.PhysicsAiTrainingJob
|
|
35
|
+
|
|
36
|
+
def get_status(self) -> str:
|
|
37
|
+
return basepb.JobStatusType.Name(self.status.typ)
|
luminarycloud/pipelines/api.py
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
# Copyright 2023-2024 Luminary Cloud, Inc. All Rights Reserved.
|
|
2
|
+
from typing import Literal
|
|
2
3
|
from dataclasses import dataclass
|
|
3
4
|
|
|
4
5
|
from datetime import datetime
|
|
5
6
|
|
|
6
|
-
from luminarycloud._helpers import timestamp_to_datetime
|
|
7
|
-
|
|
8
|
-
from ..enum.pipeline_job_status import PipelineJobStatus
|
|
9
7
|
from ..pipelines import Pipeline, PipelineArgs
|
|
10
8
|
from .._client import get_default_client
|
|
11
|
-
from .._proto.api.v0.luminarycloud.pipelines import pipelines_pb2 as pipelinespb
|
|
12
9
|
|
|
13
10
|
|
|
14
11
|
@dataclass
|
|
@@ -17,21 +14,21 @@ class PipelineRecord:
|
|
|
17
14
|
name: str
|
|
18
15
|
description: str | None
|
|
19
16
|
definition_yaml: str
|
|
20
|
-
|
|
21
|
-
|
|
17
|
+
created_at: datetime
|
|
18
|
+
updated_at: datetime
|
|
22
19
|
|
|
23
20
|
def pipeline(self) -> Pipeline:
|
|
24
21
|
return Pipeline._from_yaml(self.definition_yaml)
|
|
25
22
|
|
|
26
23
|
@classmethod
|
|
27
|
-
def
|
|
24
|
+
def from_json(cls, json: dict) -> "PipelineRecord":
|
|
28
25
|
return cls(
|
|
29
|
-
id=
|
|
30
|
-
name=
|
|
31
|
-
description=
|
|
32
|
-
definition_yaml=
|
|
33
|
-
|
|
34
|
-
|
|
26
|
+
id=json["id"],
|
|
27
|
+
name=json["name"],
|
|
28
|
+
description=json["description"],
|
|
29
|
+
definition_yaml=json["definition_yaml"],
|
|
30
|
+
created_at=datetime.fromisoformat(json["created_at"]),
|
|
31
|
+
updated_at=datetime.fromisoformat(json["updated_at"]),
|
|
35
32
|
)
|
|
36
33
|
|
|
37
34
|
|
|
@@ -42,30 +39,26 @@ class PipelineJobRecord:
|
|
|
42
39
|
project_id: str
|
|
43
40
|
name: str
|
|
44
41
|
description: str | None
|
|
45
|
-
status:
|
|
46
|
-
|
|
47
|
-
|
|
42
|
+
status: Literal["pending", "running", "completed", "failed", "cancelled"]
|
|
43
|
+
created_at: datetime
|
|
44
|
+
updated_at: datetime
|
|
48
45
|
started_at: datetime | None
|
|
49
46
|
completed_at: datetime | None
|
|
50
47
|
|
|
51
48
|
@classmethod
|
|
52
|
-
def
|
|
49
|
+
def from_json(cls, json: dict) -> "PipelineJobRecord":
|
|
53
50
|
return cls(
|
|
54
|
-
id=
|
|
55
|
-
pipeline_id=
|
|
56
|
-
project_id=
|
|
57
|
-
name=
|
|
58
|
-
description=
|
|
59
|
-
status=
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
started_at=(
|
|
63
|
-
timestamp_to_datetime(proto.started_at) if proto.HasField("started_at") else None
|
|
64
|
-
),
|
|
51
|
+
id=json["id"],
|
|
52
|
+
pipeline_id=json["pipeline_id"],
|
|
53
|
+
project_id=json["project_id"],
|
|
54
|
+
name=json["name"],
|
|
55
|
+
description=json["description"],
|
|
56
|
+
status=json["status"],
|
|
57
|
+
created_at=datetime.fromisoformat(json["created_at"]),
|
|
58
|
+
updated_at=datetime.fromisoformat(json["updated_at"]),
|
|
59
|
+
started_at=datetime.fromisoformat(json["started_at"]) if json["started_at"] else None,
|
|
65
60
|
completed_at=(
|
|
66
|
-
|
|
67
|
-
if proto.HasField("completed_at")
|
|
68
|
-
else None
|
|
61
|
+
datetime.fromisoformat(json["completed_at"]) if json["completed_at"] else None
|
|
69
62
|
),
|
|
70
63
|
)
|
|
71
64
|
|
|
@@ -89,20 +82,21 @@ def create_pipeline(
|
|
|
89
82
|
definition_yaml = pipeline.to_yaml()
|
|
90
83
|
else:
|
|
91
84
|
definition_yaml = pipeline
|
|
92
|
-
|
|
93
|
-
name
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
85
|
+
body = {
|
|
86
|
+
"name": name,
|
|
87
|
+
"definition_yaml": definition_yaml,
|
|
88
|
+
"description": description,
|
|
89
|
+
}
|
|
90
|
+
res = get_default_client().http.post("/rest/v0/pipelines", body)
|
|
91
|
+
return PipelineRecord.from_json(res["data"])
|
|
97
92
|
|
|
98
93
|
|
|
99
94
|
def list_pipelines() -> list[PipelineRecord]:
|
|
100
95
|
"""
|
|
101
96
|
List all pipelines.
|
|
102
97
|
"""
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
return [PipelineRecord.from_proto(p) for p in res.pipelines]
|
|
98
|
+
res = get_default_client().http.get("/rest/v0/pipelines")
|
|
99
|
+
return [PipelineRecord.from_json(p) for p in res["data"]]
|
|
106
100
|
|
|
107
101
|
|
|
108
102
|
def get_pipeline(id: str) -> PipelineRecord:
|
|
@@ -114,9 +108,8 @@ def get_pipeline(id: str) -> PipelineRecord:
|
|
|
114
108
|
id : str
|
|
115
109
|
ID of the pipeline to fetch.
|
|
116
110
|
"""
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
return PipelineRecord.from_proto(res.pipeline)
|
|
111
|
+
res = get_default_client().http.get(f"/rest/v0/pipelines/{id}")
|
|
112
|
+
return PipelineRecord.from_json(res["data"])
|
|
120
113
|
|
|
121
114
|
|
|
122
115
|
def create_pipeline_job(
|
|
@@ -139,75 +132,30 @@ def create_pipeline_job(
|
|
|
139
132
|
Description of the pipeline job.
|
|
140
133
|
"""
|
|
141
134
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
string_column=pipelinespb.PipelineJobArgsColumn.StringColumn(
|
|
154
|
-
name=param.name,
|
|
155
|
-
values=col_values[i],
|
|
156
|
-
)
|
|
157
|
-
)
|
|
158
|
-
)
|
|
159
|
-
elif param._represented_type() == int:
|
|
160
|
-
cols.append(
|
|
161
|
-
pipelinespb.PipelineJobArgsColumn(
|
|
162
|
-
int_column=pipelinespb.PipelineJobArgsColumn.IntColumn(
|
|
163
|
-
name=param.name,
|
|
164
|
-
values=col_values[i],
|
|
165
|
-
)
|
|
166
|
-
)
|
|
167
|
-
)
|
|
168
|
-
elif param._represented_type() == float:
|
|
169
|
-
cols.append(
|
|
170
|
-
pipelinespb.PipelineJobArgsColumn(
|
|
171
|
-
double_column=pipelinespb.PipelineJobArgsColumn.DoubleColumn(
|
|
172
|
-
name=param.name,
|
|
173
|
-
values=col_values[i],
|
|
174
|
-
)
|
|
175
|
-
)
|
|
176
|
-
)
|
|
177
|
-
elif param._represented_type() == bool:
|
|
178
|
-
cols.append(
|
|
179
|
-
pipelinespb.PipelineJobArgsColumn(
|
|
180
|
-
bool_column=pipelinespb.PipelineJobArgsColumn.BoolColumn(
|
|
181
|
-
name=param.name,
|
|
182
|
-
values=col_values[i],
|
|
183
|
-
)
|
|
184
|
-
)
|
|
185
|
-
)
|
|
186
|
-
|
|
187
|
-
req = pipelinespb.CreatePipelineJobRequest(
|
|
188
|
-
pipeline_id=pipeline_id,
|
|
189
|
-
args_columns=cols,
|
|
190
|
-
name=name,
|
|
191
|
-
description=description,
|
|
192
|
-
project_id=project_id,
|
|
193
|
-
)
|
|
194
|
-
res: pipelinespb.CreatePipelineJobResponse = get_default_client().CreatePipelineJob(req)
|
|
195
|
-
return PipelineJobRecord.from_proto(res.pipeline_job)
|
|
135
|
+
arg_rows = [row.row_values for row in args.rows]
|
|
136
|
+
body = {
|
|
137
|
+
"name": name,
|
|
138
|
+
"description": description,
|
|
139
|
+
"project_id": project_id,
|
|
140
|
+
"argument_names": [p.name for p in args.params],
|
|
141
|
+
"argument_rows": arg_rows,
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
res = get_default_client().http.post(f"/rest/v0/pipelines/{pipeline_id}/pipeline_jobs", body)
|
|
145
|
+
return PipelineJobRecord.from_json(res["data"])
|
|
196
146
|
|
|
197
147
|
|
|
198
148
|
def get_pipeline_job(id: str) -> PipelineJobRecord:
|
|
199
149
|
"""
|
|
200
150
|
Get a pipeline job by ID.
|
|
201
151
|
"""
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
return PipelineJobRecord.from_proto(res.pipeline_job)
|
|
152
|
+
res = get_default_client().http.get(f"/rest/v0/pipeline_jobs/{id}")
|
|
153
|
+
return PipelineJobRecord.from_json(res["data"])
|
|
205
154
|
|
|
206
155
|
|
|
207
156
|
def list_pipeline_jobs() -> list[PipelineJobRecord]:
|
|
208
157
|
"""
|
|
209
158
|
List all pipeline jobs.
|
|
210
159
|
"""
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return [PipelineJobRecord.from_proto(p) for p in res.pipeline_jobs]
|
|
160
|
+
res = get_default_client().http.get("/rest/v0/pipeline_jobs")
|
|
161
|
+
return [PipelineJobRecord.from_json(p) for p in res["data"]]
|
luminarycloud/project.py
CHANGED
|
@@ -10,8 +10,6 @@ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Union, Literal
|
|
|
10
10
|
|
|
11
11
|
import concurrent
|
|
12
12
|
|
|
13
|
-
import grpc
|
|
14
|
-
|
|
15
13
|
import luminarycloud as lc
|
|
16
14
|
from luminarycloud._helpers.named_variables import _named_variables_to_proto
|
|
17
15
|
from luminarycloud.params.simulation.adjoint_ import Adjoint
|
|
@@ -258,19 +256,16 @@ class Project(ProtoWrapperBase):
|
|
|
258
256
|
)
|
|
259
257
|
return lc.Mesh(_mesh)
|
|
260
258
|
|
|
261
|
-
|
|
262
|
-
def create_mesh(
|
|
259
|
+
def create_or_get_mesh(
|
|
263
260
|
self,
|
|
264
261
|
params: MeshAdaptationParams | MeshGenerationParams,
|
|
265
262
|
*,
|
|
266
263
|
name: str,
|
|
264
|
+
request_id: Optional[str] = None,
|
|
267
265
|
) -> "Mesh":
|
|
268
266
|
"""
|
|
269
|
-
Create a new mesh in the project
|
|
270
|
-
|
|
271
|
-
.. deprecated:: 0.10.0
|
|
272
|
-
`create_mesh()` will be removed in v0.11.0, it is replaced by
|
|
273
|
-
`create_or_get_mesh()`.
|
|
267
|
+
Create a new mesh in the project, or return an existing mesh with the same request_id
|
|
268
|
+
if it already exists.
|
|
274
269
|
|
|
275
270
|
Parameters
|
|
276
271
|
----------
|
|
@@ -279,14 +274,24 @@ class Project(ProtoWrapperBase):
|
|
|
279
274
|
existing geometry, use MeshGenerationParams. If adapting a mesh from an existing,
|
|
280
275
|
solution use MeshAdaptationParams.
|
|
281
276
|
name : str
|
|
282
|
-
|
|
277
|
+
Mesh name. Max 256 characters.
|
|
278
|
+
request_id : str, optional
|
|
279
|
+
Can be useful as an idempotency key. If there's an existing Mesh with the given
|
|
280
|
+
request_id, that Mesh will be returned. If there's no existing Mesh with the given
|
|
281
|
+
request_id, then a Mesh will be created and associated with that request_id. If not
|
|
282
|
+
provided, a random request_id will be generated for the Mesh, effectively preventing it
|
|
283
|
+
from being retrieved by a future `create_or_get_mesh` request. Max 256 characters.
|
|
283
284
|
"""
|
|
284
285
|
|
|
286
|
+
if request_id is None:
|
|
287
|
+
request_id = str(uuid.uuid4())
|
|
288
|
+
|
|
285
289
|
client = get_default_client()
|
|
286
290
|
|
|
287
291
|
req = meshpb.CreateMeshRequest(
|
|
288
292
|
project_id=self.id,
|
|
289
293
|
name=name,
|
|
294
|
+
request_id=request_id,
|
|
290
295
|
)
|
|
291
296
|
|
|
292
297
|
if isinstance(params, meshpb.MeshGenerationParams):
|
|
@@ -314,39 +319,6 @@ class Project(ProtoWrapperBase):
|
|
|
314
319
|
res: meshpb.CreateMeshResponse = client.CreateMesh(req)
|
|
315
320
|
return lc.Mesh(res.mesh)
|
|
316
321
|
|
|
317
|
-
def create_or_get_mesh(
|
|
318
|
-
self,
|
|
319
|
-
params: MeshAdaptationParams | MeshGenerationParams,
|
|
320
|
-
*,
|
|
321
|
-
name: str,
|
|
322
|
-
) -> "Mesh":
|
|
323
|
-
"""
|
|
324
|
-
Create a new mesh in the project, or return an existing mesh with the same parameters
|
|
325
|
-
if it already exists.
|
|
326
|
-
|
|
327
|
-
Parameters
|
|
328
|
-
----------
|
|
329
|
-
params : MeshGenerationParams | MeshAdaptationParams
|
|
330
|
-
The parameters to use to create the mesh. If generating a new mesh from an
|
|
331
|
-
existing geometry, use MeshGenerationParams. If adapting a mesh from an existing,
|
|
332
|
-
solution use MeshAdaptationParams.
|
|
333
|
-
name : str
|
|
334
|
-
Mesh name. Max 256 characters.
|
|
335
|
-
"""
|
|
336
|
-
|
|
337
|
-
try:
|
|
338
|
-
return self.create_mesh(params, name=name)
|
|
339
|
-
except grpc.RpcError as e:
|
|
340
|
-
if e.code() == grpc.StatusCode.ALREADY_EXISTS:
|
|
341
|
-
message = e.details()
|
|
342
|
-
match = re.search(r"mesh-[a-f0-9-]+$", message)
|
|
343
|
-
if match:
|
|
344
|
-
existing_mesh_id = match.group(0)
|
|
345
|
-
req = meshpb.GetMeshRequest(id=existing_mesh_id)
|
|
346
|
-
res = get_default_client().GetMesh(req)
|
|
347
|
-
return lc.Mesh(res.mesh)
|
|
348
|
-
raise
|
|
349
|
-
|
|
350
322
|
def _create_hex_mesh(
|
|
351
323
|
self,
|
|
352
324
|
names_to_file_paths: Dict[str, Union[PathLike[Any], str]],
|
luminarycloud/simulation.py
CHANGED
|
@@ -57,6 +57,8 @@ class Simulation(ProtoWrapperBase):
|
|
|
57
57
|
"ID of the simulation mesh."
|
|
58
58
|
project_id: ProjectID
|
|
59
59
|
"ID of the project containing this simulation."
|
|
60
|
+
doe_name: str
|
|
61
|
+
"Name of the design of experiments that created this simulation."
|
|
60
62
|
|
|
61
63
|
_proto: simulationpb.Simulation
|
|
62
64
|
|
|
@@ -490,7 +490,8 @@ class SimulationTemplate(ProtoWrapperBase):
|
|
|
490
490
|
code += "\n\n\n"
|
|
491
491
|
code += '# Create a new simulation template or modify the one that is synced with the UI "Setup" tab.\n'
|
|
492
492
|
code += f'project = luminarycloud.get_project("{self.project_id}")\n'
|
|
493
|
-
|
|
493
|
+
escaped_name = self.name.replace('\\','\\\\').replace('"','\\"')
|
|
494
|
+
code += f'template = project.create_simulation_template(name="{escaped_name}")\n'
|
|
494
495
|
code += '# TODO(USER): To modify the "Setup" template, uncomment the line below and comment out the line above.\n'
|
|
495
496
|
code += "# template = project.list_simulation_templates()[0] # Setup template\n\n"
|
|
496
497
|
|
luminarycloud/tables.py
CHANGED
|
@@ -10,7 +10,6 @@ from typing import Union
|
|
|
10
10
|
from .enum import TableType, QuantityType
|
|
11
11
|
from ._helpers import CodeRepr
|
|
12
12
|
from ._proto.table import table_pb2 as tablepb
|
|
13
|
-
from ._proto.quantity import quantity_pb2 as quantitypb
|
|
14
13
|
|
|
15
14
|
|
|
16
15
|
def create_rectilinear_table(
|
|
@@ -37,30 +36,30 @@ def create_rectilinear_table(
|
|
|
37
36
|
def lc_defined_header(table_type: TableType) -> list[Union[int, str]]:
|
|
38
37
|
"""Returns the required header (if any) for a type of table."""
|
|
39
38
|
if table_type == TableType.MONITOR_POINTS:
|
|
40
|
-
return [
|
|
39
|
+
return [QuantityType.LENGTH, QuantityType.LENGTH, QuantityType.LENGTH, "name", "id"]
|
|
41
40
|
elif table_type == TableType.RADIAL_DISTRIBUTION:
|
|
42
41
|
return [
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
QuantityType.RELATIVE_RADIUS,
|
|
43
|
+
QuantityType.THRUST_PROFILE,
|
|
44
|
+
QuantityType.TORQUE_PROFILE,
|
|
45
|
+
QuantityType.RADIAL_FORCE_PROFILE,
|
|
47
46
|
]
|
|
48
47
|
elif table_type == TableType.BLADE_GEOMETRY:
|
|
49
48
|
return [
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
49
|
+
QuantityType.RELATIVE_RADIUS,
|
|
50
|
+
QuantityType.TWIST_ANGLE,
|
|
51
|
+
QuantityType.SWEEP_ANGLE,
|
|
52
|
+
QuantityType.ANHEDRAL_ANGLE,
|
|
53
|
+
QuantityType.RELATIVE_CHORD,
|
|
55
54
|
]
|
|
56
55
|
elif table_type == TableType.PROFILE_BC:
|
|
57
56
|
return []
|
|
58
57
|
elif table_type == TableType.FAN_CURVE:
|
|
59
|
-
return [
|
|
58
|
+
return [QuantityType.VOLUME_FLOW_RATE, QuantityType.PRESSURE_RISE]
|
|
60
59
|
elif table_type == TableType.CUSTOM_SAMPLE_DOE:
|
|
61
60
|
return []
|
|
62
61
|
elif table_type == TableType.TEMP_VARYING:
|
|
63
|
-
return [
|
|
62
|
+
return [QuantityType.TEMPERATURE, "quantity"]
|
|
64
63
|
else:
|
|
65
64
|
raise RuntimeError("Unknown type of table.")
|
|
66
65
|
|
|
@@ -113,7 +112,7 @@ def create_rectilinear_table(
|
|
|
113
112
|
if isinstance(first_header, str):
|
|
114
113
|
table.header.axis_label[-1].name = first_header
|
|
115
114
|
else:
|
|
116
|
-
table.header.axis_label[-1].quantity =
|
|
115
|
+
table.header.axis_label[-1].quantity = first_header.value
|
|
117
116
|
table.axis.append(tablepb.Axis())
|
|
118
117
|
|
|
119
118
|
for label in header[has_axis(table_type) :]:
|
|
@@ -121,7 +120,7 @@ def create_rectilinear_table(
|
|
|
121
120
|
if isinstance(label, str):
|
|
122
121
|
table.header.record_label[-1].name = label
|
|
123
122
|
else:
|
|
124
|
-
table.header.record_label[-1].quantity =
|
|
123
|
+
table.header.record_label[-1].quantity = label.value
|
|
125
124
|
|
|
126
125
|
types = data_types(table_type, len(header))
|
|
127
126
|
|
|
@@ -14,7 +14,6 @@ from luminarycloud.types import Vector3, Vector3Like
|
|
|
14
14
|
from .._client import get_default_client
|
|
15
15
|
from .._helpers._get_project_id import _get_project_id
|
|
16
16
|
from .._helpers._code_representation import CodeRepr
|
|
17
|
-
from .._proto.quantity import quantity_pb2 as quantitypb
|
|
18
17
|
from .._proto.api.v0.luminarycloud.vis import vis_pb2
|
|
19
18
|
from ..types import SimulationID, MeshID
|
|
20
19
|
from luminarycloud.enum import (
|
|
@@ -24,6 +23,7 @@ from luminarycloud.enum import (
|
|
|
24
23
|
EntityType,
|
|
25
24
|
SceneMode,
|
|
26
25
|
VisQuantity,
|
|
26
|
+
QuantityType,
|
|
27
27
|
)
|
|
28
28
|
from ..exceptions import NotFoundError
|
|
29
29
|
from ..geometry import Geometry, get_geometry
|
|
@@ -657,7 +657,7 @@ class Scene(CodeRepr):
|
|
|
657
657
|
attrs = vis_pb2.DisplayAttributes()
|
|
658
658
|
attrs.visible = visible
|
|
659
659
|
attrs.field.component = vis_pb2.Field.COMPONENT_X
|
|
660
|
-
attrs.field.quantity_typ =
|
|
660
|
+
attrs.field.quantity_typ = QuantityType.UNSPECIFIED.value
|
|
661
661
|
req.spec.display_attributes[id].CopyFrom(attrs)
|
|
662
662
|
|
|
663
663
|
self._validate_filter_connections()
|