diff --git a/src/ansys/acp/core/_server/direct.py b/src/ansys/acp/core/_server/direct.py index 3c5dafb24e..a28b6319eb 100644 --- a/src/ansys/acp/core/_server/direct.py +++ b/src/ansys/acp/core/_server/direct.py @@ -22,6 +22,7 @@ import dataclasses import os +import pathlib import subprocess from typing import TextIO @@ -103,6 +104,10 @@ def start(self) -> None: stdout_file = self._config.stdout_file stderr_file = self._config.stderr_file + binary = pathlib.Path(self._config.binary_path) + if not binary.exists(): + raise FileNotFoundError(f"Binary not found: '{binary}'") + port = find_free_ports()[0] self._url = f"localhost:{port}" self._stdout = open(stdout_file, mode="w", encoding="utf-8") diff --git a/src/ansys/acp/core/_tree_objects/_grpc_helpers/mapping.py b/src/ansys/acp/core/_tree_objects/_grpc_helpers/mapping.py index 5cb8353b74..95e176d96b 100644 --- a/src/ansys/acp/core/_tree_objects/_grpc_helpers/mapping.py +++ b/src/ansys/acp/core/_tree_objects/_grpc_helpers/mapping.py @@ -26,6 +26,7 @@ from typing import Any, Concatenate, Generic, TypeVar from grpc import Channel +from packaging.version import parse as parse_version from typing_extensions import ParamSpec, Self from ansys.api.acp.v0.base_pb2 import CollectionPath, DeleteRequest, ListRequest @@ -302,6 +303,14 @@ def define_mutable_mapping( """Define a mutable mapping of child tree objects.""" def collection_property(self: ParentT) -> MutableMapping[CreatableValueT]: + if self._server_version is not None: + if self._server_version < parse_version(object_class._SUPPORTED_SINCE): + raise RuntimeError( + f"The '{object_class.__name__}' object is only supported since version " + f"{object_class._SUPPORTED_SINCE} of the ACP gRPC server. The current server version is " + f"{self._server_version}." + ) + return MutableMapping._initialize_with_cache( server_wrapper=self._server_wrapper, collection_path=CollectionPath( diff --git a/src/ansys/acp/core/_tree_objects/_grpc_helpers/property_helper.py b/src/ansys/acp/core/_tree_objects/_grpc_helpers/property_helper.py index 9f3ae90735..bcef7ddfba 100644 --- a/src/ansys/acp/core/_tree_objects/_grpc_helpers/property_helper.py +++ b/src/ansys/acp/core/_tree_objects/_grpc_helpers/property_helper.py @@ -29,6 +29,7 @@ from collections.abc import Callable from functools import reduce +import sys from typing import TYPE_CHECKING, Any, TypeVar from google.protobuf.message import Message @@ -91,6 +92,27 @@ def mark_grpc_properties(cls: T) -> T: if name not in props_unique: props_unique.append(name) cls._GRPC_PROPERTIES = tuple(props_unique) + + # The 'mark_grpc_properties' decorator is also used on intermediate base + # classes which do not have the '_SUPPORTED_SINCE' attribute. We only want + # to add the version information to the final class. + if hasattr(cls, "_SUPPORTED_SINCE"): + if isinstance(cls.__doc__, str): + # When adding to the docstring, we need to match the existing + # indentation of the docstring (except the first line). + # See PEP 257 'Handling Docstring Indentation'. + # Alternatively, we could strip the common indentation from the + # docstring. + indent = sys.maxsize + for line in cls.__doc__.splitlines()[1:]: + stripped = line.lstrip() + if stripped: # ignore empty lines + indent = min(indent, len(line) - len(stripped)) + if indent == sys.maxsize: + indent = 0 + cls.__doc__ += ( + f"\n\n{indent * ' '}*Added in ACP server version {cls._SUPPORTED_SINCE}.*\n" + ) return cls diff --git a/src/ansys/acp/core/_tree_objects/_grpc_helpers/protocols.py b/src/ansys/acp/core/_tree_objects/_grpc_helpers/protocols.py index 35bfdea392..9ffeac391f 100644 --- a/src/ansys/acp/core/_tree_objects/_grpc_helpers/protocols.py +++ b/src/ansys/acp/core/_tree_objects/_grpc_helpers/protocols.py @@ -151,6 +151,7 @@ class GrpcObjectBase(Protocol): __slots__: Iterable[str] = tuple() _GRPC_PROPERTIES: tuple[str, ...] = tuple() + _SUPPORTED_SINCE: str def __str__(self) -> str: string_items = [] diff --git a/src/ansys/acp/core/_tree_objects/_grpc_helpers/supported_since.py b/src/ansys/acp/core/_tree_objects/_grpc_helpers/supported_since.py index e27b63ff5e..2b67cdf4b5 100644 --- a/src/ansys/acp/core/_tree_objects/_grpc_helpers/supported_since.py +++ b/src/ansys/acp/core/_tree_objects/_grpc_helpers/supported_since.py @@ -45,10 +45,10 @@ def supported_since( Parameters ---------- - version : Optional[str] + version : The server version since which the method is supported. If ``None``, the decorator does nothing. - err_msg_tpl : Optional[str] + err_msg_tpl : A custom error message template. If ``None``, a default error message is used. """ if version is None: @@ -69,7 +69,7 @@ def inner(self: T, /, *args: P.args, **kwargs: P.kwargs) -> R: if server_version < required_version: if err_msg_tpl is None: err_msg = ( - f"The method '{func.__name__}' is only supported since version {version} " + f"The '{func.__name__}' method is only supported since version {version} " f"of the ACP gRPC server. The current server version is {server_version}." ) else: diff --git a/src/ansys/acp/core/_tree_objects/analysis_ply.py b/src/ansys/acp/core/_tree_objects/analysis_ply.py index 485c427e07..dd4e64ce5c 100644 --- a/src/ansys/acp/core/_tree_objects/analysis_ply.py +++ b/src/ansys/acp/core/_tree_objects/analysis_ply.py @@ -105,6 +105,7 @@ class AnalysisPly(ReadOnlyTreeObject, IdTreeObject): _COLLECTION_LABEL = "analysis_plies" _OBJECT_INFO_TYPE = analysis_ply_pb2.ObjectInfo + _SUPPORTED_SINCE = "24.2" def _create_stub(self) -> analysis_ply_pb2_grpc.ObjectServiceStub: return analysis_ply_pb2_grpc.ObjectServiceStub(self._channel) diff --git a/src/ansys/acp/core/_tree_objects/base.py b/src/ansys/acp/core/_tree_objects/base.py index 8e0a11133f..045b24e50b 100644 --- a/src/ansys/acp/core/_tree_objects/base.py +++ b/src/ansys/acp/core/_tree_objects/base.py @@ -76,6 +76,7 @@ class TreeObjectBase(ObjectCacheMixin, GrpcObjectBase): _COLLECTION_LABEL: str _OBJECT_INFO_TYPE: type[ObjectInfo] + _SUPPORTED_SINCE: str _pb_object: ObjectInfo name: ReadOnlyProperty[str] @@ -328,6 +329,13 @@ def store(self: Self, parent: TreeObject) -> None: Parent object to store the object under. """ self._server_wrapper_store = parent._server_wrapper + assert self._server_version is not None + if self._server_version < parse_version(self._SUPPORTED_SINCE): + raise RuntimeError( + f"The '{type(self).__name__}' object is only supported since version " + f"{self._SUPPORTED_SINCE} of the ACP gRPC server. The current server version is " + f"{self._server_version}." + ) collection_path = CollectionPath( value=_rp_join(parent._resource_path.value, self._COLLECTION_LABEL) diff --git a/src/ansys/acp/core/_tree_objects/boolean_selection_rule.py b/src/ansys/acp/core/_tree_objects/boolean_selection_rule.py index 4688496ea2..d1f90f3edb 100644 --- a/src/ansys/acp/core/_tree_objects/boolean_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/boolean_selection_rule.py @@ -91,6 +91,7 @@ class BooleanSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "boolean_selection_rules" _OBJECT_INFO_TYPE = boolean_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = boolean_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/cad_component.py b/src/ansys/acp/core/_tree_objects/cad_component.py index 6d88892eb3..586da9c437 100644 --- a/src/ansys/acp/core/_tree_objects/cad_component.py +++ b/src/ansys/acp/core/_tree_objects/cad_component.py @@ -49,6 +49,7 @@ class CADComponent(ReadOnlyTreeObject, IdTreeObject): __slots__: Iterable[str] = tuple() _COLLECTION_LABEL = "cad_components" _OBJECT_INFO_TYPE = cad_component_pb2.ObjectInfo + _SUPPORTED_SINCE = "24.2" def _create_stub(self) -> cad_component_pb2_grpc.ObjectServiceStub: return cad_component_pb2_grpc.ObjectServiceStub(self._channel) diff --git a/src/ansys/acp/core/_tree_objects/cad_geometry.py b/src/ansys/acp/core/_tree_objects/cad_geometry.py index 98bca072ff..53f18a035b 100644 --- a/src/ansys/acp/core/_tree_objects/cad_geometry.py +++ b/src/ansys/acp/core/_tree_objects/cad_geometry.py @@ -108,6 +108,7 @@ class CADGeometry(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "cad_geometries" _OBJECT_INFO_TYPE = cad_geometry_pb2.ObjectInfo _CREATE_REQUEST_TYPE = cad_geometry_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/cutoff_selection_rule.py b/src/ansys/acp/core/_tree_objects/cutoff_selection_rule.py index 390fbd5674..52ea3051b1 100644 --- a/src/ansys/acp/core/_tree_objects/cutoff_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/cutoff_selection_rule.py @@ -115,6 +115,7 @@ class CutoffSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "cutoff_selection_rules" _OBJECT_INFO_TYPE = cutoff_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = cutoff_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/cylindrical_selection_rule.py b/src/ansys/acp/core/_tree_objects/cylindrical_selection_rule.py index b3e1e232c6..68fbfdfc49 100644 --- a/src/ansys/acp/core/_tree_objects/cylindrical_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/cylindrical_selection_rule.py @@ -103,6 +103,7 @@ class CylindricalSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "cylindrical_selection_rules" _OBJECT_INFO_TYPE = cylindrical_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = cylindrical_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/edge_set.py b/src/ansys/acp/core/_tree_objects/edge_set.py index 636cd25787..a02dafe226 100644 --- a/src/ansys/acp/core/_tree_objects/edge_set.py +++ b/src/ansys/acp/core/_tree_objects/edge_set.py @@ -75,6 +75,7 @@ class EdgeSet(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "edge_sets" _OBJECT_INFO_TYPE = edge_set_pb2.ObjectInfo _CREATE_REQUEST_TYPE = edge_set_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/element_set.py b/src/ansys/acp/core/_tree_objects/element_set.py index 4fa67900dc..9c75f52bb6 100644 --- a/src/ansys/acp/core/_tree_objects/element_set.py +++ b/src/ansys/acp/core/_tree_objects/element_set.py @@ -88,6 +88,7 @@ class ElementSet(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "element_sets" _OBJECT_INFO_TYPE = element_set_pb2.ObjectInfo _CREATE_REQUEST_TYPE = element_set_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/fabric.py b/src/ansys/acp/core/_tree_objects/fabric.py index 246d5ff458..be75c5f56b 100644 --- a/src/ansys/acp/core/_tree_objects/fabric.py +++ b/src/ansys/acp/core/_tree_objects/fabric.py @@ -86,6 +86,7 @@ class Fabric(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "fabrics" _OBJECT_INFO_TYPE = fabric_pb2.ObjectInfo _CREATE_REQUEST_TYPE = fabric_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/geometrical_selection_rule.py b/src/ansys/acp/core/_tree_objects/geometrical_selection_rule.py index 68af4e1a25..b73720484f 100644 --- a/src/ansys/acp/core/_tree_objects/geometrical_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/geometrical_selection_rule.py @@ -111,6 +111,7 @@ class GeometricalSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "geometrical_selection_rules" _OBJECT_INFO_TYPE = geometrical_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = geometrical_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/linked_selection_rule.py b/src/ansys/acp/core/_tree_objects/linked_selection_rule.py index 6dd88e71a4..2803e12d53 100644 --- a/src/ansys/acp/core/_tree_objects/linked_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/linked_selection_rule.py @@ -105,6 +105,8 @@ class LinkedSelectionRule(GenericEdgePropertyType): a Boolean Selection Rule, only to a Modeling Ply. """ + _SUPPORTED_SINCE = "24.2" + def __init__( self, selection_rule: _LINKABLE_SELECTION_RULE_TYPES, diff --git a/src/ansys/acp/core/_tree_objects/lookup_table_1d.py b/src/ansys/acp/core/_tree_objects/lookup_table_1d.py index 7dbb2f62b7..d1a8e39260 100644 --- a/src/ansys/acp/core/_tree_objects/lookup_table_1d.py +++ b/src/ansys/acp/core/_tree_objects/lookup_table_1d.py @@ -78,6 +78,7 @@ class LookUpTable1D(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "lookup_tables_1d" _OBJECT_INFO_TYPE = lookup_table_1d_pb2.ObjectInfo _CREATE_REQUEST_TYPE = lookup_table_1d_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/lookup_table_1d_column.py b/src/ansys/acp/core/_tree_objects/lookup_table_1d_column.py index 437f0a11f0..5ca0ab53fd 100644 --- a/src/ansys/acp/core/_tree_objects/lookup_table_1d_column.py +++ b/src/ansys/acp/core/_tree_objects/lookup_table_1d_column.py @@ -62,6 +62,7 @@ class LookUpTable1DColumn(LookUpTableColumnBase): _COLLECTION_LABEL = "lookup_table_1d_columns" _OBJECT_INFO_TYPE = lookup_table_1d_column_pb2.ObjectInfo _CREATE_REQUEST_TYPE = lookup_table_1d_column_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/lookup_table_3d.py b/src/ansys/acp/core/_tree_objects/lookup_table_3d.py index 78a3db0fa2..03b48b6807 100644 --- a/src/ansys/acp/core/_tree_objects/lookup_table_3d.py +++ b/src/ansys/acp/core/_tree_objects/lookup_table_3d.py @@ -87,6 +87,7 @@ class LookUpTable3D(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "lookup_tables_3d" _OBJECT_INFO_TYPE = lookup_table_3d_pb2.ObjectInfo _CREATE_REQUEST_TYPE = lookup_table_3d_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/lookup_table_3d_column.py b/src/ansys/acp/core/_tree_objects/lookup_table_3d_column.py index d34e9b56c1..29ecc9a504 100644 --- a/src/ansys/acp/core/_tree_objects/lookup_table_3d_column.py +++ b/src/ansys/acp/core/_tree_objects/lookup_table_3d_column.py @@ -62,6 +62,7 @@ class LookUpTable3DColumn(LookUpTableColumnBase): _COLLECTION_LABEL = "lookup_table_3d_columns" _OBJECT_INFO_TYPE = lookup_table_3d_column_pb2.ObjectInfo _CREATE_REQUEST_TYPE = lookup_table_3d_column_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/material/material.py b/src/ansys/acp/core/_tree_objects/material/material.py index 0cbf4ab40a..859c7022ed 100644 --- a/src/ansys/acp/core/_tree_objects/material/material.py +++ b/src/ansys/acp/core/_tree_objects/material/material.py @@ -128,6 +128,7 @@ class Material(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "materials" _OBJECT_INFO_TYPE = material_pb2.ObjectInfo _CREATE_REQUEST_TYPE = material_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/density.py b/src/ansys/acp/core/_tree_objects/material/property_sets/density.py index a5693511f2..aa3035c04e 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/density.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/density.py @@ -44,6 +44,7 @@ class ConstantDensity(_DensityMixin, _ConstantPropertySet): """Constant density material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" def __init__( self, @@ -65,5 +66,6 @@ class VariableDensity(_DensityMixin, _VariablePropertySet): """Variable density material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" rho = variable_material_grpc_data_property("rho") diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/engineering_constants.py b/src/ansys/acp/core/_tree_objects/material/property_sets/engineering_constants.py index bdfe87d58e..5845873371 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/engineering_constants.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/engineering_constants.py @@ -70,6 +70,7 @@ class ConstantEngineeringConstants(_EngineeringConstantsMixin, _ConstantProperty """Constant engineering constants material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" @classmethod def from_isotropic_constants( @@ -173,6 +174,7 @@ class VariableEngineeringConstants(_EngineeringConstantsMixin, _VariableProperty """Variable engineering constants material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" E = variable_material_grpc_data_property("E", **_ISOTROPIC_KWARGS) nu = variable_material_grpc_data_property("nu", **_ISOTROPIC_KWARGS) diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/fabric_fiber_angle.py b/src/ansys/acp/core/_tree_objects/material/property_sets/fabric_fiber_angle.py index a14f47cca7..ae84305398 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/fabric_fiber_angle.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/fabric_fiber_angle.py @@ -48,6 +48,7 @@ class ConstantFabricFiberAngle(_FabricFiberAngleMixin, _ConstantPropertySet): """ _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" def __init__( self, @@ -73,5 +74,6 @@ class VariableFabricFiberAngle(_FabricFiberAngleMixin, _VariablePropertySet): """ _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" fabric_fiber_angle = variable_material_grpc_data_property("fabric_fiber_angle") diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/larc_constants.py b/src/ansys/acp/core/_tree_objects/material/property_sets/larc_constants.py index ea3b606626..b5baf38527 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/larc_constants.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/larc_constants.py @@ -44,6 +44,7 @@ class ConstantLaRCConstants(_LaRCConstantsMixin, _ConstantPropertySet): """Constant LaRC failure criterion properties.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" def __init__( self, @@ -79,6 +80,7 @@ class VariableLaRCConstants(_LaRCConstantsMixin, _VariablePropertySet): """Variable LaRC failure criterion properties.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" fracture_angle_under_compression = variable_material_grpc_data_property( "fracture_angle_under_compression" diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/puck_constants.py b/src/ansys/acp/core/_tree_objects/material/property_sets/puck_constants.py index a604c44f0c..024240c5c8 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/puck_constants.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/puck_constants.py @@ -60,6 +60,7 @@ class ConstantPuckConstants(_PuckConstantsMixin, _ConstantPropertySet): """Constant Puck constants material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" def __init__( self, @@ -125,6 +126,7 @@ class VariablePuckConstants(_PuckConstantsMixin, _VariablePropertySet): """Variable Puck constants material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" p_21_pos = variable_material_grpc_data_property("p_21_pos") p_21_neg = variable_material_grpc_data_property("p_21_neg") diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/strain_limits.py b/src/ansys/acp/core/_tree_objects/material/property_sets/strain_limits.py index b40833b505..e00a3b4fa1 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/strain_limits.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/strain_limits.py @@ -70,6 +70,7 @@ class ConstantStrainLimits(_StrainLimitsMixin, _ConstantPropertySet): """Constant strain limits material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" @classmethod def from_isotropic_constants( @@ -172,6 +173,7 @@ class VariableStrainLimits(_StrainLimitsMixin, _VariablePropertySet): """Variable strain limits material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" effective_strain = variable_material_grpc_data_property("effective_strain", **_ISOTROPIC_KWARGS) eXc = variable_material_grpc_data_property("eXc", **_ORTHOTROPIC_KWARGS) diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/stress_limits.py b/src/ansys/acp/core/_tree_objects/material/property_sets/stress_limits.py index 284c1fbd15..2c895f4cb8 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/stress_limits.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/stress_limits.py @@ -70,6 +70,7 @@ class ConstantStressLimits(_StressLimitsMixin, _ConstantPropertySet): """Constant stress limits material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" @classmethod def from_isotropic_constants( @@ -172,6 +173,7 @@ class VariableStressLimits(_StressLimitsMixin, _VariablePropertySet): """Variable stress limits material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" effective_stress = variable_material_grpc_data_property("effective_stress", **_ISOTROPIC_KWARGS) Xc = variable_material_grpc_data_property("Xc", **_ORTHOTROPIC_KWARGS) diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/tsai_wu_constants.py b/src/ansys/acp/core/_tree_objects/material/property_sets/tsai_wu_constants.py index e0c0c590dd..b6439a159e 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/tsai_wu_constants.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/tsai_wu_constants.py @@ -44,6 +44,7 @@ class ConstantTsaiWuConstants(_TsaiWuConstantsMixin, _ConstantPropertySet): """Constant Tsai-Wu constants material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" def __init__( self, @@ -71,6 +72,7 @@ class VariableTsaiWuConstants(_TsaiWuConstantsMixin, _VariablePropertySet): """Variable Tsai-Wu constants material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" XY = variable_material_grpc_data_property("XY") XZ = variable_material_grpc_data_property("XZ") diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/woven_characterization.py b/src/ansys/acp/core/_tree_objects/material/property_sets/woven_characterization.py index 98164ae487..d2262e9713 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/woven_characterization.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/woven_characterization.py @@ -44,6 +44,7 @@ class ConstantWovenCharacterization(_WovenCharacterizationMixin, _ConstantProper """Constant woven characterization material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" def __init__( self, @@ -98,6 +99,7 @@ class VariableWovenCharacterization(_WovenCharacterizationMixin, _VariableProper """Variable woven characterization material property set.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" E1_1 = variable_material_grpc_data_property("E1_1") E2_1 = variable_material_grpc_data_property("E2_1") diff --git a/src/ansys/acp/core/_tree_objects/material/property_sets/woven_stress_limits.py b/src/ansys/acp/core/_tree_objects/material/property_sets/woven_stress_limits.py index eea7145dc3..b3f10a344f 100644 --- a/src/ansys/acp/core/_tree_objects/material/property_sets/woven_stress_limits.py +++ b/src/ansys/acp/core/_tree_objects/material/property_sets/woven_stress_limits.py @@ -44,6 +44,7 @@ class ConstantWovenStressLimits(_WovenStressLimitsMixin, _ConstantPropertySet): """Constant stress limits property set for woven materials.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" def __init__( self, @@ -89,6 +90,7 @@ class VariableWovenStressLimits(_WovenStressLimitsMixin, _VariablePropertySet): """Variable stress limits property set for woven materials.""" _GRPC_PROPERTIES = tuple() + _SUPPORTED_SINCE = "24.2" Xc = variable_material_grpc_data_property("Xc") Yc = variable_material_grpc_data_property("Yc") diff --git a/src/ansys/acp/core/_tree_objects/model.py b/src/ansys/acp/core/_tree_objects/model.py index 3efca801ba..3a7fa90288 100644 --- a/src/ansys/acp/core/_tree_objects/model.py +++ b/src/ansys/acp/core/_tree_objects/model.py @@ -226,6 +226,7 @@ class Model(TreeObject): _COLLECTION_LABEL = "models" _OBJECT_INFO_TYPE = model_pb2.ObjectInfo + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/modeling_group.py b/src/ansys/acp/core/_tree_objects/modeling_group.py index cfeb18d771..fb375e06cc 100644 --- a/src/ansys/acp/core/_tree_objects/modeling_group.py +++ b/src/ansys/acp/core/_tree_objects/modeling_group.py @@ -71,6 +71,7 @@ class ModelingGroup(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "modeling_groups" _OBJECT_INFO_TYPE = modeling_group_pb2.ObjectInfo _CREATE_REQUEST_TYPE = modeling_group_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__(self, *, name: str = "ModelingGroup"): super().__init__(name=name) diff --git a/src/ansys/acp/core/_tree_objects/modeling_ply.py b/src/ansys/acp/core/_tree_objects/modeling_ply.py index 5b2b201d69..36e174d451 100644 --- a/src/ansys/acp/core/_tree_objects/modeling_ply.py +++ b/src/ansys/acp/core/_tree_objects/modeling_ply.py @@ -131,6 +131,8 @@ class TaperEdge(GenericEdgePropertyType): offset is ``-offset/tan(angle)``. """ + _SUPPORTED_SINCE = "24.2" + def __init__(self, edge_set: EdgeSet, *, angle: float, offset: float): self._callback_apply_changes: Callable[[], None] | None = None self.edge_set = edge_set @@ -302,6 +304,7 @@ class ModelingPly(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "modeling_plies" _OBJECT_INFO_TYPE = modeling_ply_pb2.ObjectInfo _CREATE_REQUEST_TYPE = modeling_ply_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/oriented_selection_set.py b/src/ansys/acp/core/_tree_objects/oriented_selection_set.py index 613e60c355..064b165f84 100644 --- a/src/ansys/acp/core/_tree_objects/oriented_selection_set.py +++ b/src/ansys/acp/core/_tree_objects/oriented_selection_set.py @@ -160,6 +160,7 @@ class OrientedSelectionSet(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "oriented_selection_sets" _OBJECT_INFO_TYPE = oriented_selection_set_pb2.ObjectInfo _CREATE_REQUEST_TYPE = oriented_selection_set_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/parallel_selection_rule.py b/src/ansys/acp/core/_tree_objects/parallel_selection_rule.py index a6c28cd42a..c9bcfac5e4 100644 --- a/src/ansys/acp/core/_tree_objects/parallel_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/parallel_selection_rule.py @@ -105,6 +105,7 @@ class ParallelSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "parallel_selection_rules" _OBJECT_INFO_TYPE = parallel_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = parallel_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/production_ply.py b/src/ansys/acp/core/_tree_objects/production_ply.py index ff9d7b2eb5..eb4cd52123 100644 --- a/src/ansys/acp/core/_tree_objects/production_ply.py +++ b/src/ansys/acp/core/_tree_objects/production_ply.py @@ -104,6 +104,7 @@ class ProductionPly(ReadOnlyTreeObject, IdTreeObject): _COLLECTION_LABEL = "production_plies" _OBJECT_INFO_TYPE = production_ply_pb2.ObjectInfo + _SUPPORTED_SINCE = "24.2" def _create_stub(self) -> production_ply_pb2_grpc.ObjectServiceStub: return production_ply_pb2_grpc.ObjectServiceStub(self._channel) diff --git a/src/ansys/acp/core/_tree_objects/rosette.py b/src/ansys/acp/core/_tree_objects/rosette.py index 37c179d99a..bf51eddfe5 100644 --- a/src/ansys/acp/core/_tree_objects/rosette.py +++ b/src/ansys/acp/core/_tree_objects/rosette.py @@ -68,6 +68,7 @@ class Rosette(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "rosettes" _OBJECT_INFO_TYPE = rosette_pb2.ObjectInfo _CREATE_REQUEST_TYPE = rosette_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/sensor.py b/src/ansys/acp/core/_tree_objects/sensor.py index 8c47d03e3f..0f1e2709c1 100644 --- a/src/ansys/acp/core/_tree_objects/sensor.py +++ b/src/ansys/acp/core/_tree_objects/sensor.py @@ -76,6 +76,7 @@ class Sensor(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "sensors" _OBJECT_INFO_TYPE = sensor_pb2.ObjectInfo _CREATE_REQUEST_TYPE = sensor_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/spherical_selection_rule.py b/src/ansys/acp/core/_tree_objects/spherical_selection_rule.py index 433c8c1ae4..7fbb45702b 100644 --- a/src/ansys/acp/core/_tree_objects/spherical_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/spherical_selection_rule.py @@ -101,6 +101,7 @@ class SphericalSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "spherical_selection_rules" _OBJECT_INFO_TYPE = spherical_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = spherical_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/stackup.py b/src/ansys/acp/core/_tree_objects/stackup.py index f12ff5d762..8f69713553 100644 --- a/src/ansys/acp/core/_tree_objects/stackup.py +++ b/src/ansys/acp/core/_tree_objects/stackup.py @@ -78,6 +78,8 @@ class FabricWithAngle(GenericEdgePropertyType): """ + _SUPPORTED_SINCE = "24.2" + def __init__(self, fabric: Fabric, angle: float = 0.0): self._callback_apply_changes: Callable[[], None] | None = None self.fabric = fabric @@ -185,6 +187,7 @@ class Stackup(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "stackups" _OBJECT_INFO_TYPE = stackup_pb2.ObjectInfo _CREATE_REQUEST_TYPE = stackup_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/sublaminate.py b/src/ansys/acp/core/_tree_objects/sublaminate.py index f3e7f03ad1..ea3958d910 100644 --- a/src/ansys/acp/core/_tree_objects/sublaminate.py +++ b/src/ansys/acp/core/_tree_objects/sublaminate.py @@ -68,6 +68,8 @@ class Lamina(GenericEdgePropertyType): """ + _SUPPORTED_SINCE = "24.2" + def __init__(self, material: _LINKABLE_MATERIAL_TYPES, angle: float = 0.0): self._callback_apply_changes: Callable[[], None] | None = None self.material = material @@ -174,6 +176,7 @@ class SubLaminate(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "sublaminates" _OBJECT_INFO_TYPE = sublaminate_pb2.ObjectInfo _CREATE_REQUEST_TYPE = sublaminate_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/tube_selection_rule.py b/src/ansys/acp/core/_tree_objects/tube_selection_rule.py index 7920289228..6c3f29c63b 100644 --- a/src/ansys/acp/core/_tree_objects/tube_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/tube_selection_rule.py @@ -109,6 +109,7 @@ class TubeSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "tube_selection_rules" _OBJECT_INFO_TYPE = tube_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = tube_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/variable_offset_selection_rule.py b/src/ansys/acp/core/_tree_objects/variable_offset_selection_rule.py index 4a0be106b8..b70c8934ac 100644 --- a/src/ansys/acp/core/_tree_objects/variable_offset_selection_rule.py +++ b/src/ansys/acp/core/_tree_objects/variable_offset_selection_rule.py @@ -116,6 +116,7 @@ class VariableOffsetSelectionRule(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "variable_offset_selection_rules" _OBJECT_INFO_TYPE = variable_offset_selection_rule_pb2.ObjectInfo _CREATE_REQUEST_TYPE = variable_offset_selection_rule_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self, diff --git a/src/ansys/acp/core/_tree_objects/virtual_geometry.py b/src/ansys/acp/core/_tree_objects/virtual_geometry.py index 0af3696054..f7ab2dcb7a 100644 --- a/src/ansys/acp/core/_tree_objects/virtual_geometry.py +++ b/src/ansys/acp/core/_tree_objects/virtual_geometry.py @@ -53,6 +53,8 @@ class SubShape(GenericEdgePropertyType): """Represents a sub-shape of a virtual geometry.""" + _SUPPORTED_SINCE = "24.2" + def __init__(self, cad_geometry: CADGeometry, path: str): self._callback_apply_changes: Callable[[], None] | None = None self.cad_geometry = cad_geometry @@ -150,6 +152,7 @@ class VirtualGeometry(CreatableTreeObject, IdTreeObject): _COLLECTION_LABEL = "virtual_geometries" _OBJECT_INFO_TYPE = virtual_geometry_pb2.ObjectInfo _CREATE_REQUEST_TYPE = virtual_geometry_pb2.CreateRequest + _SUPPORTED_SINCE = "24.2" def __init__( self,