diff --git a/RFEM/TypesForNodes/nodalMeshRefinement.py b/RFEM/TypesForNodes/nodalMeshRefinement.py index 00105f5b..f5a5d2ad 100644 --- a/RFEM/TypesForNodes/nodalMeshRefinement.py +++ b/RFEM/TypesForNodes/nodalMeshRefinement.py @@ -1,11 +1,98 @@ from RFEM.initModel import Model, clearAtributes +from RFEM.enums import NodalMeshRefinementType +from enum import Enum + +class FElengthArrangement(Enum): + LENGTH_ARRANGEMENT_RADIAL, LENGTH_ARRANGEMENT_GRADUALLY, LENGTH_ARRANGEMENT_COMBINED = range(3) class NodalMeshRefinement(): def __init__(self, no: int = 1, + type = NodalMeshRefinementType.TYPE_CIRCULAR, + mesh_parameters: list = None, + apply_on_selected_surfaces: bool = False, + comment: str = '', + params: dict = None, + model = Model): + """ + Nodal Mesh Refinement + + Args: + no (int, optional): Number + type (_type_, optional): TYPE_CIRCULAR or TYPE_RECTANGULAR + mesh_parameters (list, optional): _description_. Defaults to None. + if TYPE_CIRCULAR: + (circular_radius, circular_target_inner_length, circular_target_outer_length, circular_length_arrangement) + (2.5, 0.1, 0.5, FElengthArrangement.LENGTH_ARRANGEMENT_RADIAL) + elif TYPE_RECTANGULAR: + (rectangular_side, rectangular_target_inner_length) + (0.5, 0.1) + comment (str, optional): Comment + params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary + model (_type_, optional): Model instance + """ + + # Client model | Nodal Mesh Refinement + clientObject = model.clientModel.factory.create('ns0:nodal_mesh_refinement') + + # Clears object atributes | Sets all atributes to None + clearAtributes(clientObject) + + # Nodal Mesh Refinement No. + clientObject.no = no + + # Nodal Mesh Refinement Type + clientObject.type = type.name + + # Mesh Parameters + if type == NodalMeshRefinementType.TYPE_CIRCULAR: + clientObject.circular_radius = mesh_parameters[0] + clientObject.circular_target_inner_length = mesh_parameters[1] + clientObject.circular_target_outer_length = mesh_parameters[2] + clientObject.circular_length_arrangement = mesh_parameters[3].name + elif type == NodalMeshRefinementType.TYPE_RECTANGULAR: + clientObject.rectangular_side = mesh_parameters[0] + clientObject.rectangular_target_inner_length = mesh_parameters[1] + + # Apply Only on Selected Surfaces + clientObject.apply_only_on_selected_surfaces = apply_on_selected_surfaces + + # Comment + clientObject.comment = comment + + # Adding optional parameters via dictionary + if params: + for key in params: + clientObject[key] = params[key] + + # Add Nodal Mesh Refinement to client model + model.clientModel.service.set_nodal_mesh_refinement(clientObject) + + @staticmethod + def Circular( + no: int = 1, + circular_radius: float = 2.5, + circular_target_inner_length: float = 0.1, + circular_target_outer_length: float = 0.5, + circular_length_arrangement = FElengthArrangement.LENGTH_ARRANGEMENT_RADIAL, + apply_on_selected_surfaces: bool = False, comment: str = '', params: dict = None, model = Model): + """ + Circular Nodal Mesh Refinement + + Args: + no (int, optional): Number + circular_radius (float, optional): Radius + circular_target_inner_length (float, optional): Inner target FE length + circular_target_outer_length (float, optional): Outer target FE length + circular_length_arrangement (_type_, optional): FE length arrangenemt + apply_on_selected_surfaces (bool, optional): Apply only on surfaces + comment (str, optional): Comment + params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary + model (_type_, optional): Model instance + """ # Client model | Nodal Mesh Refinement clientObject = model.clientModel.factory.create('ns0:nodal_mesh_refinement') @@ -16,6 +103,70 @@ def __init__(self, # Nodal Mesh Refinement No. clientObject.no = no + # Nodal Mesh Refinement Type + clientObject.type = NodalMeshRefinementType.TYPE_CIRCULAR.name + + # Mesh Parameters + clientObject.circular_radius = circular_radius + clientObject.circular_target_inner_length = circular_target_inner_length + clientObject.circular_target_outer_length = circular_target_outer_length + clientObject.circular_length_arrangement = circular_length_arrangement.name + + # Apply Only on Selected Surfaces + clientObject.apply_only_on_selected_surfaces = apply_on_selected_surfaces + + # Comment + clientObject.comment = comment + + # Adding optional parameters via dictionary + if params: + for key in params: + clientObject[key] = params[key] + + # Add Nodal Mesh Refinement to client model + model.clientModel.service.set_nodal_mesh_refinement(clientObject) + + @staticmethod + def Rectangular( + no: int = 1, + rectangular_side: float = 2.5, + rectangular_target_inner_length: float = 0.1, + apply_on_selected_surfaces: bool = False, + comment: str = '', + params: dict = None, + model = Model): + """ + Rectangular Nodal Mesh Refinement + + Args: + no (int, optional): Number + rectangular_side (float, optional): Side length + rectangular_target_inner_length (float, optional): Inner target FE length + apply_on_selected_surfaces (bool, optional): Apply only on surfaces + comment (str, optional): Comment + params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary + model (_type_, optional): Model instance + """ + + # Client model | Nodal Mesh Refinement + clientObject = model.clientModel.factory.create('ns0:nodal_mesh_refinement') + + # Clears object atributes | Sets all atributes to None + clearAtributes(clientObject) + + # Nodal Mesh Refinement No. + clientObject.no = no + + # Nodal Mesh Refinement Type + clientObject.type = NodalMeshRefinementType.TYPE_RECTANGULAR.name + + # Mesh Parameters + clientObject.rectangular_side = rectangular_side + clientObject.rectangular_target_inner_length = rectangular_target_inner_length + + # Apply Only on Selected Surfaces + clientObject.apply_only_on_selected_surfaces = apply_on_selected_surfaces + # Comment clientObject.comment = comment diff --git a/RFEM/TypesForNodes/nodalSupport.py b/RFEM/TypesForNodes/nodalSupport.py index e3cb1082..827de569 100644 --- a/RFEM/TypesForNodes/nodalSupport.py +++ b/RFEM/TypesForNodes/nodalSupport.py @@ -1,94 +1,113 @@ -from RFEM.initModel import Model, clearAtributes, ConvertToDlString -from RFEM.dataTypes import inf -from RFEM.enums import NodalSupportType - -def setNodalSupportConditions(clientObject, - C_u_X: float, - C_u_Y: float, - C_u_Z: float, - C_phi_X: float, - C_phi_Y: float, - C_phi_Z: float): - ''' - Sets nodal support conditions - - Params: - clientObject: Client model object | Nodal support - C_u_X,Y,Z: Translational support conditions in respected direction - C_phi_X,Y,Z: Rotational support conditions about respected axis - comment: Comment - - Returns: - clientObject: Initialized client model object | Nodal Support - ''' - - clientObject.spring_x = C_u_X - clientObject.spring_y = C_u_Y - clientObject.spring_z = C_u_Z - - clientObject.rotational_restraint_x = C_phi_X - clientObject.rotational_restraint_y = C_phi_Y - clientObject.rotational_restraint_z = C_phi_Z - - return clientObject - -class NodalSupport(): - def __init__(self, - no: int = 1, - nodes_no: str = '1 2', - support_type = NodalSupportType.HINGED, - comment: str = '', - params: dict = None, - model = Model): - - # Client model | Nodal Support - clientObject = model.clientModel.factory.create('ns0:nodal_support') - - # Clears object atributes | Sets all atributes to None - clearAtributes(clientObject) - - # Nodal Support No. - clientObject.no = no - - # Nodes No. (e.g. "5 6 7 12") - clientObject.nodes = ConvertToDlString(nodes_no) - - # Nodal Support Conditions - if support_type == NodalSupportType.FIXED: - # FIXED 'xxx xxx' - clientObject = setNodalSupportConditions(clientObject, inf, inf, inf, inf, inf, inf) - - elif support_type == NodalSupportType.HINGED: - # HINGED 'xxx --x' - clientObject = setNodalSupportConditions(clientObject, inf, inf, inf, 0.0, 0.0, inf) - - elif support_type == NodalSupportType.ROLLER: - # ROLLER '--x --x' - clientObject = setNodalSupportConditions(clientObject, 0.0, 0.0, inf, 0.0, 0.0, inf) - - elif support_type == NodalSupportType.ROLLER_IN_X: - # ROLLER_IN_X '-xx --x' - clientObject = setNodalSupportConditions(clientObject, 0.0, inf, inf, 0.0, 0.0, inf) - - elif support_type == NodalSupportType.ROLLER_IN_Y: - # ROLLER_IN_Y 'x-x --x' - clientObject = setNodalSupportConditions(clientObject, inf, 0.0, inf, 0.0, 0.0, inf) - - elif support_type == NodalSupportType.ROLLER_IN_Z: - # ROLLER_IN_Z 'xx- --x' - clientObject = setNodalSupportConditions(clientObject, inf, inf, 0.0, 0.0, 0.0, inf) - - elif support_type == NodalSupportType.FREE: - # FREE '--- ---' - clientObject = setNodalSupportConditions(clientObject, 0, 0, 0, 0, 0, 0) - - # Comment - clientObject.comment = comment - - # Adding optional parameters via dictionary - if params: - for key in params: - clientObject[key] = params[key] - - # Add Nodal Support to client model - model.clientModel.service.set_nodal_support(clientObject) +from RFEM.initModel import Model, clearAtributes, ConvertToDlString +from RFEM.dataTypes import inf +from RFEM.enums import NodalSupportType + +def setNodalSupportConditions(clientObject, + C_u_X: float, + C_u_Y: float, + C_u_Z: float, + C_phi_X: float, + C_phi_Y: float, + C_phi_Z: float): + ''' + Sets nodal support conditions + + Params: + clientObject: Client model object | Nodal support + C_u_X,Y,Z: Translational support conditions in respected direction + C_phi_X,Y,Z: Rotational support conditions about respected axis + + Returns: + clientObject: Initialized client model object | Nodal Support + ''' + + clientObject.spring_x = C_u_X + clientObject.spring_y = C_u_Y + clientObject.spring_z = C_u_Z + + clientObject.rotational_restraint_x = C_phi_X + clientObject.rotational_restraint_y = C_phi_Y + clientObject.rotational_restraint_z = C_phi_Z + + return clientObject + +class NodalSupport(): + def __init__(self, + no: int = 1, + nodes_no: str = '1 2', + support = NodalSupportType.HINGED, + comment: str = '', + params: dict = None, + model = Model): + """ + Nodal Support + + Args: + no (int, optional): Number + nodes_no (str, optional): Assigned to nodes + support (enum or list, optional): Support definition + comment (str, optional): Commment + params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary + model (_type_, optional): Model instance + + Raises: + ValueError: 'Support parameter can be enum or list with 6 items.' + """ + + # Client model | Nodal Support + clientObject = model.clientModel.factory.create('ns0:nodal_support') + + # Clears object atributes | Sets all atributes to None + clearAtributes(clientObject) + + # Nodal Support No. + clientObject.no = no + + # Nodes No. (e.g. "5 6 7 12") + clientObject.nodes = ConvertToDlString(nodes_no) + + # Nodal Support Conditions + if support == NodalSupportType.FIXED: + # FIXED 'xxx xxx' + clientObject = setNodalSupportConditions(clientObject, inf, inf, inf, inf, inf, inf) + + elif support == NodalSupportType.HINGED: + # HINGED 'xxx --x' + clientObject = setNodalSupportConditions(clientObject, inf, inf, inf, 0.0, 0.0, inf) + + elif support == NodalSupportType.ROLLER: + # ROLLER '--x --x' + clientObject = setNodalSupportConditions(clientObject, 0.0, 0.0, inf, 0.0, 0.0, inf) + + elif support == NodalSupportType.ROLLER_IN_X: + # ROLLER_IN_X '-xx --x' + clientObject = setNodalSupportConditions(clientObject, 0.0, inf, inf, 0.0, 0.0, inf) + + elif support == NodalSupportType.ROLLER_IN_Y: + # ROLLER_IN_Y 'x-x --x' + clientObject = setNodalSupportConditions(clientObject, inf, 0.0, inf, 0.0, 0.0, inf) + + elif support == NodalSupportType.ROLLER_IN_Z: + # ROLLER_IN_Z 'xx- --x' + clientObject = setNodalSupportConditions(clientObject, inf, inf, 0.0, 0.0, 0.0, inf) + + elif support == NodalSupportType.FREE: + # FREE '--- ---' + clientObject = setNodalSupportConditions(clientObject, 0, 0, 0, 0, 0, 0) + + elif isinstance(support, list) and len(support) == 6: + clientObject = setNodalSupportConditions(clientObject, support[0], support[1], support[2], support[3], support[4], support[5]) + + else: + raise ValueError('Support parameter can be enum or list with 6 items.') + + # Comment + clientObject.comment = comment + + # Adding optional parameters via dictionary + if params: + for key in params: + clientObject[key] = params[key] + + # Add Nodal Support to client model + model.clientModel.service.set_nodal_support(clientObject) diff --git a/RFEM/enums.py b/RFEM/enums.py index a71d3120..e443c64c 100644 --- a/RFEM/enums.py +++ b/RFEM/enums.py @@ -1784,6 +1784,12 @@ class SolidContactParallelType(Enum): FAILURE_IF_CONTACT_PERPENDICULAR_TO_SURFACES_FAILED, FULL_FORCE_TRANSMISSION, RIGID_FRICTION, RIGID_FRICTION_LIMIT, \ ELASTIC_FRICTION, ELASTIC_FRICTION_LIMIT, ELASTIC_SOLID = range(7) +class NodalMeshRefinementType(Enum): + ''' + Nodal Mesh Refinement + ''' + TYPE_CIRCULAR, TYPE_RECTANGULAR = range(2) + class ActionCategoryType(Enum): ''' Load Case Action Category diff --git a/UnitTests/test_TypesForNodes.py b/UnitTests/test_TypesForNodes.py new file mode 100644 index 00000000..a97bec81 --- /dev/null +++ b/UnitTests/test_TypesForNodes.py @@ -0,0 +1,82 @@ +import os +import sys +PROJECT_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), + os.pardir) +) +sys.path.append(PROJECT_ROOT) + +import pytest +from RFEM.enums import NodalMeshRefinementType, NodalSupportType +from RFEM.initModel import Model +from RFEM.BasicObjects.material import Material +from RFEM.BasicObjects.node import Node +from RFEM.BasicObjects.line import Line +from RFEM.BasicObjects.surface import Surface +from RFEM.BasicObjects.thickness import Thickness +from RFEM.TypesForNodes.nodalSupport import NodalSupport +from RFEM.TypesForNodes.nodalMeshRefinement import NodalMeshRefinement, FElengthArrangement +from RFEM.TypesForNodes.nodalSupport import NodalSupport +from RFEM.dataTypes import inf + + +if Model.clientModel is None: + Model() + +def test_typesForNodes(): + + Model.clientModel.service.delete_all() + Model.clientModel.service.begin_modification() + + Material(1, 'S235') + Thickness(1, 'Thick', 1, 0.35) + + Node(1, 0, 0, 0) + Node(2, 5, 0, 0) + Node(3, 5, 5, 0) + Node(4, 0, 5, 0) + Node(5,2.5,2.5,-2.5) + + NodalSupport(1, '1 2', [inf, inf, inf, 0.0, 0.0, inf]) + NodalSupport(2, '3', NodalSupportType.FIXED) + NodalSupport(3, '4', NodalSupportType.ROLLER_IN_X) + with pytest.raises(ValueError): + NodalSupport(4, '5', [inf, inf, inf, 0.0]) + + NodalMeshRefinement(1, NodalMeshRefinementType.TYPE_CIRCULAR, [2.2, 0.1, 0.5, FElengthArrangement.LENGTH_ARRANGEMENT_RADIAL]) + NodalMeshRefinement.Circular(2, 3) + NodalMeshRefinement.Rectangular(3, 2.7) + Model.clientModel.service.finish_modification() + + nodalSupport = Model.clientModel.service.get_nodal_support(1) + assert nodalSupport.spring_x == inf + assert nodalSupport.spring_y == inf + assert nodalSupport.spring_z == inf + assert nodalSupport.rotational_restraint_x == 0 + assert nodalSupport.rotational_restraint_y == 0 + assert nodalSupport.rotational_restraint_z == inf + + nodalSupport = Model.clientModel.service.get_nodal_support(2) + assert nodalSupport.spring_x == inf + assert nodalSupport.spring_y == inf + assert nodalSupport.spring_z == inf + assert nodalSupport.rotational_restraint_x == inf + assert nodalSupport.rotational_restraint_y == inf + assert nodalSupport.rotational_restraint_z == inf + + nodalSupport = Model.clientModel.service.get_nodal_support(3) + assert nodalSupport.spring_x == 0 + assert nodalSupport.spring_y == inf + assert nodalSupport.spring_z == inf + assert nodalSupport.rotational_restraint_x == 0 + assert nodalSupport.rotational_restraint_y == 0 + assert nodalSupport.rotational_restraint_z == inf + + nodalMeshRefinement = Model.clientModel.service.get_nodal_mesh_refinement(1) + assert nodalMeshRefinement.circular_radius == 2.2 + + nodalMeshRefinement = Model.clientModel.service.get_nodal_mesh_refinement(2) + assert nodalMeshRefinement.circular_radius == 3 + + nodalMeshRefinement = Model.clientModel.service.get_nodal_mesh_refinement(3) + assert nodalMeshRefinement.rectangular_side == 2.7