From 799ff285950ae237d0056aaee6f416ad629354ce Mon Sep 17 00:00:00 2001 From: Ninad Kamat Date: Thu, 13 Jul 2023 15:32:27 -0500 Subject: [PATCH] Update code from internal 0.5.0.dev2 development --- .../meshing/prime/autogen/connectstructs.py | 271 ++++++++++++++ .../meshing/prime/autogen/fileiostructs.py | 27 +- src/ansys/meshing/prime/autogen/igastructs.py | 340 ++++++++++++++++-- src/ansys/meshing/prime/autogen/part.py | 10 +- .../meshing/prime/autogen/primeconfig.py | 4 + .../meshing/prime/autogen/quadtospline.py | 79 ++++ .../prime/autogen/surfaceutilitystructs.py | 2 +- .../prime/autogen/thinvolumecontrolstructs.py | 64 +++- .../meshing/prime/autogen/wrapperstructs.py | 37 +- src/ansys/meshing/prime/internals/defaults.py | 6 +- 10 files changed, 790 insertions(+), 50 deletions(-) create mode 100644 src/ansys/meshing/prime/autogen/quadtospline.py diff --git a/src/ansys/meshing/prime/autogen/connectstructs.py b/src/ansys/meshing/prime/autogen/connectstructs.py index 7c3c7c2510..26b3188e6a 100644 --- a/src/ansys/meshing/prime/autogen/connectstructs.py +++ b/src/ansys/meshing/prime/autogen/connectstructs.py @@ -36,6 +36,277 @@ class MatchedMeshOption(enum.IntEnum): TRIMTWOSIDES = 4 """Delete matched faces on both sides and merge matched nodes at middle locations (works only within a single part).""" +class OverlapPairs(CoreObject): + """Provides ids of a pair of overlapping face zonelets. + """ + _default_params = {} + + def __initialize( + self, + zone_id0: int, + zone_id1: int): + self._zone_id0 = zone_id0 + self._zone_id1 = zone_id1 + + def __init__( + self, + model: CommunicationManager=None, + zone_id0: int = None, + zone_id1: int = None, + json_data : dict = None, + **kwargs): + """Initializes the OverlapPairs. + + Parameters + ---------- + model: Model + Model to create a OverlapPairs object with default parameters. + zone_id0: int, optional + Id of one overlapping face zonelet. + zone_id1: int, optional + Id of other overlapping face zonelet. + json_data: dict, optional + JSON dictionary to create a OverlapPairs object with provided parameters. + + Examples + -------- + >>> overlap_pairs = prime.OverlapPairs(model = model) + """ + if json_data: + self.__initialize( + json_data["zoneId0"] if "zoneId0" in json_data else None, + json_data["zoneId1"] if "zoneId1" in json_data else None) + else: + all_field_specified = all(arg is not None for arg in [zone_id0, zone_id1]) + if all_field_specified: + self.__initialize( + zone_id0, + zone_id1) + else: + if model is None: + raise ValueError("Invalid assignment. Either pass model or specify all properties") + else: + param_json = model._communicator.initialize_params(model, "OverlapPairs") + json_data = param_json["OverlapPairs"] if "OverlapPairs" in param_json else {} + self.__initialize( + zone_id0 if zone_id0 is not None else ( OverlapPairs._default_params["zone_id0"] if "zone_id0" in OverlapPairs._default_params else (json_data["zoneId0"] if "zoneId0" in json_data else None)), + zone_id1 if zone_id1 is not None else ( OverlapPairs._default_params["zone_id1"] if "zone_id1" in OverlapPairs._default_params else (json_data["zoneId1"] if "zoneId1" in json_data else None))) + self._custom_params = kwargs + if model is not None: + [ model._logger.warning(f'Unsupported argument : {key}') for key in kwargs ] + [setattr(type(self), key, property(lambda self, key = key: self._custom_params[key] if key in self._custom_params else None, + lambda self, value, key = key : self._custom_params.update({ key: value }))) for key in kwargs] + self._freeze() + + @staticmethod + def set_default( + zone_id0: int = None, + zone_id1: int = None): + """Set the default values of OverlapPairs. + + Parameters + ---------- + zone_id0: int, optional + Id of one overlapping face zonelet. + zone_id1: int, optional + Id of other overlapping face zonelet. + """ + args = locals() + [OverlapPairs._default_params.update({ key: value }) for key, value in args.items() if value is not None] + + @staticmethod + def print_default(): + """Print the default values of OverlapPairs. + + Examples + -------- + >>> OverlapPairs.print_default() + """ + message = "" + message += ''.join(str(key) + ' : ' + str(value) + '\n' for key, value in OverlapPairs._default_params.items()) + print(message) + + def _jsonify(self) -> Dict[str, Any]: + json_data = {} + if self._zone_id0 is not None: + json_data["zoneId0"] = self._zone_id0 + if self._zone_id1 is not None: + json_data["zoneId1"] = self._zone_id1 + [ json_data.update({ utils.to_camel_case(key) : value }) for key, value in self._custom_params.items()] + return json_data + + def __str__(self) -> str: + message = "zone_id0 : %s\nzone_id1 : %s" % (self._zone_id0, self._zone_id1) + message += ''.join('\n' + str(key) + ' : ' + str(value) for key, value in self._custom_params.items()) + return message + + @property + def zone_id0(self) -> int: + """Id of one overlapping face zonelet. + """ + return self._zone_id0 + + @zone_id0.setter + def zone_id0(self, value: int): + self._zone_id0 = value + + @property + def zone_id1(self) -> int: + """Id of other overlapping face zonelet. + """ + return self._zone_id1 + + @zone_id1.setter + def zone_id1(self, value: int): + self._zone_id1 = value + +class OverlapSearchResults(CoreObject): + """Provides ids of a pair of overlapping face zonelets. + """ + _default_params = {} + + def __initialize( + self, + n_pairs: int, + overlap_pairs: List[OverlapPairs], + error_code: ErrorCode): + self._n_pairs = n_pairs + self._overlap_pairs = overlap_pairs + self._error_code = ErrorCode(error_code) + + def __init__( + self, + model: CommunicationManager=None, + n_pairs: int = None, + overlap_pairs: List[OverlapPairs] = None, + error_code: ErrorCode = None, + json_data : dict = None, + **kwargs): + """Initializes the OverlapSearchResults. + + Parameters + ---------- + model: Model + Model to create a OverlapSearchResults object with default parameters. + n_pairs: int, optional + Number of pairs. + overlap_pairs: List[OverlapPairs], optional + Ids corresponding to pairs of overlapping face zonelets. + error_code: ErrorCode, optional + Error Code associated with failure of operation. + json_data: dict, optional + JSON dictionary to create a OverlapSearchResults object with provided parameters. + + Examples + -------- + >>> overlap_search_results = prime.OverlapSearchResults(model = model) + """ + if json_data: + self.__initialize( + json_data["nPairs"] if "nPairs" in json_data else None, + [OverlapPairs(model = model, json_data = data) for data in json_data["overlapPairs"]] if "overlapPairs" in json_data else None, + ErrorCode(json_data["errorCode"] if "errorCode" in json_data else None)) + else: + all_field_specified = all(arg is not None for arg in [n_pairs, overlap_pairs, error_code]) + if all_field_specified: + self.__initialize( + n_pairs, + overlap_pairs, + error_code) + else: + if model is None: + raise ValueError("Invalid assignment. Either pass model or specify all properties") + else: + param_json = model._communicator.initialize_params(model, "OverlapSearchResults") + json_data = param_json["OverlapSearchResults"] if "OverlapSearchResults" in param_json else {} + self.__initialize( + n_pairs if n_pairs is not None else ( OverlapSearchResults._default_params["n_pairs"] if "n_pairs" in OverlapSearchResults._default_params else (json_data["nPairs"] if "nPairs" in json_data else None)), + overlap_pairs if overlap_pairs is not None else ( OverlapSearchResults._default_params["overlap_pairs"] if "overlap_pairs" in OverlapSearchResults._default_params else [OverlapPairs(model = model, json_data = data) for data in (json_data["overlapPairs"] if "overlapPairs" in json_data else None)]), + error_code if error_code is not None else ( OverlapSearchResults._default_params["error_code"] if "error_code" in OverlapSearchResults._default_params else ErrorCode(json_data["errorCode"] if "errorCode" in json_data else None))) + self._custom_params = kwargs + if model is not None: + [ model._logger.warning(f'Unsupported argument : {key}') for key in kwargs ] + [setattr(type(self), key, property(lambda self, key = key: self._custom_params[key] if key in self._custom_params else None, + lambda self, value, key = key : self._custom_params.update({ key: value }))) for key in kwargs] + self._freeze() + + @staticmethod + def set_default( + n_pairs: int = None, + overlap_pairs: List[OverlapPairs] = None, + error_code: ErrorCode = None): + """Set the default values of OverlapSearchResults. + + Parameters + ---------- + n_pairs: int, optional + Number of pairs. + overlap_pairs: List[OverlapPairs], optional + Ids corresponding to pairs of overlapping face zonelets. + error_code: ErrorCode, optional + Error Code associated with failure of operation. + """ + args = locals() + [OverlapSearchResults._default_params.update({ key: value }) for key, value in args.items() if value is not None] + + @staticmethod + def print_default(): + """Print the default values of OverlapSearchResults. + + Examples + -------- + >>> OverlapSearchResults.print_default() + """ + message = "" + message += ''.join(str(key) + ' : ' + str(value) + '\n' for key, value in OverlapSearchResults._default_params.items()) + print(message) + + def _jsonify(self) -> Dict[str, Any]: + json_data = {} + if self._n_pairs is not None: + json_data["nPairs"] = self._n_pairs + if self._overlap_pairs is not None: + json_data["overlapPairs"] = [data._jsonify() for data in self._overlap_pairs] + if self._error_code is not None: + json_data["errorCode"] = self._error_code + [ json_data.update({ utils.to_camel_case(key) : value }) for key, value in self._custom_params.items()] + return json_data + + def __str__(self) -> str: + message = "n_pairs : %s\noverlap_pairs : %s\nerror_code : %s" % (self._n_pairs, '[' + ''.join('\n' + str(data) for data in self._overlap_pairs) + ']', self._error_code) + message += ''.join('\n' + str(key) + ' : ' + str(value) for key, value in self._custom_params.items()) + return message + + @property + def n_pairs(self) -> int: + """Number of pairs. + """ + return self._n_pairs + + @n_pairs.setter + def n_pairs(self, value: int): + self._n_pairs = value + + @property + def overlap_pairs(self) -> List[OverlapPairs]: + """Ids corresponding to pairs of overlapping face zonelets. + """ + return self._overlap_pairs + + @overlap_pairs.setter + def overlap_pairs(self, value: List[OverlapPairs]): + self._overlap_pairs = value + + @property + def error_code(self) -> ErrorCode: + """Error Code associated with failure of operation. + """ + return self._error_code + + @error_code.setter + def error_code(self, value: ErrorCode): + self._error_code = value + class ConnectResults(CoreObject): """Results associated with the connection operations. """ diff --git a/src/ansys/meshing/prime/autogen/fileiostructs.py b/src/ansys/meshing/prime/autogen/fileiostructs.py index 098f4752e1..43cbf401a8 100644 --- a/src/ansys/meshing/prime/autogen/fileiostructs.py +++ b/src/ansys/meshing/prime/autogen/fileiostructs.py @@ -1265,6 +1265,7 @@ class ImportCadParams(CoreObject): def __initialize( self, append: bool, + ansys_release: str, cad_reader_route: CadReaderRoute, part_creation_type: PartCreationType, geometry_transfer: bool, @@ -1274,6 +1275,7 @@ def __initialize( stitch_tolerance: float, cad_update_parameters: Dict[str, Union[str, int, float, bool]]): self._append = append + self._ansys_release = ansys_release self._cad_reader_route = CadReaderRoute(cad_reader_route) self._part_creation_type = PartCreationType(part_creation_type) self._geometry_transfer = geometry_transfer @@ -1287,6 +1289,7 @@ def __init__( self, model: CommunicationManager=None, append: bool = None, + ansys_release: str = None, cad_reader_route: CadReaderRoute = None, part_creation_type: PartCreationType = None, geometry_transfer: bool = None, @@ -1305,6 +1308,8 @@ def __init__( Model to create a ImportCadParams object with default parameters. append: bool, optional Append imported CAD into existing model when true. + ansys_release: str, optional + Configures the Ansys release to be used for loading CAD data through non Native route. cad_reader_route: CadReaderRoute, optional Specify the available CAD reader routes. The available CAD reader routes are ProgramControlled, Native, WorkBench, SpaceClaim. part_creation_type: PartCreationType, optional @@ -1331,6 +1336,7 @@ def __init__( if json_data: self.__initialize( json_data["append"] if "append" in json_data else None, + json_data["ansysRelease"] if "ansysRelease" in json_data else None, CadReaderRoute(json_data["cadReaderRoute"] if "cadReaderRoute" in json_data else None), PartCreationType(json_data["partCreationType"] if "partCreationType" in json_data else None), json_data["geometryTransfer"] if "geometryTransfer" in json_data else None, @@ -1340,10 +1346,11 @@ def __init__( json_data["stitchTolerance"] if "stitchTolerance" in json_data else None, json_data["cadUpdateParameters"] if "cadUpdateParameters" in json_data else None) else: - all_field_specified = all(arg is not None for arg in [append, cad_reader_route, part_creation_type, geometry_transfer, length_unit, refacet, cad_refaceting_params, stitch_tolerance, cad_update_parameters]) + all_field_specified = all(arg is not None for arg in [append, ansys_release, cad_reader_route, part_creation_type, geometry_transfer, length_unit, refacet, cad_refaceting_params, stitch_tolerance, cad_update_parameters]) if all_field_specified: self.__initialize( append, + ansys_release, cad_reader_route, part_creation_type, geometry_transfer, @@ -1360,6 +1367,7 @@ def __init__( json_data = param_json["ImportCadParams"] if "ImportCadParams" in param_json else {} self.__initialize( append if append is not None else ( ImportCadParams._default_params["append"] if "append" in ImportCadParams._default_params else (json_data["append"] if "append" in json_data else None)), + ansys_release if ansys_release is not None else ( ImportCadParams._default_params["ansys_release"] if "ansys_release" in ImportCadParams._default_params else (json_data["ansysRelease"] if "ansysRelease" in json_data else None)), cad_reader_route if cad_reader_route is not None else ( ImportCadParams._default_params["cad_reader_route"] if "cad_reader_route" in ImportCadParams._default_params else CadReaderRoute(json_data["cadReaderRoute"] if "cadReaderRoute" in json_data else None)), part_creation_type if part_creation_type is not None else ( ImportCadParams._default_params["part_creation_type"] if "part_creation_type" in ImportCadParams._default_params else PartCreationType(json_data["partCreationType"] if "partCreationType" in json_data else None)), geometry_transfer if geometry_transfer is not None else ( ImportCadParams._default_params["geometry_transfer"] if "geometry_transfer" in ImportCadParams._default_params else (json_data["geometryTransfer"] if "geometryTransfer" in json_data else None)), @@ -1378,6 +1386,7 @@ def __init__( @staticmethod def set_default( append: bool = None, + ansys_release: str = None, cad_reader_route: CadReaderRoute = None, part_creation_type: PartCreationType = None, geometry_transfer: bool = None, @@ -1392,6 +1401,8 @@ def set_default( ---------- append: bool, optional Append imported CAD into existing model when true. + ansys_release: str, optional + Configures the Ansys release to be used for loading CAD data through non Native route. cad_reader_route: CadReaderRoute, optional Specify the available CAD reader routes. The available CAD reader routes are ProgramControlled, Native, WorkBench, SpaceClaim. part_creation_type: PartCreationType, optional @@ -1428,6 +1439,8 @@ def _jsonify(self) -> Dict[str, Any]: json_data = {} if self._append is not None: json_data["append"] = self._append + if self._ansys_release is not None: + json_data["ansysRelease"] = self._ansys_release if self._cad_reader_route is not None: json_data["cadReaderRoute"] = self._cad_reader_route if self._part_creation_type is not None: @@ -1448,7 +1461,7 @@ def _jsonify(self) -> Dict[str, Any]: return json_data def __str__(self) -> str: - message = "append : %s\ncad_reader_route : %s\npart_creation_type : %s\ngeometry_transfer : %s\nlength_unit : %s\nrefacet : %s\ncad_refaceting_params : %s\nstitch_tolerance : %s\ncad_update_parameters : %s" % (self._append, self._cad_reader_route, self._part_creation_type, self._geometry_transfer, self._length_unit, self._refacet, '{ ' + str(self._cad_refaceting_params) + ' }', self._stitch_tolerance, self._cad_update_parameters) + message = "append : %s\nansys_release : %s\ncad_reader_route : %s\npart_creation_type : %s\ngeometry_transfer : %s\nlength_unit : %s\nrefacet : %s\ncad_refaceting_params : %s\nstitch_tolerance : %s\ncad_update_parameters : %s" % (self._append, self._ansys_release, self._cad_reader_route, self._part_creation_type, self._geometry_transfer, self._length_unit, self._refacet, '{ ' + str(self._cad_refaceting_params) + ' }', self._stitch_tolerance, self._cad_update_parameters) message += ''.join('\n' + str(key) + ' : ' + str(value) for key, value in self._custom_params.items()) return message @@ -1462,6 +1475,16 @@ def append(self) -> bool: def append(self, value: bool): self._append = value + @property + def ansys_release(self) -> str: + """Configures the Ansys release to be used for loading CAD data through non Native route. + """ + return self._ansys_release + + @ansys_release.setter + def ansys_release(self, value: str): + self._ansys_release = value + @property def cad_reader_route(self) -> CadReaderRoute: """Specify the available CAD reader routes. The available CAD reader routes are ProgramControlled, Native, WorkBench, SpaceClaim. diff --git a/src/ansys/meshing/prime/autogen/igastructs.py b/src/ansys/meshing/prime/autogen/igastructs.py index 1484c5b9c9..3e91d3f02b 100644 --- a/src/ansys/meshing/prime/autogen/igastructs.py +++ b/src/ansys/meshing/prime/autogen/igastructs.py @@ -63,7 +63,7 @@ def __init__( Examples -------- - >>> i_garesults = prime.IGAResults(model = model) + >>> iga_results = prime.IGAResults(model = model) """ if json_data: self.__initialize( @@ -200,7 +200,7 @@ def __init__( Examples -------- - >>> i_gaspline = prime.IGASpline(model = model) + >>> iga_spline = prime.IGASpline(model = model) """ if json_data: self.__initialize( @@ -283,6 +283,7 @@ def __initialize( spline_refinement_level: int, control_points: Iterable[float], spline_points: Iterable[float], + bad_spline_points_indices: Iterable[int], deviation_array: Iterable[float], invalid_jacobian_elements_count: int, average_mesh_size: float, @@ -292,6 +293,7 @@ def __initialize( self._spline_refinement_level = spline_refinement_level self._control_points = control_points if isinstance(control_points, np.ndarray) else np.array(control_points, dtype=np.double) if control_points is not None else None self._spline_points = spline_points if isinstance(spline_points, np.ndarray) else np.array(spline_points, dtype=np.double) if spline_points is not None else None + self._bad_spline_points_indices = bad_spline_points_indices if isinstance(bad_spline_points_indices, np.ndarray) else np.array(bad_spline_points_indices, dtype=np.int32) if bad_spline_points_indices is not None else None self._deviation_array = deviation_array if isinstance(deviation_array, np.ndarray) else np.array(deviation_array, dtype=np.double) if deviation_array is not None else None self._invalid_jacobian_elements_count = invalid_jacobian_elements_count self._average_mesh_size = average_mesh_size @@ -305,6 +307,7 @@ def __init__( spline_refinement_level: int = None, control_points: Iterable[float] = None, spline_points: Iterable[float] = None, + bad_spline_points_indices: Iterable[int] = None, deviation_array: Iterable[float] = None, invalid_jacobian_elements_count: int = None, average_mesh_size: float = None, @@ -319,20 +322,31 @@ def __init__( model: Model Model to create a IGAUSplineSurf object with default parameters. id: int, optional + Id of the unstructured spline surface. spline_refinement_level: int, optional + Refinement level for rendering of spline points. control_points: Iterable[float], optional + Coordinates of the control points of the spline. spline_points: Iterable[float], optional + Coordinates of the spline points. + bad_spline_points_indices: Iterable[int], optional + Node indices in the spline points list which has negative jacobian value. deviation_array: Iterable[float], optional + Deviation value from the spline point to the model geometry. invalid_jacobian_elements_count: int, optional + Count of elements with negative jacobian. average_mesh_size: float, optional + Reference length to compute deviation. elements_count: int, optional + Count of shell elements. shell_thickness: float, optional + Thickness of shell. json_data: dict, optional JSON dictionary to create a IGAUSplineSurf object with provided parameters. Examples -------- - >>> i_gauspline_surf = prime.IGAUSplineSurf(model = model) + >>> iga_uspline_surf = prime.IGAUSplineSurf(model = model) """ if json_data: self.__initialize( @@ -340,19 +354,21 @@ def __init__( json_data["splineRefinementLevel"] if "splineRefinementLevel" in json_data else None, json_data["controlPoints"] if "controlPoints" in json_data else None, json_data["splinePoints"] if "splinePoints" in json_data else None, + json_data["badSplinePointsIndices"] if "badSplinePointsIndices" in json_data else None, json_data["deviationArray"] if "deviationArray" in json_data else None, json_data["invalidJacobianElementsCount"] if "invalidJacobianElementsCount" in json_data else None, json_data["averageMeshSize"] if "averageMeshSize" in json_data else None, json_data["elementsCount"] if "elementsCount" in json_data else None, json_data["shellThickness"] if "shellThickness" in json_data else None) else: - all_field_specified = all(arg is not None for arg in [id, spline_refinement_level, control_points, spline_points, deviation_array, invalid_jacobian_elements_count, average_mesh_size, elements_count, shell_thickness]) + all_field_specified = all(arg is not None for arg in [id, spline_refinement_level, control_points, spline_points, bad_spline_points_indices, deviation_array, invalid_jacobian_elements_count, average_mesh_size, elements_count, shell_thickness]) if all_field_specified: self.__initialize( id, spline_refinement_level, control_points, spline_points, + bad_spline_points_indices, deviation_array, invalid_jacobian_elements_count, average_mesh_size, @@ -369,6 +385,7 @@ def __init__( spline_refinement_level if spline_refinement_level is not None else ( IGAUSplineSurf._default_params["spline_refinement_level"] if "spline_refinement_level" in IGAUSplineSurf._default_params else (json_data["splineRefinementLevel"] if "splineRefinementLevel" in json_data else None)), control_points if control_points is not None else ( IGAUSplineSurf._default_params["control_points"] if "control_points" in IGAUSplineSurf._default_params else (json_data["controlPoints"] if "controlPoints" in json_data else None)), spline_points if spline_points is not None else ( IGAUSplineSurf._default_params["spline_points"] if "spline_points" in IGAUSplineSurf._default_params else (json_data["splinePoints"] if "splinePoints" in json_data else None)), + bad_spline_points_indices if bad_spline_points_indices is not None else ( IGAUSplineSurf._default_params["bad_spline_points_indices"] if "bad_spline_points_indices" in IGAUSplineSurf._default_params else (json_data["badSplinePointsIndices"] if "badSplinePointsIndices" in json_data else None)), deviation_array if deviation_array is not None else ( IGAUSplineSurf._default_params["deviation_array"] if "deviation_array" in IGAUSplineSurf._default_params else (json_data["deviationArray"] if "deviationArray" in json_data else None)), invalid_jacobian_elements_count if invalid_jacobian_elements_count is not None else ( IGAUSplineSurf._default_params["invalid_jacobian_elements_count"] if "invalid_jacobian_elements_count" in IGAUSplineSurf._default_params else (json_data["invalidJacobianElementsCount"] if "invalidJacobianElementsCount" in json_data else None)), average_mesh_size if average_mesh_size is not None else ( IGAUSplineSurf._default_params["average_mesh_size"] if "average_mesh_size" in IGAUSplineSurf._default_params else (json_data["averageMeshSize"] if "averageMeshSize" in json_data else None)), @@ -387,6 +404,7 @@ def set_default( spline_refinement_level: int = None, control_points: Iterable[float] = None, spline_points: Iterable[float] = None, + bad_spline_points_indices: Iterable[int] = None, deviation_array: Iterable[float] = None, invalid_jacobian_elements_count: int = None, average_mesh_size: float = None, @@ -397,14 +415,25 @@ def set_default( Parameters ---------- id: int, optional + Id of the unstructured spline surface. spline_refinement_level: int, optional + Refinement level for rendering of spline points. control_points: Iterable[float], optional + Coordinates of the control points of the spline. spline_points: Iterable[float], optional + Coordinates of the spline points. + bad_spline_points_indices: Iterable[int], optional + Node indices in the spline points list which has negative jacobian value. deviation_array: Iterable[float], optional + Deviation value from the spline point to the model geometry. invalid_jacobian_elements_count: int, optional + Count of elements with negative jacobian. average_mesh_size: float, optional + Reference length to compute deviation. elements_count: int, optional + Count of shell elements. shell_thickness: float, optional + Thickness of shell. """ args = locals() [IGAUSplineSurf._default_params.update({ key: value }) for key, value in args.items() if value is not None] @@ -431,6 +460,8 @@ def _jsonify(self) -> Dict[str, Any]: json_data["controlPoints"] = self._control_points if self._spline_points is not None: json_data["splinePoints"] = self._spline_points + if self._bad_spline_points_indices is not None: + json_data["badSplinePointsIndices"] = self._bad_spline_points_indices if self._deviation_array is not None: json_data["deviationArray"] = self._deviation_array if self._invalid_jacobian_elements_count is not None: @@ -445,14 +476,13 @@ def _jsonify(self) -> Dict[str, Any]: return json_data def __str__(self) -> str: - message = "id : %s\nspline_refinement_level : %s\ncontrol_points : %s\nspline_points : %s\ndeviation_array : %s\ninvalid_jacobian_elements_count : %s\naverage_mesh_size : %s\nelements_count : %s\nshell_thickness : %s" % (self._id, self._spline_refinement_level, self._control_points, self._spline_points, self._deviation_array, self._invalid_jacobian_elements_count, self._average_mesh_size, self._elements_count, self._shell_thickness) + message = "id : %s\nspline_refinement_level : %s\ncontrol_points : %s\nspline_points : %s\nbad_spline_points_indices : %s\ndeviation_array : %s\ninvalid_jacobian_elements_count : %s\naverage_mesh_size : %s\nelements_count : %s\nshell_thickness : %s" % (self._id, self._spline_refinement_level, self._control_points, self._spline_points, self._bad_spline_points_indices, self._deviation_array, self._invalid_jacobian_elements_count, self._average_mesh_size, self._elements_count, self._shell_thickness) message += ''.join('\n' + str(key) + ' : ' + str(value) for key, value in self._custom_params.items()) return message @property def id(self) -> int: - """ - Id of the unstructured spline surface. + """Id of the unstructured spline surface. """ return self._id @@ -462,8 +492,7 @@ def id(self, value: int): @property def spline_refinement_level(self) -> int: - """ - Refinement level for rendering of spline points. + """Refinement level for rendering of spline points. """ return self._spline_refinement_level @@ -473,8 +502,7 @@ def spline_refinement_level(self, value: int): @property def control_points(self) -> Iterable[float]: - """ - Coordinates of the control points of the spline. + """Coordinates of the control points of the spline. """ return self._control_points @@ -484,8 +512,7 @@ def control_points(self, value: Iterable[float]): @property def spline_points(self) -> Iterable[float]: - """ - Coordinates of the spline points. + """Coordinates of the spline points. """ return self._spline_points @@ -494,9 +521,18 @@ def spline_points(self, value: Iterable[float]): self._spline_points = value @property - def deviation_array(self) -> Iterable[float]: + def bad_spline_points_indices(self) -> Iterable[int]: + """Node indices in the spline points list which has negative jacobian value. """ - Deviation value from the spline point to the model geometry. + return self._bad_spline_points_indices + + @bad_spline_points_indices.setter + def bad_spline_points_indices(self, value: Iterable[int]): + self._bad_spline_points_indices = value + + @property + def deviation_array(self) -> Iterable[float]: + """Deviation value from the spline point to the model geometry. """ return self._deviation_array @@ -506,8 +542,7 @@ def deviation_array(self, value: Iterable[float]): @property def invalid_jacobian_elements_count(self) -> int: - """ - Count of elements with negative jacobian. + """Count of elements with negative jacobian. """ return self._invalid_jacobian_elements_count @@ -517,8 +552,7 @@ def invalid_jacobian_elements_count(self, value: int): @property def average_mesh_size(self) -> float: - """ - Reference length to compute deviation. + """Reference length to compute deviation. """ return self._average_mesh_size @@ -528,8 +562,7 @@ def average_mesh_size(self, value: float): @property def elements_count(self) -> int: - """ - Count of shell elements. + """Count of shell elements. """ return self._elements_count @@ -539,8 +572,7 @@ def elements_count(self, value: int): @property def shell_thickness(self) -> float: - """ - Thickness of shell. + """Thickness of shell. """ return self._shell_thickness @@ -879,6 +911,268 @@ def control_point_selection_type(self) -> ControlPointSelection: def control_point_selection_type(self, value: ControlPointSelection): self._control_point_selection_type = value +class QuadToSplineParams(CoreObject): + """Parameters to control conversion quadrilateral to spline. + """ + _default_params = {} + + def __initialize( + self, + keep_feature: bool, + feature_mode: bool, + feature_angle: float, + corner_angle: float, + pillow: bool, + shell_thickness: float, + solid_shell: bool, + continuity: int): + self._keep_feature = keep_feature + self._feature_mode = feature_mode + self._feature_angle = feature_angle + self._corner_angle = corner_angle + self._pillow = pillow + self._shell_thickness = shell_thickness + self._solid_shell = solid_shell + self._continuity = continuity + + def __init__( + self, + model: CommunicationManager=None, + keep_feature: bool = None, + feature_mode: bool = None, + feature_angle: float = None, + corner_angle: float = None, + pillow: bool = None, + shell_thickness: float = None, + solid_shell: bool = None, + continuity: int = None, + json_data : dict = None, + **kwargs): + """Initializes the QuadToSplineParams. + + Parameters + ---------- + model: Model + Model to create a QuadToSplineParams object with default parameters. + keep_feature: bool, optional + Option to turn on or off feature capture. + feature_mode: bool, optional + Feature extract options. + feature_angle: float, optional + Angle to capture the feature. + corner_angle: float, optional + Corner angle of the feature. + pillow: bool, optional + Option to turn on or off pillow feature. + shell_thickness: float, optional + Thickness of shell. + solid_shell: bool, optional + Solid shell option. Set true to generate solid shell spline, and set false to generate surface spline. + continuity: int, optional + Continuity options. 0 creates C0 continuity spline. 1 creates C1 continuity spline. + json_data: dict, optional + JSON dictionary to create a QuadToSplineParams object with provided parameters. + + Examples + -------- + >>> quad_to_spline_params = prime.QuadToSplineParams(model = model) + """ + if json_data: + self.__initialize( + json_data["keepFeature"] if "keepFeature" in json_data else None, + json_data["featureMode"] if "featureMode" in json_data else None, + json_data["featureAngle"] if "featureAngle" in json_data else None, + json_data["cornerAngle"] if "cornerAngle" in json_data else None, + json_data["pillow"] if "pillow" in json_data else None, + json_data["shellThickness"] if "shellThickness" in json_data else None, + json_data["solidShell"] if "solidShell" in json_data else None, + json_data["continuity"] if "continuity" in json_data else None) + else: + all_field_specified = all(arg is not None for arg in [keep_feature, feature_mode, feature_angle, corner_angle, pillow, shell_thickness, solid_shell, continuity]) + if all_field_specified: + self.__initialize( + keep_feature, + feature_mode, + feature_angle, + corner_angle, + pillow, + shell_thickness, + solid_shell, + continuity) + else: + if model is None: + raise ValueError("Invalid assignment. Either pass model or specify all properties") + else: + param_json = model._communicator.initialize_params(model, "QuadToSplineParams") + json_data = param_json["QuadToSplineParams"] if "QuadToSplineParams" in param_json else {} + self.__initialize( + keep_feature if keep_feature is not None else ( QuadToSplineParams._default_params["keep_feature"] if "keep_feature" in QuadToSplineParams._default_params else (json_data["keepFeature"] if "keepFeature" in json_data else None)), + feature_mode if feature_mode is not None else ( QuadToSplineParams._default_params["feature_mode"] if "feature_mode" in QuadToSplineParams._default_params else (json_data["featureMode"] if "featureMode" in json_data else None)), + feature_angle if feature_angle is not None else ( QuadToSplineParams._default_params["feature_angle"] if "feature_angle" in QuadToSplineParams._default_params else (json_data["featureAngle"] if "featureAngle" in json_data else None)), + corner_angle if corner_angle is not None else ( QuadToSplineParams._default_params["corner_angle"] if "corner_angle" in QuadToSplineParams._default_params else (json_data["cornerAngle"] if "cornerAngle" in json_data else None)), + pillow if pillow is not None else ( QuadToSplineParams._default_params["pillow"] if "pillow" in QuadToSplineParams._default_params else (json_data["pillow"] if "pillow" in json_data else None)), + shell_thickness if shell_thickness is not None else ( QuadToSplineParams._default_params["shell_thickness"] if "shell_thickness" in QuadToSplineParams._default_params else (json_data["shellThickness"] if "shellThickness" in json_data else None)), + solid_shell if solid_shell is not None else ( QuadToSplineParams._default_params["solid_shell"] if "solid_shell" in QuadToSplineParams._default_params else (json_data["solidShell"] if "solidShell" in json_data else None)), + continuity if continuity is not None else ( QuadToSplineParams._default_params["continuity"] if "continuity" in QuadToSplineParams._default_params else (json_data["continuity"] if "continuity" in json_data else None))) + self._custom_params = kwargs + if model is not None: + [ model._logger.warning(f'Unsupported argument : {key}') for key in kwargs ] + [setattr(type(self), key, property(lambda self, key = key: self._custom_params[key] if key in self._custom_params else None, + lambda self, value, key = key : self._custom_params.update({ key: value }))) for key in kwargs] + self._freeze() + + @staticmethod + def set_default( + keep_feature: bool = None, + feature_mode: bool = None, + feature_angle: float = None, + corner_angle: float = None, + pillow: bool = None, + shell_thickness: float = None, + solid_shell: bool = None, + continuity: int = None): + """Set the default values of QuadToSplineParams. + + Parameters + ---------- + keep_feature: bool, optional + Option to turn on or off feature capture. + feature_mode: bool, optional + Feature extract options. + feature_angle: float, optional + Angle to capture the feature. + corner_angle: float, optional + Corner angle of the feature. + pillow: bool, optional + Option to turn on or off pillow feature. + shell_thickness: float, optional + Thickness of shell. + solid_shell: bool, optional + Solid shell option. Set true to generate solid shell spline, and set false to generate surface spline. + continuity: int, optional + Continuity options. 0 creates C0 continuity spline. 1 creates C1 continuity spline. + """ + args = locals() + [QuadToSplineParams._default_params.update({ key: value }) for key, value in args.items() if value is not None] + + @staticmethod + def print_default(): + """Print the default values of QuadToSplineParams. + + Examples + -------- + >>> QuadToSplineParams.print_default() + """ + message = "" + message += ''.join(str(key) + ' : ' + str(value) + '\n' for key, value in QuadToSplineParams._default_params.items()) + print(message) + + def _jsonify(self) -> Dict[str, Any]: + json_data = {} + if self._keep_feature is not None: + json_data["keepFeature"] = self._keep_feature + if self._feature_mode is not None: + json_data["featureMode"] = self._feature_mode + if self._feature_angle is not None: + json_data["featureAngle"] = self._feature_angle + if self._corner_angle is not None: + json_data["cornerAngle"] = self._corner_angle + if self._pillow is not None: + json_data["pillow"] = self._pillow + if self._shell_thickness is not None: + json_data["shellThickness"] = self._shell_thickness + if self._solid_shell is not None: + json_data["solidShell"] = self._solid_shell + if self._continuity is not None: + json_data["continuity"] = self._continuity + [ json_data.update({ utils.to_camel_case(key) : value }) for key, value in self._custom_params.items()] + return json_data + + def __str__(self) -> str: + message = "keep_feature : %s\nfeature_mode : %s\nfeature_angle : %s\ncorner_angle : %s\npillow : %s\nshell_thickness : %s\nsolid_shell : %s\ncontinuity : %s" % (self._keep_feature, self._feature_mode, self._feature_angle, self._corner_angle, self._pillow, self._shell_thickness, self._solid_shell, self._continuity) + message += ''.join('\n' + str(key) + ' : ' + str(value) for key, value in self._custom_params.items()) + return message + + @property + def keep_feature(self) -> bool: + """Option to turn on or off feature capture. + """ + return self._keep_feature + + @keep_feature.setter + def keep_feature(self, value: bool): + self._keep_feature = value + + @property + def feature_mode(self) -> bool: + """Feature extract options. + """ + return self._feature_mode + + @feature_mode.setter + def feature_mode(self, value: bool): + self._feature_mode = value + + @property + def feature_angle(self) -> float: + """Angle to capture the feature. + """ + return self._feature_angle + + @feature_angle.setter + def feature_angle(self, value: float): + self._feature_angle = value + + @property + def corner_angle(self) -> float: + """Corner angle of the feature. + """ + return self._corner_angle + + @corner_angle.setter + def corner_angle(self, value: float): + self._corner_angle = value + + @property + def pillow(self) -> bool: + """Option to turn on or off pillow feature. + """ + return self._pillow + + @pillow.setter + def pillow(self, value: bool): + self._pillow = value + + @property + def shell_thickness(self) -> float: + """Thickness of shell. + """ + return self._shell_thickness + + @shell_thickness.setter + def shell_thickness(self, value: float): + self._shell_thickness = value + + @property + def solid_shell(self) -> bool: + """Solid shell option. Set true to generate solid shell spline, and set false to generate surface spline. + """ + return self._solid_shell + + @solid_shell.setter + def solid_shell(self, value: bool): + self._solid_shell = value + + @property + def continuity(self) -> int: + """Continuity options. 0 creates C0 continuity spline. 1 creates C1 continuity spline. + """ + return self._continuity + + @continuity.setter + def continuity(self, value: int): + self._continuity = value + class RefineSplineParams(CoreObject): """Spline refinement parameters. """ diff --git a/src/ansys/meshing/prime/autogen/part.py b/src/ansys/meshing/prime/autogen/part.py index 527e1760b7..5024fc5b89 100644 --- a/src/ansys/meshing/prime/autogen/part.py +++ b/src/ansys/meshing/prime/autogen/part.py @@ -1440,7 +1440,7 @@ def get_splines(self) -> Iterable[int]: self._model._print_logs_after_command("get_splines") return result - def get_uspline_surface(self) -> IGAUSplineSurf: + def get_unstructured_spline_surface(self) -> IGAUSplineSurf: """ Gets the unstructured surface spline for the part. @@ -1453,14 +1453,14 @@ def get_uspline_surface(self) -> IGAUSplineSurf: Examples -------- >>> from ansys.meshing.prime import Part - >>> spline = part.GetUSplineSurface() + >>> spline = part.GetUnstructuredSplineSurface() """ args = {} - command_name = "PrimeMesh::Part/GetUSplineSurface" - self._model._print_logs_before_command("get_uspline_surface", args) + command_name = "PrimeMesh::Part/GetUnstructuredSplineSurface" + self._model._print_logs_before_command("get_unstructured_spline_surface", args) result = self._comm.serve(self._model, command_name, self._object_id, args=args) - self._model._print_logs_after_command("get_uspline_surface", IGAUSplineSurf(model = self._model, json_data = result)) + self._model._print_logs_after_command("get_unstructured_spline_surface", IGAUSplineSurf(model = self._model, json_data = result)) return IGAUSplineSurf(model = self._model, json_data = result) def get_summary(self, params : PartSummaryParams) -> PartSummaryResults: diff --git a/src/ansys/meshing/prime/autogen/primeconfig.py b/src/ansys/meshing/prime/autogen/primeconfig.py index f3f2bc8442..4febefa41f 100644 --- a/src/ansys/meshing/prime/autogen/primeconfig.py +++ b/src/ansys/meshing/prime/autogen/primeconfig.py @@ -578,6 +578,10 @@ class ErrorCode(enum.IntEnum): """Invalid volume scope provided for thin volume control.""" THINVOLUMECONTROLINVALIDCONTROL = 12110 """Same face scope is set as target for multiple thin volume controls.""" + THINVOLUMECONTROLSAMESOURCEFORMORETHANTWOCONTROL = 12111 + """Same face scope is set as source for more than two thin volume controls.""" + THINVOLUMEMESHNOTSUPPORTEDWITHFACEBASEDDATABASE = 12112 + """Thin volume mesh is not supported with face based database.""" MICROSTRUCTUREINVALIDELEMENTTYPE = 13000 """Invalid input provided. Invalid Element Type.""" diff --git a/src/ansys/meshing/prime/autogen/quadtospline.py b/src/ansys/meshing/prime/autogen/quadtospline.py new file mode 100644 index 0000000000..886f0a8f0c --- /dev/null +++ b/src/ansys/meshing/prime/autogen/quadtospline.py @@ -0,0 +1,79 @@ +""" Auto-generated file. DO NOT MODIFY """ +from __future__ import annotations +from ansys.meshing.prime.internals.comm_manager import CommunicationManager +from ansys.meshing.prime.params.primestructs import * +from ansys.meshing.prime.autogen.coreobject import * +from typing import List, Any, Union + +class QuadToSpline(CoreObject): + """Converts all-quad mesh to spline. + + """ + + def __init__(self, model: CommunicationManager): + """ Initialize QuadToSpline """ + self._model = model + self._comm = model._communicator + command_name = "PrimeMesh::QuadToSpline/Construct" + args = {"ModelID" : model._object_id , "MaxID" : -1 } + result = self._comm.serve(model, command_name, args=args) + self._object_id = result["ObjectIndex"] + self._freeze() + + def __enter__(self): + """ Enter context for QuadToSpline. """ + return self + + def __exit__(self, type, value, traceback) : + """ Exit context for QuadToSpline. """ + command_name = "PrimeMesh::QuadToSpline/Destruct" + self._comm.serve(self._model, command_name, self._object_id, args={}) + + def convert_quad_to_spline__beta(self, part_id : int, quad_mesh_face_zonelet_ids : Iterable[int], topo_face_ids : Iterable[int], topo_edge_ids : Iterable[int], quad_to_spline_params : QuadToSplineParams) -> IGAResults: + """ Converts fully quad mesh with topology to spline with the given conversion parameters. + + + Parameters + ---------- + part_id : int + Id of the Part. + quad_mesh_face_zonelet_ids : Iterable[int] + Ids of the face zonelets of quad mesh. + topo_face_ids : Iterable[int] + Ids of topofaces. + topo_edge_ids : Iterable[int] + Ids of topoedges. + quad_to_spline_params : QuadToSplineParams + Parameters to convert quad to spline. + + Returns + ------- + IGAResults + Returns the IGAResults structure. + + + Examples + -------- + >>> results = quadToSpline.ConvertQuadToSpline(part_id, quad_mesh_face_zonelet_ids, geometric_face_zonelet_ids, geometric_edge_zonelet_ids, quad_to_spline_params) + + """ + if not isinstance(part_id, int): + raise TypeError("Invalid argument type passed for part_id, valid argument type is int.") + if not isinstance(quad_mesh_face_zonelet_ids, Iterable): + raise TypeError("Invalid argument type passed for quad_mesh_face_zonelet_ids, valid argument type is Iterable[int].") + if not isinstance(topo_face_ids, Iterable): + raise TypeError("Invalid argument type passed for topo_face_ids, valid argument type is Iterable[int].") + if not isinstance(topo_edge_ids, Iterable): + raise TypeError("Invalid argument type passed for topo_edge_ids, valid argument type is Iterable[int].") + if not isinstance(quad_to_spline_params, QuadToSplineParams): + raise TypeError("Invalid argument type passed for quad_to_spline_params, valid argument type is QuadToSplineParams.") + args = {"part_id" : part_id, + "quad_mesh_face_zonelet_ids" : quad_mesh_face_zonelet_ids, + "topo_face_ids" : topo_face_ids, + "topo_edge_ids" : topo_edge_ids, + "quad_to_spline_params" : quad_to_spline_params._jsonify()} + command_name = "PrimeMesh::QuadToSpline/ConvertQuadToSpline_Beta" + self._model._print_logs_before_command("convert_quad_to_spline__beta", args) + result = self._comm.serve(self._model, command_name, self._object_id, args=args) + self._model._print_logs_after_command("convert_quad_to_spline__beta", IGAResults(model = self._model, json_data = result)) + return IGAResults(model = self._model, json_data = result) diff --git a/src/ansys/meshing/prime/autogen/surfaceutilitystructs.py b/src/ansys/meshing/prime/autogen/surfaceutilitystructs.py index 4e67835214..13dbb2cde2 100644 --- a/src/ansys/meshing/prime/autogen/surfaceutilitystructs.py +++ b/src/ansys/meshing/prime/autogen/surfaceutilitystructs.py @@ -293,7 +293,7 @@ def error_code(self, value: ErrorCode): self._error_code = value class CopyZoneletsParams(CoreObject): - """Parameters to copy zonelets. + """Parameters to copy zonelets. This is for internal use only. """ _default_params = {} diff --git a/src/ansys/meshing/prime/autogen/thinvolumecontrolstructs.py b/src/ansys/meshing/prime/autogen/thinvolumecontrolstructs.py index d803591234..554ac78eaf 100644 --- a/src/ansys/meshing/prime/autogen/thinvolumecontrolstructs.py +++ b/src/ansys/meshing/prime/autogen/thinvolumecontrolstructs.py @@ -9,19 +9,25 @@ from ansys.meshing.prime.params.primestructs import * class ThinVolumeMeshParams(CoreObject): - """Parameters to generate thin volume mesh. + """Parameters to generate thin volume mesh. This is for internal use only. """ _default_params = {} def __initialize( self, - n_layers: int): + n_layers: int, + no_side_imprint: bool, + n_ignore_rings: int): self._n_layers = n_layers - + self._no_side_imprint = no_side_imprint + self._n_ignore_rings = n_ignore_rings + def __init__( self, model: CommunicationManager=None, n_layers: int = None, + no_side_imprint: bool = None, + n_ignore_rings: int = None, json_data : dict = None, **kwargs): """Initializes the ThinVolumeMeshParams. @@ -32,6 +38,10 @@ def __init__( Model to create a ThinVolumeMeshParams object with default parameters. n_layers: int, optional Number of thin volume layers to be generated. + no_side_imprint: bool, optional + Checks whether to imprint quad faces on side zonelets. + n_ignore_rings: int, optional + Number of layers to ignore when no imprint on sides. json_data: dict, optional JSON dictionary to create a ThinVolumeMeshParams object with provided parameters. @@ -41,12 +51,16 @@ def __init__( """ if json_data: self.__initialize( - json_data["nLayers"] if "nLayers" in json_data else None) + json_data["nLayers"] if "nLayers" in json_data else None, + json_data["noSideImprint"] if "noSideImprint" in json_data else None, + json_data["nIgnoreRings"] if "nIgnoreRings" in json_data else None) else: - all_field_specified = all(arg is not None for arg in [n_layers]) + all_field_specified = all(arg is not None for arg in [n_layers, no_side_imprint, n_ignore_rings]) if all_field_specified: self.__initialize( - n_layers) + n_layers, + no_side_imprint, + n_ignore_rings) else: if model is None: raise ValueError("Invalid assignment. Either pass model or specify all properties") @@ -54,7 +68,9 @@ def __init__( param_json = model._communicator.initialize_params(model, "ThinVolumeMeshParams") json_data = param_json["ThinVolumeMeshParams"] if "ThinVolumeMeshParams" in param_json else {} self.__initialize( - n_layers if n_layers is not None else ( ThinVolumeMeshParams._default_params["n_layers"] if "n_layers" in ThinVolumeMeshParams._default_params else (json_data["nLayers"] if "nLayers" in json_data else None))) + n_layers if n_layers is not None else ( ThinVolumeMeshParams._default_params["n_layers"] if "n_layers" in ThinVolumeMeshParams._default_params else (json_data["nLayers"] if "nLayers" in json_data else None)), + no_side_imprint if no_side_imprint is not None else ( ThinVolumeMeshParams._default_params["no_side_imprint"] if "no_side_imprint" in ThinVolumeMeshParams._default_params else (json_data["noSideImprint"] if "noSideImprint" in json_data else None)), + n_ignore_rings if n_ignore_rings is not None else ( ThinVolumeMeshParams._default_params["n_ignore_rings"] if "n_ignore_rings" in ThinVolumeMeshParams._default_params else (json_data["nIgnoreRings"] if "nIgnoreRings" in json_data else None))) self._custom_params = kwargs if model is not None: [ model._logger.warning(f'Unsupported argument : {key}') for key in kwargs ] @@ -64,13 +80,19 @@ def __init__( @staticmethod def set_default( - n_layers: int = None): + n_layers: int = None, + no_side_imprint: bool = None, + n_ignore_rings: int = None): """Set the default values of ThinVolumeMeshParams. Parameters ---------- n_layers: int, optional Number of thin volume layers to be generated. + no_side_imprint: bool, optional + Checks whether to imprint quad faces on side zonelets. + n_ignore_rings: int, optional + Number of layers to ignore when no imprint on sides. """ args = locals() [ThinVolumeMeshParams._default_params.update({ key: value }) for key, value in args.items() if value is not None] @@ -91,11 +113,15 @@ def _jsonify(self) -> Dict[str, Any]: json_data = {} if self._n_layers is not None: json_data["nLayers"] = self._n_layers + if self._no_side_imprint is not None: + json_data["noSideImprint"] = self._no_side_imprint + if self._n_ignore_rings is not None: + json_data["nIgnoreRings"] = self._n_ignore_rings [ json_data.update({ utils.to_camel_case(key) : value }) for key, value in self._custom_params.items()] return json_data def __str__(self) -> str: - message = "n_layers : %s\n" % (self._n_layers) + message = "n_layers : %s\nno_side_imprint : %s\nn_ignore_rings : %s" % (self._n_layers, self._no_side_imprint, self._n_ignore_rings) message += ''.join('\n' + str(key) + ' : ' + str(value) for key, value in self._custom_params.items()) return message @@ -108,3 +134,23 @@ def n_layers(self) -> int: @n_layers.setter def n_layers(self, value: int): self._n_layers = value + + @property + def no_side_imprint(self) -> bool: + """Checks whether to imprint quad faces on side zonelets. + """ + return self._no_side_imprint + + @no_side_imprint.setter + def no_side_imprint(self, value: bool): + self._no_side_imprint = value + + @property + def n_ignore_rings(self) -> int: + """Number of layers to ignore when no imprint on sides. + """ + return self._n_ignore_rings + + @n_ignore_rings.setter + def n_ignore_rings(self, value: int): + self._n_ignore_rings = value diff --git a/src/ansys/meshing/prime/autogen/wrapperstructs.py b/src/ansys/meshing/prime/autogen/wrapperstructs.py index cf56693b3e..fbad11a58f 100644 --- a/src/ansys/meshing/prime/autogen/wrapperstructs.py +++ b/src/ansys/meshing/prime/autogen/wrapperstructs.py @@ -1009,12 +1009,14 @@ def __initialize( gap_size: float, material_point_name: str, suggested_part_name: str, - number_of_threads: int): + number_of_threads: int, + merge_to_geom: bool): self._target = target self._gap_size = gap_size self._material_point_name = material_point_name self._suggested_part_name = suggested_part_name self._number_of_threads = number_of_threads + self._merge_to_geom = merge_to_geom def __init__( self, @@ -1024,6 +1026,7 @@ def __init__( material_point_name: str = None, suggested_part_name: str = None, number_of_threads: int = None, + merge_to_geom: bool = None, json_data : dict = None, **kwargs): """Initializes the WrapperCloseGapsParams. @@ -1042,6 +1045,8 @@ def __init__( Suggested part name for created patching surfaces. number_of_threads: int, optional Number of threads for multithreading. + merge_to_geom: bool, optional + Merges the created gap closure elements to the nearest input geometry. json_data: dict, optional JSON dictionary to create a WrapperCloseGapsParams object with provided parameters. @@ -1055,16 +1060,18 @@ def __init__( json_data["gapSize"] if "gapSize" in json_data else None, json_data["materialPointName"] if "materialPointName" in json_data else None, json_data["suggestedPartName"] if "suggestedPartName" in json_data else None, - json_data["numberOfThreads"] if "numberOfThreads" in json_data else None) + json_data["numberOfThreads"] if "numberOfThreads" in json_data else None, + json_data["mergeToGeom"] if "mergeToGeom" in json_data else None) else: - all_field_specified = all(arg is not None for arg in [target, gap_size, material_point_name, suggested_part_name, number_of_threads]) + all_field_specified = all(arg is not None for arg in [target, gap_size, material_point_name, suggested_part_name, number_of_threads, merge_to_geom]) if all_field_specified: self.__initialize( target, gap_size, material_point_name, suggested_part_name, - number_of_threads) + number_of_threads, + merge_to_geom) else: if model is None: raise ValueError("Invalid assignment. Either pass model or specify all properties") @@ -1076,7 +1083,8 @@ def __init__( gap_size if gap_size is not None else ( WrapperCloseGapsParams._default_params["gap_size"] if "gap_size" in WrapperCloseGapsParams._default_params else (json_data["gapSize"] if "gapSize" in json_data else None)), material_point_name if material_point_name is not None else ( WrapperCloseGapsParams._default_params["material_point_name"] if "material_point_name" in WrapperCloseGapsParams._default_params else (json_data["materialPointName"] if "materialPointName" in json_data else None)), suggested_part_name if suggested_part_name is not None else ( WrapperCloseGapsParams._default_params["suggested_part_name"] if "suggested_part_name" in WrapperCloseGapsParams._default_params else (json_data["suggestedPartName"] if "suggestedPartName" in json_data else None)), - number_of_threads if number_of_threads is not None else ( WrapperCloseGapsParams._default_params["number_of_threads"] if "number_of_threads" in WrapperCloseGapsParams._default_params else (json_data["numberOfThreads"] if "numberOfThreads" in json_data else None))) + number_of_threads if number_of_threads is not None else ( WrapperCloseGapsParams._default_params["number_of_threads"] if "number_of_threads" in WrapperCloseGapsParams._default_params else (json_data["numberOfThreads"] if "numberOfThreads" in json_data else None)), + merge_to_geom if merge_to_geom is not None else ( WrapperCloseGapsParams._default_params["merge_to_geom"] if "merge_to_geom" in WrapperCloseGapsParams._default_params else (json_data["mergeToGeom"] if "mergeToGeom" in json_data else None))) self._custom_params = kwargs if model is not None: [ model._logger.warning(f'Unsupported argument : {key}') for key in kwargs ] @@ -1090,7 +1098,8 @@ def set_default( gap_size: float = None, material_point_name: str = None, suggested_part_name: str = None, - number_of_threads: int = None): + number_of_threads: int = None, + merge_to_geom: bool = None): """Set the default values of WrapperCloseGapsParams. Parameters @@ -1105,6 +1114,8 @@ def set_default( Suggested part name for created patching surfaces. number_of_threads: int, optional Number of threads for multithreading. + merge_to_geom: bool, optional + Merges the created gap closure elements to the nearest input geometry. """ args = locals() [WrapperCloseGapsParams._default_params.update({ key: value }) for key, value in args.items() if value is not None] @@ -1133,11 +1144,13 @@ def _jsonify(self) -> Dict[str, Any]: json_data["suggestedPartName"] = self._suggested_part_name if self._number_of_threads is not None: json_data["numberOfThreads"] = self._number_of_threads + if self._merge_to_geom is not None: + json_data["mergeToGeom"] = self._merge_to_geom [ json_data.update({ utils.to_camel_case(key) : value }) for key, value in self._custom_params.items()] return json_data def __str__(self) -> str: - message = "target : %s\ngap_size : %s\nmaterial_point_name : %s\nsuggested_part_name : %s\nnumber_of_threads : %s" % ('{ ' + str(self._target) + ' }', self._gap_size, self._material_point_name, self._suggested_part_name, self._number_of_threads) + message = "target : %s\ngap_size : %s\nmaterial_point_name : %s\nsuggested_part_name : %s\nnumber_of_threads : %s\nmerge_to_geom : %s" % ('{ ' + str(self._target) + ' }', self._gap_size, self._material_point_name, self._suggested_part_name, self._number_of_threads, self._merge_to_geom) message += ''.join('\n' + str(key) + ' : ' + str(value) for key, value in self._custom_params.items()) return message @@ -1191,6 +1204,16 @@ def number_of_threads(self) -> int: def number_of_threads(self, value: int): self._number_of_threads = value + @property + def merge_to_geom(self) -> bool: + """Merges the created gap closure elements to the nearest input geometry. + """ + return self._merge_to_geom + + @merge_to_geom.setter + def merge_to_geom(self, value: bool): + self._merge_to_geom = value + class WrapperCloseGapsResult(CoreObject): """Result structure associated with close gaps operation. """ diff --git a/src/ansys/meshing/prime/internals/defaults.py b/src/ansys/meshing/prime/internals/defaults.py index ac258f1be5..56970fc68d 100644 --- a/src/ansys/meshing/prime/internals/defaults.py +++ b/src/ansys/meshing/prime/internals/defaults.py @@ -18,16 +18,16 @@ import appdirs USER_DATA_PATH = os.getenv( - 'PYPRIMEMESH_USER_DATA', - appdirs.user_data_dir(appname='ansys_meshing_prime', appauthor='Ansys'), + 'PYPRIMEMESH_USER_DATA', appdirs.user_data_dir(appname='pyprimemesh', appauthor=False) ) except ModuleNotFoundError: # If appdirs is not installed, then try with tempfile. # NOTE: This only occurs for ADO ARM Test runs import tempfile + USER_NAME = os.getenv('USERNAME', os.getenv('USER', 'pyprimemesh')) USER_DATA_PATH = os.getenv( - 'PYPRIMEMESH_USER_DATA', os.path.join(tempfile.gettempdir(), 'ansys_meshing_prime') + 'PYPRIMEMESH_USER_DATA', os.path.join(tempfile.gettempdir(), USER_NAME) ) if not os.path.exists(USER_DATA_PATH): # pragma: no cover