luminarycloud 0.22.3__py3-none-any.whl → 0.23.0__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 (258) hide show
  1. luminarycloud/__init__.py +9 -3
  2. luminarycloud/_client/client.py +1 -1
  3. luminarycloud/_helpers/_code_representation.py +1 -0
  4. luminarycloud/_helpers/_create_simulation.py +5 -1
  5. luminarycloud/_helpers/proto_decorator.py +46 -38
  6. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.py +214 -137
  7. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2.pyi +152 -0
  8. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.py +103 -0
  9. luminarycloud/_proto/api/v0/luminarycloud/geometry/geometry_pb2_grpc.pyi +40 -0
  10. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.py +137 -63
  11. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2.pyi +166 -6
  12. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.py +68 -0
  13. luminarycloud/_proto/api/v0/luminarycloud/physics_ai/physics_ai_pb2_grpc.pyi +24 -0
  14. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.py +94 -71
  15. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2.pyi +46 -0
  16. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.py +35 -0
  17. luminarycloud/_proto/api/v0/luminarycloud/simulation/simulation_pb2_grpc.pyi +16 -0
  18. luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.py +25 -3
  19. luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2.pyi +32 -0
  20. luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2_grpc.py +34 -0
  21. luminarycloud/_proto/api/v0/luminarycloud/simulation_template/simulation_template_pb2_grpc.pyi +12 -0
  22. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.py +68 -21
  23. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2.pyi +119 -0
  24. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.py +33 -0
  25. luminarycloud/_proto/api/v0/luminarycloud/vis/vis_pb2_grpc.pyi +10 -0
  26. luminarycloud/_proto/client/simulation_pb2.py +405 -346
  27. luminarycloud/_proto/client/simulation_pb2.pyi +175 -21
  28. luminarycloud/_proto/clusterconfig/clusterconfig_pb2.py +273 -0
  29. luminarycloud/_proto/clusterconfig/clusterconfig_pb2.pyi +808 -0
  30. luminarycloud/_proto/geometry/geometry_pb2.pyi +1 -1
  31. luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2.py +2 -2
  32. luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.py +68 -0
  33. luminarycloud/_proto/physicsaitrainingservice/physicsaitrainingservice_pb2_grpc.pyi +24 -0
  34. luminarycloud/enum/__init__.py +1 -0
  35. luminarycloud/enum/gpu_type.py +42 -7
  36. luminarycloud/enum/vis_enums.py +18 -0
  37. luminarycloud/geometry.py +81 -0
  38. luminarycloud/geometry_contacts.py +222 -0
  39. luminarycloud/meshing/mesh_generation_params.py +4 -4
  40. luminarycloud/meshing/sizing_strategy/__init__.py +0 -1
  41. luminarycloud/meshing/sizing_strategy/sizing_strategies.py +0 -20
  42. luminarycloud/params/geometry/shapes.py +137 -31
  43. luminarycloud/params/outputs/__init__.py +0 -2
  44. luminarycloud/params/outputs/output.py +17 -5
  45. luminarycloud/params/simulation/__init__.py +2 -0
  46. luminarycloud/params/simulation/adaptive_mesh_refinement/active_region_.py +1 -1
  47. luminarycloud/params/simulation/adaptive_mesh_refinement/boundary_layer_profile_.py +1 -1
  48. luminarycloud/params/simulation/adaptive_mesh_refinement_.py +1 -1
  49. luminarycloud/params/simulation/adjoint_.py +8 -5
  50. luminarycloud/params/simulation/basic/gravity/gravity_off_.py +1 -1
  51. luminarycloud/params/simulation/basic/gravity/gravity_on_.py +1 -1
  52. luminarycloud/params/simulation/basic/gravity_.py +1 -1
  53. luminarycloud/params/simulation/body_frame_.py +1 -1
  54. luminarycloud/params/simulation/entity_relationships/volume_material_relationship_.py +1 -1
  55. luminarycloud/params/simulation/entity_relationships/volume_physics_relationship_.py +1 -1
  56. luminarycloud/params/simulation/entity_relationships_.py +1 -1
  57. luminarycloud/params/simulation/general_.py +1 -1
  58. luminarycloud/params/simulation/material/fluid/boussinesq_approximation/boussinesq_off_.py +1 -1
  59. luminarycloud/params/simulation/material/fluid/boussinesq_approximation/boussinesq_on_.py +1 -1
  60. luminarycloud/params/simulation/material/fluid/boussinesq_approximation_.py +1 -1
  61. luminarycloud/params/simulation/material/fluid/material_model/__init__.py +2 -0
  62. luminarycloud/params/simulation/material/fluid/material_model/ideal_gas_.py +1 -1
  63. luminarycloud/params/simulation/material/fluid/material_model/incompressible_fluid_.py +1 -1
  64. luminarycloud/params/simulation/material/fluid/material_model/incompressible_fluid_with_energy_.py +1 -1
  65. luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend/__init__.py +2 -0
  66. luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend/real_gas_coolprop_.py +43 -0
  67. luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend/real_gas_polynomial_.py +53 -0
  68. luminarycloud/params/simulation/material/fluid/material_model/real_gas_backend_.py +29 -0
  69. luminarycloud/params/simulation/material/fluid/material_model_.py +1 -1
  70. luminarycloud/params/simulation/material/fluid/thermal_conductivity_model/prescribed_conductivity_.py +1 -1
  71. luminarycloud/params/simulation/material/fluid/thermal_conductivity_model/prescribed_prandtl_number_.py +1 -1
  72. luminarycloud/params/simulation/material/fluid/thermal_conductivity_model/temperature_dependent_conductivity_.py +1 -1
  73. luminarycloud/params/simulation/material/fluid/thermal_conductivity_model_.py +1 -1
  74. luminarycloud/params/simulation/material/fluid/viscosity_model/prescribed_viscosity_.py +1 -1
  75. luminarycloud/params/simulation/material/fluid/viscosity_model/sutherland_.py +1 -1
  76. luminarycloud/params/simulation/material/fluid/viscosity_model/temperature_dependent_viscosity_.py +1 -1
  77. luminarycloud/params/simulation/material/fluid/viscosity_model_.py +1 -1
  78. luminarycloud/params/simulation/material/material_fluid_.py +78 -2
  79. luminarycloud/params/simulation/material/material_solid_.py +1 -1
  80. luminarycloud/params/simulation/material_entity_.py +1 -1
  81. luminarycloud/params/simulation/monitor_plane_.py +1 -1
  82. luminarycloud/params/simulation/motion_data/frame_transforms/no_transform_.py +1 -1
  83. luminarycloud/params/simulation/motion_data/frame_transforms/rotational_transform_.py +1 -1
  84. luminarycloud/params/simulation/motion_data/frame_transforms/translational_transform_.py +1 -1
  85. luminarycloud/params/simulation/motion_data/frame_transforms_.py +1 -1
  86. luminarycloud/params/simulation/motion_data/motion_type/constant_angular_motion_.py +1 -1
  87. luminarycloud/params/simulation/motion_data/motion_type/constant_translation_motion_.py +1 -1
  88. luminarycloud/params/simulation/motion_data/motion_type_.py +1 -1
  89. luminarycloud/params/simulation/motion_data_.py +1 -1
  90. luminarycloud/params/simulation/multi_physics_coupling_options_.py +1 -1
  91. luminarycloud/params/simulation/nonlinear_control/__init__.py +1 -0
  92. luminarycloud/params/simulation/nonlinear_control/nonlinear_control_system_.py +48 -0
  93. luminarycloud/params/simulation/nonlinear_control_.py +61 -0
  94. luminarycloud/params/simulation/output_.py +1 -1
  95. luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk/actuator_disk_orientation_selection/actuator_disk_specify_normal_vector_.py +1 -1
  96. luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk/actuator_disk_orientation_selection/actuator_disk_specify_rotation_angles_.py +1 -1
  97. luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk/actuator_disk_orientation_selection_.py +1 -1
  98. luminarycloud/params/simulation/particle_group/particle_group_type/actuator_disk_.py +1 -1
  99. luminarycloud/params/simulation/particle_group/particle_group_type/actuator_line_.py +1 -1
  100. luminarycloud/params/simulation/particle_group/particle_group_type/probe_points_.py +1 -1
  101. luminarycloud/params/simulation/particle_group/particle_group_type/source_points_.py +1 -1
  102. luminarycloud/params/simulation/particle_group/particle_group_type_.py +1 -1
  103. luminarycloud/params/simulation/particle_group_.py +1 -1
  104. luminarycloud/params/simulation/physics/fluid/adjoint_controls_fluid_.py +1 -1
  105. luminarycloud/params/simulation/physics/fluid/basic_fluid_.py +1 -1
  106. luminarycloud/params/simulation/physics/fluid/boundary_conditions/farfield_.py +1 -1
  107. luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/fan_curve_inlet_.py +1 -1
  108. luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/mach_inlet_.py +1 -1
  109. luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/mass_flow_inlet_.py +1 -1
  110. luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/total_pressure_inlet_.py +1 -1
  111. luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/velocity_components_inlet_.py +1 -1
  112. luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet/velocity_magnitude_inlet_.py +1 -1
  113. luminarycloud/params/simulation/physics/fluid/boundary_conditions/inlet_.py +1 -1
  114. luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/fan_curve_outlet_.py +1 -1
  115. luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/outlet_pressure_.py +1 -1
  116. luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/outlet_target_corrected_mass_flow_rate_.py +1 -1
  117. luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy/outlet_target_mass_flow_rate_.py +1 -1
  118. luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet/outlet_strategy_.py +1 -1
  119. luminarycloud/params/simulation/physics/fluid/boundary_conditions/outlet_.py +1 -1
  120. luminarycloud/params/simulation/physics/fluid/boundary_conditions/symmetry_.py +1 -1
  121. luminarycloud/params/simulation/physics/fluid/boundary_conditions/turbulence_boundary_conditions_.py +1 -1
  122. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/energy/prescribed_heat_flux_.py +1 -1
  123. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/energy/prescribed_temperature_.py +1 -1
  124. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/momentum/no_slip_.py +1 -1
  125. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/momentum/slip_.py +1 -1
  126. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/momentum/wall_model_.py +1 -1
  127. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/wall_energy_.py +1 -1
  128. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall/wall_momentum_.py +1 -1
  129. luminarycloud/params/simulation/physics/fluid/boundary_conditions/wall_.py +1 -1
  130. luminarycloud/params/simulation/physics/fluid/boundary_conditions_fluid_.py +1 -1
  131. luminarycloud/params/simulation/physics/fluid/initialization/__init__.py +1 -0
  132. luminarycloud/params/simulation/physics/fluid/initialization/fluid_existing_solution_.py +1 -1
  133. luminarycloud/params/simulation/physics/fluid/initialization/fluid_farfield_values_.py +14 -1
  134. luminarycloud/params/simulation/physics/fluid/initialization/fluid_initialization_per_zone_.py +48 -0
  135. luminarycloud/params/simulation/physics/fluid/initialization/fluid_prescribed_values_.py +14 -1
  136. luminarycloud/params/simulation/physics/fluid/initialization/turbulence_initialization_.py +1 -1
  137. luminarycloud/params/simulation/physics/fluid/initialization_fluid_.py +1 -1
  138. luminarycloud/params/simulation/physics/fluid/physical_behavior/blade_element_airfoil_data_.py +1 -1
  139. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/actuator_disk_blade_element_.py +1 -1
  140. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/actuator_disk_radial_distribution_.py +1 -1
  141. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/actuator_disk_uniform_thrust_.py +1 -1
  142. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model/fan_curve_internal_.py +1 -1
  143. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_disk_model_.py +1 -1
  144. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_line_model/actuator_line_blade_element_.py +1 -1
  145. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/actuator_line_model_.py +1 -1
  146. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/blade_element_params_.py +1 -1
  147. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/particle_source_model/general_acceleration_source_.py +1 -1
  148. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/particle_source_model/general_mass_source_.py +1 -1
  149. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model/particle_source_model_.py +1 -1
  150. luminarycloud/params/simulation/physics/fluid/physical_behavior/physical_behavior_model_.py +1 -1
  151. luminarycloud/params/simulation/physics/fluid/physical_behavior_.py +1 -1
  152. luminarycloud/params/simulation/physics/fluid/porous_behavior_.py +1 -1
  153. luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_explicit_relaxation_.py +1 -1
  154. luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_auto_.py +1 -1
  155. luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_off_.py +1 -1
  156. luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup/robust_startup_on_.py +1 -1
  157. luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation/robust_startup_.py +1 -1
  158. luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method/fluid_implicit_relaxation_.py +1 -1
  159. luminarycloud/params/simulation/physics/fluid/solution_controls/fluid_relaxation_method_.py +1 -1
  160. luminarycloud/params/simulation/physics/fluid/solution_controls/pseudo_time_step_method/cfl_based_.py +1 -1
  161. luminarycloud/params/simulation/physics/fluid/solution_controls/pseudo_time_step_method/fixed_pseudo_time_step_.py +1 -1
  162. luminarycloud/params/simulation/physics/fluid/solution_controls/pseudo_time_step_method_.py +1 -1
  163. luminarycloud/params/simulation/physics/fluid/solution_controls_fluid_.py +1 -1
  164. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/ec2_.py +1 -1
  165. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/fds_.py +1 -1
  166. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/ld2_.py +1 -1
  167. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme/rhie_chow_.py +1 -1
  168. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_.py +1 -1
  169. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_order/first_order_.py +1 -1
  170. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_order/second_order_.py +1 -1
  171. luminarycloud/params/simulation/physics/fluid/spatial_discretization/convective_scheme_order_.py +1 -1
  172. luminarycloud/params/simulation/physics/fluid/spatial_discretization_fluid_.py +1 -1
  173. luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation/ddes_.py +1 -1
  174. luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation/ddes_vtm_.py +1 -1
  175. luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation/iddes_.py +1 -1
  176. luminarycloud/params/simulation/physics/fluid/turbulence/des_formulation_.py +1 -1
  177. luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst/constants/custom_komega_sst_constants_.py +1 -1
  178. luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst/constants/default_komega_sst_constants_.py +1 -1
  179. luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst/komega_sst_constants_.py +1 -1
  180. luminarycloud/params/simulation/physics/fluid/turbulence/komega_sst_.py +1 -1
  181. luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras/constants/custom_spalart_allmaras_constants_.py +1 -1
  182. luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras/constants/default_spalart_allmaras_constants_.py +1 -1
  183. luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras/spalart_allmaras_constants_.py +1 -1
  184. luminarycloud/params/simulation/physics/fluid/turbulence/spalart_allmaras_.py +1 -1
  185. luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/amd_.py +1 -1
  186. luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/sigma_.py +1 -1
  187. luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/smagorinsky_.py +1 -1
  188. luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/vreman_.py +1 -1
  189. luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model/wale_.py +1 -1
  190. luminarycloud/params/simulation/physics/fluid/turbulence/sub_grid_scale_model_.py +1 -1
  191. luminarycloud/params/simulation/physics/fluid/turbulence_.py +1 -1
  192. luminarycloud/params/simulation/physics/fluid_.py +1 -1
  193. luminarycloud/params/simulation/physics/heat/adjoint_controls_heat_.py +1 -1
  194. luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_convection_.py +1 -1
  195. luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_heat_flux_.py +1 -1
  196. luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_integrated_heat_flux_.py +1 -1
  197. luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_symmetry_.py +1 -1
  198. luminarycloud/params/simulation/physics/heat/boundary_conditions/heat_bc_temperature_.py +1 -1
  199. luminarycloud/params/simulation/physics/heat/boundary_conditions_heat_.py +1 -1
  200. luminarycloud/params/simulation/physics/heat/heat_source/heat_source_type/heat_source_type_power_.py +1 -1
  201. luminarycloud/params/simulation/physics/heat/heat_source/heat_source_type/heat_source_type_power_per_unit_of_volume_.py +1 -1
  202. luminarycloud/params/simulation/physics/heat/heat_source/heat_source_type_.py +1 -1
  203. luminarycloud/params/simulation/physics/heat/heat_source_.py +1 -1
  204. luminarycloud/params/simulation/physics/heat/initialization/__init__.py +1 -0
  205. luminarycloud/params/simulation/physics/heat/initialization/heat_existing_solution_.py +1 -1
  206. luminarycloud/params/simulation/physics/heat/initialization/heat_prescribed_values/__init__.py +1 -0
  207. luminarycloud/params/simulation/physics/heat/initialization/heat_prescribed_values/heat_initialization_per_zone_.py +40 -0
  208. luminarycloud/params/simulation/physics/heat/initialization/heat_prescribed_values_.py +14 -1
  209. luminarycloud/params/simulation/physics/heat/initialization_heat_.py +1 -1
  210. luminarycloud/params/simulation/physics/heat/solution_controls/heat_relaxation_method/heat_implicit_relaxation_.py +1 -1
  211. luminarycloud/params/simulation/physics/heat/solution_controls/heat_relaxation_method_.py +1 -1
  212. luminarycloud/params/simulation/physics/heat/solution_controls_heat_.py +1 -1
  213. luminarycloud/params/simulation/physics/heat/spatial_discretization_heat_.py +1 -1
  214. luminarycloud/params/simulation/physics/heat_.py +1 -1
  215. luminarycloud/params/simulation/physics/periodic_pair_.py +5 -1
  216. luminarycloud/params/simulation/physics/solution_controls/linear_solver_type/gauss_seidel_.py +1 -1
  217. luminarycloud/params/simulation/physics/solution_controls/linear_solver_type/krylov_amg_.py +1 -1
  218. luminarycloud/params/simulation/physics/solution_controls/linear_solver_type_.py +1 -1
  219. luminarycloud/params/simulation/physics_.py +1 -1
  220. luminarycloud/params/simulation/simulation_param_.py +8 -1
  221. luminarycloud/params/simulation/sliding_interfaces_.py +1 -1
  222. luminarycloud/params/simulation/surface_name_.py +1 -1
  223. luminarycloud/params/simulation/time/compute_statistics/compute_statistics_off_.py +1 -1
  224. luminarycloud/params/simulation/time/compute_statistics/compute_statistics_on_.py +1 -1
  225. luminarycloud/params/simulation/time/compute_statistics_.py +1 -1
  226. luminarycloud/params/simulation/time/time_marching/time_explicit_.py +1 -1
  227. luminarycloud/params/simulation/time/time_marching/time_implicit_.py +1 -1
  228. luminarycloud/params/simulation/time/time_marching_.py +1 -1
  229. luminarycloud/params/simulation/time/time_step_ramp/time_step_ramp_off_.py +1 -1
  230. luminarycloud/params/simulation/time/time_step_ramp/time_step_ramp_on_.py +1 -1
  231. luminarycloud/params/simulation/time/time_step_ramp_.py +1 -1
  232. luminarycloud/params/simulation/time_.py +1 -1
  233. luminarycloud/params/simulation/volume_entity_.py +1 -1
  234. luminarycloud/physics_ai/__init__.py +9 -0
  235. luminarycloud/physics_ai/architectures.py +129 -17
  236. luminarycloud/physics_ai/datasets.py +66 -11
  237. luminarycloud/physics_ai/training_jobs.py +50 -4
  238. luminarycloud/pipelines/__init__.py +5 -4
  239. luminarycloud/pipelines/api.py +148 -34
  240. luminarycloud/pipelines/arguments.py +8 -3
  241. luminarycloud/pipelines/core.py +10 -72
  242. luminarycloud/pipelines/stages.py +28 -25
  243. luminarycloud/pipelines/user_code_validation.py +122 -0
  244. luminarycloud/project.py +0 -14
  245. luminarycloud/simulation.py +42 -11
  246. luminarycloud/simulation_param.py +0 -62
  247. luminarycloud/simulation_template.py +1 -11
  248. luminarycloud/types/adfloat.py +48 -4
  249. luminarycloud/types/matrix3.py +9 -9
  250. luminarycloud/types/vector3.py +52 -23
  251. luminarycloud/vis/__init__.py +3 -0
  252. luminarycloud/vis/visualization.py +88 -0
  253. luminarycloud/volume_selection.py +29 -17
  254. {luminarycloud-0.22.3.dist-info → luminarycloud-0.23.0.dist-info}/METADATA +1 -1
  255. {luminarycloud-0.22.3.dist-info → luminarycloud-0.23.0.dist-info}/RECORD +257 -244
  256. luminarycloud/params/outputs/residual_output.py +0 -24
  257. /luminarycloud/params/{simulation/_lib.py → _lib.py} +0 -0
  258. {luminarycloud-0.22.3.dist-info → luminarycloud-0.23.0.dist-info}/WHEEL +0 -0
luminarycloud/project.py CHANGED
@@ -30,7 +30,6 @@ from ._helpers import (
30
30
  list_inference_jobs,
31
31
  SurfaceForInference,
32
32
  )
33
- from ._helpers.warnings import deprecated
34
33
  from ._proto.api.v0.luminarycloud.geometry import geometry_pb2 as geometrypb
35
34
  from ._proto.api.v0.luminarycloud.mesh import mesh_pb2 as meshpb
36
35
  from ._proto.api.v0.luminarycloud.named_variable_set import (
@@ -833,19 +832,6 @@ def get_project(
833
832
  return Project(res.project)
834
833
 
835
834
 
836
- @deprecated("Use iterate_projects() instead.", "0.10.1")
837
- def list_projects() -> list[Project]:
838
- """
839
- List projects accessible by the user.
840
-
841
- .. deprecated:: 0.10.1
842
- `list_projects()` will be removed in v0.11.0, it is replaced by
843
- `iterate_projects()` because the latter provides a more efficient
844
- way to fetch projects.
845
- """
846
- return list(iterate_projects())
847
-
848
-
849
835
  class ProjectIterator(PaginationIterator[Project]):
850
836
  """Iterator class for projects that provides length hint."""
851
837
 
@@ -6,7 +6,6 @@ from typing import Optional
6
6
  from ._client import get_default_client
7
7
  from ._helpers._timestamp_to_datetime import timestamp_to_datetime
8
8
  from ._helpers._wait_for_simulation import wait_for_simulation
9
- from ._helpers.warnings import deprecated
10
9
  from ._proto.api.v0.luminarycloud.common import common_pb2 as commonpb
11
10
  from ._proto.api.v0.luminarycloud.simulation import simulation_pb2 as simulationpb
12
11
  from ._proto.api.v0.luminarycloud.solution import solution_pb2 as solutionpb
@@ -16,14 +15,14 @@ from ._wrapper import ProtoWrapper, ProtoWrapperBase
16
15
  from .enum import (
17
16
  AveragingType,
18
17
  CalculationType,
18
+ MomentConventionType,
19
19
  QuantityType,
20
20
  ResidualNormalization,
21
- MomentConventionType,
22
21
  SimulationStatus,
23
22
  Vector3Component,
24
23
  )
24
+ from .outputs import ForceOutputDefinition, SurfaceAverageOutputDefinition
25
25
  from .outputs.stopping_conditions import StoppingConditionStatusResult
26
- from .simulation_param import SimulationParam
27
26
  from .reference_values import ReferenceValues
28
27
  from .simulation_param import SimulationParam
29
28
  from .solution import Solution
@@ -74,7 +73,7 @@ class Simulation(ProtoWrapperBase):
74
73
  def update(
75
74
  self,
76
75
  *,
77
- name: str = None,
76
+ name: Optional[str] = None,
78
77
  ) -> None:
79
78
  """
80
79
  Update/Edit simulation attributes.
@@ -184,7 +183,7 @@ class Simulation(ProtoWrapperBase):
184
183
  quantity_type: QuantityType,
185
184
  surface_ids: list[str],
186
185
  *,
187
- reference_values: ReferenceValues = None,
186
+ reference_values: Optional[ReferenceValues] = None,
188
187
  calculation_type: CalculationType = CalculationType.AGGREGATE,
189
188
  frame_id: str = "",
190
189
  force_direction: Optional[Vector3Like] = None,
@@ -279,6 +278,44 @@ class Simulation(ProtoWrapperBase):
279
278
  res = get_default_client().GetSimulationSurfaceQuantityOutput(req)
280
279
  return _DownloadedTextFile(res.csv_file)
281
280
 
281
+ def download_output_from_definition(
282
+ self,
283
+ output_definition: ForceOutputDefinition | SurfaceAverageOutputDefinition,
284
+ *,
285
+ reference_values: Optional[ReferenceValues] = None,
286
+ ):
287
+ """
288
+ Downloads surface outputs (e.g. lift, drag, ...) in csv format based on an output
289
+ definition.
290
+
291
+ Unless `reference_values` is explicitly passed, the Simulation's reference values -- i.e.
292
+ the ones specified when the Simulation was created -- will be used for computing
293
+ non-dimensional output quantities. While the Luminary Cloud UI lets you update the reference
294
+ values on a Simulation result after it has run, those updates only affect the output
295
+ calculations seen in the UI, they have no effect on the ones retrieved by this method.
296
+
297
+ Parameters
298
+ ----------
299
+ output_definition : ForceOutputDefinition | SurfaceAverageOutputDefinition
300
+ Output definition
301
+
302
+ Other Parameters
303
+ ----------------
304
+ reference_values : ReferenceValues, optional
305
+ Reference values used for computing forces, moments, and other non-dimensional output
306
+ quantities. If not provided, the simulation's reference values will be used, i.e., the
307
+ ones specified when the simulation was created.
308
+ """
309
+ req = simulationpb.GetSimulationOutputFromDefinitionRequest(
310
+ id=self.id,
311
+ output_definition=output_definition._to_proto(),
312
+ reference_values=(
313
+ reference_values._to_proto() if reference_values else ReferenceValues()._to_proto()
314
+ ),
315
+ )
316
+ res = get_default_client().GetSimulationOutputFromDefinition(req)
317
+ return _DownloadedTextFile(res.csv_file)
318
+
282
319
  def delete(self) -> None:
283
320
  """
284
321
  Delete the simulation.
@@ -349,12 +386,6 @@ class Simulation(ProtoWrapperBase):
349
386
  res = get_default_client().GetStoppingConditionStatus(req)
350
387
  return StoppingConditionStatusResult._from_proto(res)
351
388
 
352
- @deprecated(
353
- "Use get_parameters() instead. This method will be removed in a future release.",
354
- )
355
- def get_simulation_param(self) -> SimulationParam:
356
- return self.get_parameters()
357
-
358
389
  # This is used by the assistant for the SDK Code shown in the Results tab.
359
390
  def _to_code(self) -> str:
360
391
  return f"""# This code shows how to modify the parameters of the current simulation to create a new one.
@@ -247,63 +247,6 @@ class SimulationParam(_SimulationParam):
247
247
  )
248
248
  )
249
249
 
250
- def configure_adjoint_surface_output(
251
- self,
252
- quantity_type: QuantityType,
253
- surface_ids: list[str],
254
- *,
255
- reference_values: ReferenceValues = None,
256
- frame_id: str = "",
257
- force_direction: Optional[Vector3Like] = None,
258
- moment_center: Optional[Vector3Like] = None,
259
- moment_convention_type: MomentConventionType = MomentConventionType.BODY_FRAME,
260
- averaging_type: AveragingType = AveragingType.UNSPECIFIED,
261
- ) -> None:
262
- """
263
- Helper to configure the surface output differentiated by the adjoint solver.
264
- See Simulation.download_surface_output() for details on the input parameters.
265
-
266
- .. warning:: This feature is experimental and may change or be removed without notice.
267
- """
268
- self.adjoint = self.adjoint or Adjoint()
269
- self.adjoint._output = outputpb.Output()
270
- self.adjoint._output.quantity = quantity_type.value
271
- self.adjoint._output.in_surfaces.extend(surface_ids)
272
- self.adjoint._output.frame_id = frame_id
273
- if QuantityType._is_average(quantity_type):
274
- if averaging_type == AveragingType.UNSPECIFIED:
275
- self.adjoint._output.surface_average_properties.averaging_type = (
276
- SpaceAveragingType.NO_AVERAGING.value
277
- )
278
- elif averaging_type == AveragingType.AREA:
279
- self.adjoint._output.surface_average_properties.averaging_type = (
280
- SpaceAveragingType.AREA.value
281
- )
282
- elif averaging_type == AveragingType.MASS_FLOW:
283
- self.adjoint._output.surface_average_properties.averaging_type = (
284
- SpaceAveragingType.MASS_FLOW.value
285
- )
286
- elif QuantityType._is_force(quantity_type):
287
- self.adjoint._output.force_properties.CopyFrom(
288
- outputpb.ForceProperties(
289
- force_dir_type=(
290
- outputpb.FORCE_DIRECTION_BODY_ORIENTATION_AND_FLOW_DIR
291
- if quantity_type._has_tag(quantityoptspb.TAG_AUTO_DIRECTION)
292
- else outputpb.FORCE_DIRECTION_CUSTOM
293
- ),
294
- force_direction=(
295
- _to_vector3_ad_proto(force_direction) if force_direction else None
296
- ),
297
- moment_center=_to_vector3_ad_proto(moment_center) if moment_center else None,
298
- moment_convention_type=moment_convention_type.value,
299
- )
300
- )
301
- else:
302
- raise ValueError("Invalid QuantityType.")
303
-
304
- if reference_values is not None:
305
- self.reference_values = reference_values
306
-
307
250
  def __repr__(self) -> str:
308
251
  return pformat(vars(self), compact=True, sort_dicts=True)
309
252
 
@@ -334,11 +277,6 @@ from luminarycloud import outputs, SimulationParam, EntityIdentifier
334
277
  code += self._to_code_helper("obj", hide_defaults, use_tmp_objs).replace(
335
278
  "luminarycloud.simulation_param.SimulationParam()", "luminarycloud.SimulationParam()", 1
336
279
  )
337
- if self.adjoint.primal_simulation_id != "":
338
- code += """
339
- # TODO(USER): Select appropriate parameters to configure the adjoint output.
340
- obj.configure_adjoint_output("...")
341
- """
342
280
  return code
343
281
 
344
282
  def find_parameter(self, parameter: str) -> None:
@@ -8,7 +8,6 @@ from difflib import Differ
8
8
  from .enum import (
9
9
  TableType,
10
10
  )
11
- from ._helpers.warnings import deprecated
12
11
  from ._client import get_default_client
13
12
  from ._helpers._simulation_params_from_json import simulation_params_from_json_path
14
13
  from ._helpers._timestamp_to_datetime import timestamp_to_datetime
@@ -180,15 +179,6 @@ class SimulationTemplate(ProtoWrapperBase):
180
179
  """
181
180
  return SimulationParam.from_proto(self._proto.parameters)
182
181
 
183
- @deprecated(
184
- "Use get_parameters() instead. This method will be removed in a future release.",
185
- )
186
- def get_simulation_param(self) -> SimulationParam:
187
- """
188
- Returns a copy of the simulation parameters associated with this template.
189
- """
190
- return self.get_parameters()
191
-
192
182
  def list_tables(
193
183
  self,
194
184
  table_type: Optional[TableType] = None,
@@ -490,7 +480,7 @@ class SimulationTemplate(ProtoWrapperBase):
490
480
  code += "\n\n\n"
491
481
  code += '# Create a new simulation template or modify the one that is synced with the UI "Setup" tab.\n'
492
482
  code += f'project = luminarycloud.get_project("{self.project_id}")\n'
493
- escaped_name = self.name.replace('\\','\\\\').replace('"','\\"')
483
+ escaped_name = self.name.replace("\\", "\\\\").replace('"', '\\"')
494
484
  code += f'template = project.create_simulation_template(name="{escaped_name}")\n'
495
485
  code += '# TODO(USER): To modify the "Setup" template, uncomment the line below and comment out the line above.\n'
496
486
  code += "# template = project.list_simulation_templates()[0] # Setup template\n\n"
@@ -1,5 +1,8 @@
1
+ import warnings
1
2
  from abc import ABCMeta
2
- from typing import Any, Union
3
+ from functools import total_ordering
4
+ from typing import Any
5
+
3
6
  from .._proto.base.base_pb2 import AdFloatType, ExpressionType, FirstOrderAdType, SecondOrderAdType
4
7
 
5
8
 
@@ -9,13 +12,14 @@ class AdFloat(float, metaclass=ABCMeta):
9
12
  pass
10
13
 
11
14
 
15
+ @total_ordering
12
16
  class FirstOrderAdFloat(AdFloat):
13
17
  """An immutable float with first order adjoints/tangents attached."""
14
18
 
15
19
  _tangent: tuple[float, ...]
16
20
  _adjoint: tuple[float, ...]
17
21
 
18
- def __new__(cls: type["FirstOrderAdFloat"], value: float, *_: Any) -> "FirstOrderAdFloat":
22
+ def __new__(cls, value: float, *_: Any) -> "FirstOrderAdFloat":
19
23
  return super().__new__(cls, value)
20
24
 
21
25
  def __init__(self, value: float, tangent: tuple[float, ...], adjoint: tuple[float, ...]):
@@ -45,6 +49,11 @@ class FirstOrderAdFloat(AdFloat):
45
49
  and self.adjoint == other.adjoint
46
50
  )
47
51
 
52
+ def __lt__(self, other: Any) -> bool:
53
+ if not isinstance(other, LcFloat):
54
+ return NotImplemented
55
+ return _lcfloat_to_float(self) < _lcfloat_to_float(other)
56
+
48
57
  @staticmethod
49
58
  def _from_proto(proto: FirstOrderAdType) -> "FirstOrderAdFloat":
50
59
  return FirstOrderAdFloat(
@@ -54,6 +63,7 @@ class FirstOrderAdFloat(AdFloat):
54
63
  )
55
64
 
56
65
 
66
+ @total_ordering
57
67
  class SecondOrderAdFloat(AdFloat):
58
68
  """An immutable float with second order adjoints/tangents attached."""
59
69
 
@@ -101,6 +111,11 @@ class SecondOrderAdFloat(AdFloat):
101
111
  and self._adjoint == other._adjoint
102
112
  )
103
113
 
114
+ def __lt__(self, other: Any) -> bool:
115
+ if not isinstance(other, LcFloat):
116
+ return NotImplemented
117
+ return _lcfloat_to_float(self) < _lcfloat_to_float(other)
118
+
104
119
  @staticmethod
105
120
  def _from_proto(proto: SecondOrderAdType) -> "SecondOrderAdFloat":
106
121
  return SecondOrderAdFloat(
@@ -110,6 +125,7 @@ class SecondOrderAdFloat(AdFloat):
110
125
  )
111
126
 
112
127
 
128
+ @total_ordering
113
129
  class Expression:
114
130
  """An expression or value that can be evaluated or used in evaluations."""
115
131
 
@@ -119,6 +135,8 @@ class Expression:
119
135
  def __init__(self, expression: str):
120
136
  if not expression:
121
137
  raise ValueError("Expression cannot be empty")
138
+ # TODO(LC-26796) either evaluate here or in `_to_proto`
139
+ # (or add a separate method to evaluate, but then `Expression` would no longer be immutable)
122
140
  self._value = 0.0
123
141
  self._expression = expression
124
142
 
@@ -145,11 +163,22 @@ class Expression:
145
163
  return False
146
164
  return self._value == other._value and self._expression == other._expression
147
165
 
148
- def _to_code(self, *args) -> str:
166
+ def __lt__(self, other: Any) -> bool:
167
+ if not isinstance(other, LcFloat):
168
+ return NotImplemented
169
+ return _lcfloat_to_float(self) < _lcfloat_to_float(other)
170
+
171
+ def __float__(self) -> float:
172
+ return self._value
173
+
174
+ def __repr__(self) -> str:
175
+ return self._to_code()
176
+
177
+ def _to_code(self, *args: Any) -> str:
149
178
  return f"Expression({self._expression.__repr__()})"
150
179
 
151
180
 
152
- LcFloat = Union[float, FirstOrderAdFloat, SecondOrderAdFloat, Expression]
181
+ LcFloat = float | FirstOrderAdFloat | SecondOrderAdFloat | Expression
153
182
 
154
183
 
155
184
  def _to_ad_proto(value: LcFloat) -> AdFloatType:
@@ -190,3 +219,18 @@ def _from_ad_proto(proto: AdFloatType) -> LcFloat:
190
219
  return 0.0
191
220
 
192
221
  raise ValueError("Invalid AdFloatType proto")
222
+
223
+
224
+ def _lcfloat_to_float(value: LcFloat) -> float:
225
+ if isinstance(value, AdFloat):
226
+ return float(value)
227
+ if isinstance(value, Expression):
228
+ # TODO(LC-26796) evaluate expressions
229
+ warnings.warn(
230
+ "Attempted to convert Expression to float; result may be unexpected. "
231
+ "This behavior will be improved in a later release.",
232
+ category=UserWarning,
233
+ stacklevel=2,
234
+ )
235
+ return value.value
236
+ return value
@@ -15,9 +15,9 @@ class Matrix3:
15
15
 
16
16
  def _to_proto(self) -> basepb.Matrix3:
17
17
  return basepb.Matrix3(
18
- a=basepb.Vector3(x=self.a.x, y=self.a.y, z=self.a.z),
19
- b=basepb.Vector3(x=self.b.x, y=self.b.y, z=self.b.z),
20
- c=basepb.Vector3(x=self.c.x, y=self.c.y, z=self.c.z),
18
+ a=self.a._to_base_proto(),
19
+ b=self.b._to_base_proto(),
20
+ c=self.c._to_base_proto(),
21
21
  )
22
22
 
23
23
  def _to_ad_proto(self) -> basepb.AdMatrix3:
@@ -28,11 +28,11 @@ class Matrix3:
28
28
  )
29
29
 
30
30
  def _from_proto(self, proto: basepb.Matrix3) -> None:
31
- self.a = Vector3(x=proto.a.x, y=proto.a.y, z=proto.a.z)
32
- self.b = Vector3(x=proto.b.x, y=proto.b.y, z=proto.b.z)
33
- self.c = Vector3(x=proto.c.x, y=proto.c.y, z=proto.c.z)
31
+ self.a._from_base_proto(proto.a)
32
+ self.b._from_base_proto(proto.b)
33
+ self.c._from_base_proto(proto.c)
34
34
 
35
35
  def _from_ad_proto(self, proto: basepb.AdMatrix3) -> None:
36
- self.a = Vector3.from_ad_proto(proto.a)
37
- self.b = Vector3.from_ad_proto(proto.b)
38
- self.c = Vector3.from_ad_proto(proto.c)
36
+ self.a._from_ad_proto(proto.a)
37
+ self.b._from_ad_proto(proto.b)
38
+ self.c._from_ad_proto(proto.c)
@@ -1,13 +1,15 @@
1
1
  # Copyright 2023-2024 Luminary Cloud, Inc. All Rights Reserved.
2
+ from collections.abc import Iterator
2
3
  from dataclasses import dataclass
3
- from typing import TypeAlias, Iterator
4
+ from typing import TypeAlias
5
+
6
+ from luminarycloud.types import LcFloat
4
7
 
5
8
  from .._proto.api.v0.luminarycloud.common import common_pb2 as commonpb
6
- from .._proto.base.base_pb2 import AdVector3, Vector3 as Vector3Proto
7
- from .adfloat import (
8
- _to_ad_proto as _float_to_ad_proto,
9
- _from_ad_proto as _float_from_ad_proto,
10
- )
9
+ from .._proto.base import base_pb2 as basepb
10
+ from .adfloat import Expression, _lcfloat_to_float
11
+ from .adfloat import _from_ad_proto as _float_from_ad_proto
12
+ from .adfloat import _to_ad_proto as _float_to_ad_proto
11
13
 
12
14
 
13
15
  @dataclass
@@ -30,43 +32,64 @@ class Vector3:
30
32
  array([1., 2., 3.])
31
33
  """
32
34
 
33
- x: float = 0.0
34
- y: float = 0.0
35
- z: float = 0.0
35
+ x: LcFloat = 0.0
36
+ y: LcFloat = 0.0
37
+ z: LcFloat = 0.0
36
38
 
37
39
  def _to_proto(self) -> commonpb.Vector3:
38
- return commonpb.Vector3(x=self.x, y=self.y, z=self.z)
40
+ # TODO(LC-26796) evaluate expressions to do this conversion
41
+ if any(isinstance(c, Expression) for c in (self.x, self.y, self.z)):
42
+ raise ValueError(
43
+ "Cannot convert Vector3 with Expression components to commonpb.Vector3"
44
+ )
45
+ return commonpb.Vector3(
46
+ x=_lcfloat_to_float(self.x),
47
+ y=_lcfloat_to_float(self.y),
48
+ z=_lcfloat_to_float(self.z),
49
+ )
39
50
 
40
51
  def _from_proto(self, proto: commonpb.Vector3) -> None:
41
52
  self.x = proto.x
42
53
  self.y = proto.y
43
54
  self.z = proto.z
44
55
 
45
- def _to_ad_proto(self) -> AdVector3:
46
- advector = AdVector3()
56
+ def _to_ad_proto(self) -> basepb.AdVector3:
57
+ advector = basepb.AdVector3()
47
58
  advector.x.CopyFrom(_float_to_ad_proto(self.x))
48
59
  advector.y.CopyFrom(_float_to_ad_proto(self.y))
49
60
  advector.z.CopyFrom(_float_to_ad_proto(self.z))
50
61
  return advector
51
62
 
52
- def _to_base_proto(self) -> Vector3Proto:
53
- return Vector3Proto(x=self.x, y=self.y, z=self.z)
54
-
55
- def _from_ad_proto(self, proto: AdVector3) -> None:
63
+ def _from_ad_proto(self, proto: basepb.AdVector3) -> None:
56
64
  self.x = _float_from_ad_proto(proto.x)
57
65
  self.y = _float_from_ad_proto(proto.y)
58
66
  self.z = _float_from_ad_proto(proto.z)
59
67
 
60
68
  @classmethod
61
- def from_ad_proto(cls, proto: AdVector3) -> "Vector3":
69
+ def from_ad_proto(cls, proto: basepb.AdVector3) -> "Vector3":
62
70
  vector = cls()
63
71
  vector._from_ad_proto(proto)
64
72
  return vector
65
73
 
66
- def __getitem__(self, index: int) -> float:
74
+ def _to_base_proto(self) -> basepb.Vector3:
75
+ # TODO(LC-26796) evaluate expressions to do this conversion
76
+ if any(isinstance(c, Expression) for c in (self.x, self.y, self.z)):
77
+ raise ValueError("Cannot convert Vector3 with Expression components to basepb.Vector3")
78
+ return basepb.Vector3(
79
+ x=_lcfloat_to_float(self.x),
80
+ y=_lcfloat_to_float(self.y),
81
+ z=_lcfloat_to_float(self.z),
82
+ )
83
+
84
+ def _from_base_proto(self, proto: basepb.Vector3) -> None:
85
+ self.x = proto.x
86
+ self.y = proto.y
87
+ self.z = proto.z
88
+
89
+ def __getitem__(self, index: int) -> LcFloat:
67
90
  return [self.x, self.y, self.z][index]
68
91
 
69
- def __setitem__(self, index: int, value: float) -> None:
92
+ def __setitem__(self, index: int, value: LcFloat) -> None:
70
93
  if index == 0:
71
94
  self.x = value
72
95
  elif index == 1:
@@ -76,7 +99,7 @@ class Vector3:
76
99
  else:
77
100
  raise IndexError(f"Index {index} out of bounds for Vector3")
78
101
 
79
- def __iter__(self) -> Iterator[float]:
102
+ def __iter__(self) -> Iterator[LcFloat]:
80
103
  """Enable iteration over the vector components."""
81
104
  yield self.x
82
105
  yield self.y
@@ -90,10 +113,12 @@ class Vector3:
90
113
  Vector3Like: TypeAlias = Vector3 | list[float] | tuple[float, float, float] # type: ignore
91
114
 
92
115
 
93
- def _to_vector3(value: Vector3Like) -> Vector3:
116
+ def _to_vector3(value: Vector3Like | None) -> Vector3:
117
+ if value is None:
118
+ return Vector3()
94
119
  if isinstance(value, Vector3):
95
120
  return value
96
- elif isinstance(value, list) or isinstance(value, tuple):
121
+ elif isinstance(value, (list, tuple)):
97
122
  assert len(value) == 3
98
123
  return Vector3(value[0], value[1], value[2])
99
124
  else:
@@ -104,5 +129,9 @@ def _to_vector3_proto(value: Vector3Like) -> commonpb.Vector3:
104
129
  return _to_vector3(value)._to_proto()
105
130
 
106
131
 
107
- def _to_vector3_ad_proto(value: Vector3Like) -> AdVector3:
132
+ def _to_vector3_base_proto(value: Vector3Like) -> basepb.Vector3:
133
+ return _to_vector3(value)._to_base_proto()
134
+
135
+
136
+ def _to_vector3_ad_proto(value: Vector3Like) -> basepb.AdVector3:
108
137
  return _to_vector3(value)._to_ad_proto()
@@ -1,3 +1,4 @@
1
+ from .display import Field as Field
1
2
  from .visualization import (
2
3
  RenderOutput as RenderOutput,
3
4
  Scene as Scene,
@@ -8,6 +9,8 @@ from .visualization import (
8
9
  list_cameras as list_cameras,
9
10
  RangeResult as RangeResult,
10
11
  range_query as range_query,
12
+ ExtremaResult as ExtremaResult,
13
+ extrema_query as extrema_query,
11
14
  get_camera as get_camera,
12
15
  DirectionalCamera as DirectionalCamera,
13
16
  LookAtCamera as LookAtCamera,
@@ -25,6 +25,7 @@ from luminarycloud.enum import (
25
25
  VisQuantity,
26
26
  QuantityType,
27
27
  FieldAssociation,
28
+ ExtremaType,
28
29
  )
29
30
  from ..exceptions import NotFoundError
30
31
  from ..geometry import Geometry, get_geometry
@@ -1109,6 +1110,28 @@ class RangeResult:
1109
1110
  """ Name of the field. """
1110
1111
 
1111
1112
 
1113
+ @dc.dataclass
1114
+ class ExtremaResult:
1115
+ """
1116
+ Result from an extrema query containing information about a single extremum value.
1117
+
1118
+ .. warning:: This feature is experimental and may change or be removed in the future.
1119
+ """
1120
+
1121
+ value: float
1122
+ """ The extremum value. """
1123
+ local_cell_id: int
1124
+ """ Local cell id in the volume specified by the volume name. """
1125
+ approx_cell_center: Vector3
1126
+ """ Approximate cell center in global coordinates. """
1127
+ volume_id: str
1128
+ """ Id of the volume. """
1129
+ global_face_ids: List[int]
1130
+ """ Cell's global face ids. """
1131
+ connected_bounds_ids: List[str]
1132
+ """ Ids of any connected surfaces. """
1133
+
1134
+
1112
1135
  def range_query(solution: Solution, field_association: FieldAssociation) -> List[RangeResult]:
1113
1136
  """
1114
1137
  The range query returns the min/max values for all fields in a solution. Two
@@ -1155,6 +1178,71 @@ def range_query(solution: Solution, field_association: FieldAssociation) -> List
1155
1178
  return result
1156
1179
 
1157
1180
 
1181
+ def extrema_query(
1182
+ solution: Solution,
1183
+ field: Field,
1184
+ extrema_type: ExtremaType,
1185
+ num_values: int = 10,
1186
+ ) -> List[ExtremaResult]:
1187
+ """
1188
+ The extrema query returns the top N minimum or maximum values for a specific
1189
+ field/component in a solution. This is useful for finding hotspots, peak values,
1190
+ or other extreme conditions in your simulation results.
1191
+
1192
+ .. warning:: This feature is experimental and may change or be removed in the future.
1193
+
1194
+ Parameters
1195
+ ----------
1196
+ solution: Solution
1197
+ The solution object to query.
1198
+ field: Field
1199
+ The field (quantity and component) to query for extrema values.
1200
+ extrema_type: ExtremaType
1201
+ Whether to find minimum or maximum values.
1202
+ num_values: int
1203
+ How many extrema values to return. Default: 10
1204
+
1205
+ Returns
1206
+ -------
1207
+ List[ExtremaResult]
1208
+ A list of extrema results, each containing the value, location, and connectivity information.
1209
+ """
1210
+
1211
+ if num_values <= 0:
1212
+ raise ValueError(f"num_values must be positive, got {num_values}")
1213
+
1214
+ if field.quantity == VisQuantity.NONE:
1215
+ raise ValueError("Field quantity cannot be NONE")
1216
+
1217
+ sim = get_simulation(solution.simulation_id)
1218
+ req = vis_pb2.ExtremaQueryRequest()
1219
+ req.entity.simulation.id = solution.simulation_id
1220
+ req.entity.simulation.solution_id = solution.id
1221
+ req.project_id = sim.project_id
1222
+
1223
+ # Use the Field's _to_proto method to properly set field with quantity and component
1224
+ req.field.CopyFrom(field._to_proto())
1225
+
1226
+ req.num_values = num_values
1227
+ req.extrema_type = extrema_type
1228
+
1229
+ res: vis_pb2.ExtremaQueryReply = get_default_client().ExtremaQuery(req)
1230
+ result: List[ExtremaResult] = []
1231
+ for e in res.extrema:
1232
+ extrema_result = ExtremaResult(
1233
+ value=e.value,
1234
+ local_cell_id=e.local_cell_id,
1235
+ approx_cell_center=Vector3(
1236
+ x=e.approx_cell_center.x, y=e.approx_cell_center.y, z=e.approx_cell_center.z
1237
+ ),
1238
+ volume_id=e.volume_id,
1239
+ global_face_ids=list(e.global_face_ids),
1240
+ connected_bounds_ids=list(e.connected_bounds_ids),
1241
+ )
1242
+ result.append(extrema_result)
1243
+ return result
1244
+
1245
+
1158
1246
  def list_renders(entity: Geometry | Mesh | Solution) -> List[RenderOutput]:
1159
1247
  """
1160
1248
  Lists all previously created renders associated with a project and an entity.