diff --git a/RFEM/TypesForSurfaces/surfaceEccentricity.py b/RFEM/TypesForSurfaces/surfaceEccentricity.py index 2009703b..2a61c7ef 100644 --- a/RFEM/TypesForSurfaces/surfaceEccentricity.py +++ b/RFEM/TypesForSurfaces/surfaceEccentricity.py @@ -1,11 +1,36 @@ -from RFEM.initModel import Model, clearAtributes +from RFEM.initModel import Model, clearAtributes, ConvertToDlString +from RFEM.enums import SurfaceEccentricityAlignment +from enum import Enum + +class TransverseOffsetObject(Enum): + MEMBER, SURFACE = range(2) class SurfaceEccentricity(): def __init__(self, no: int = 1, + offset: float = 0.1, + assigned_to_surfaces: str = '1', + thickness_alignment = SurfaceEccentricityAlignment.ALIGN_MIDDLE, + transverse_offset_object = TransverseOffsetObject.SURFACE, + transverse_offset_object_no: int = 1, + transverse_offset_alignment = SurfaceEccentricityAlignment.ALIGN_MIDDLE, comment: str = '', params: dict = None, model = Model): + """ + Surfase Eccentricity + + Args: + no (int, optional): Number + offset (float, optional): Offset value + assigned_to_surfaces (str, optional): Eccentricity assignmet + thickness_alignment (enum, optional): Thickness alignment + transverse_offset_object (enum, optional): Transverse offset reference type (member, surface or None) + transverse_offset_object_no (int, optional): Transverse offset reference number + transverse_offset_alignment (enum, optional): Transverse offset aligment + comment (str, optional): Comments + params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary + """ # Client model | Surface Eccentricity clientObject = model.clientModel.factory.create('ns0:surface_eccentricity') @@ -16,6 +41,25 @@ def __init__(self, # Surface Eccentricity No. clientObject.no = no + # Offset + clientObject.offset = offset + + # Assigned to Surfaces + clientObject.assigned_to_surfaces = ConvertToDlString(assigned_to_surfaces) + + # Thickness Assigmnet + clientObject.thickness_alignment = thickness_alignment.name + + # Transverse Offset Object, Number, and Transverse Offset Alignment + if transverse_offset_object == TransverseOffsetObject.MEMBER: + clientObject.transverse_offset_reference_type = "TRANSVERSE_OFFSET_TYPE_FROM_MEMBER_SECTION" + clientObject.transverse_offset_reference_member = transverse_offset_object_no + clientObject.transverse_offset_alignment = transverse_offset_alignment.name + elif transverse_offset_object == TransverseOffsetObject.SURFACE: + clientObject.transverse_offset_reference_type = "TRANSVERSE_OFFSET_TYPE_FROM_SURFACE_THICKNESS" + clientObject.transverse_offset_reference_surface = transverse_offset_object_no + clientObject.transverse_offset_alignment = transverse_offset_alignment.name + # Comment clientObject.comment = comment diff --git a/RFEM/TypesForSurfaces/surfaceMeshRefinements.py b/RFEM/TypesForSurfaces/surfaceMeshRefinements.py index 4013bf90..516e95f0 100644 --- a/RFEM/TypesForSurfaces/surfaceMeshRefinements.py +++ b/RFEM/TypesForSurfaces/surfaceMeshRefinements.py @@ -1,11 +1,23 @@ -from RFEM.initModel import Model, clearAtributes +from RFEM.initModel import Model, clearAtributes, ConvertToDlString class SurfaceMeshRefinement(): def __init__(self, no: int = 1, + surfaces: str = "1", + target_length: float = 0.2, comment: str = '', params: dict = None, model = Model): + """ + Surface Mesh Refinement + + Args: + no (int, optional): _description_. Defaults to 1. + surfaces (str, optional): _description_. Defaults to "1". + target_length (float, optional): _description_. Defaults to 0.1. + comment (str, optional): _description_. Defaults to ''. + params (dict, optional): _description_. Defaults to None. + """ # Client model | Surface Mesh Refinement clientObject = model.clientModel.factory.create('ns0:surface_mesh_refinement') @@ -16,6 +28,12 @@ def __init__(self, # Surface Mesh Refinement No. clientObject.no = no + # Assigned to Surfaces + clientObject.surfaces = ConvertToDlString(surfaces) + + # Target FE Length + clientObject.target_length = target_length + # Comment clientObject.comment = comment diff --git a/RFEM/TypesForSurfaces/surfaceStiffnessModification.py b/RFEM/TypesForSurfaces/surfaceStiffnessModification.py index cf51c7e4..6e3d8cde 100644 --- a/RFEM/TypesForSurfaces/surfaceStiffnessModification.py +++ b/RFEM/TypesForSurfaces/surfaceStiffnessModification.py @@ -1,11 +1,30 @@ from RFEM.initModel import Model, clearAtributes +from RFEM.enums import SurfaceStiffnessModificationType class SurfaceStiffnessModification(): def __init__(self, no: int = 1, + type = SurfaceStiffnessModificationType.TYPE_TOTAL_STIFFNESS_FACTOR, + factors: list = None, comment: str = '', params: dict = None, model = Model): + """ + Surface Stiffeness Modification + + Args: + no (int, optional): Number + type (_type_, optional): Modification Type + factors (list, optional): Stiffeness Modification Factors + if SurfaceStiffnessModificationType.TYPE_TOTAL_STIFFNESS_FACTOR: + factor_of_total_stiffness + elif SurfaceStiffnessModificationType.TYPE_PARTIAL_STIFFNESSES_FACTORS: + factor_of_bending_stiffness, factor_of_shear_stiffness, factor_of_membrane_stiffness, factor_of_eccentric_effects, and factor_of_weight + elif SurfaceStiffnessModificationType.TYPE_STIFFNESS_MATRIX_ELEMENTS_FACTORS: + all 21 factors from kd11 to kd38 + comment (str, optional): Comments + params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary + """ # Client model | Surface Stifness Modification clientObject = model.clientModel.factory.create('ns0:surface_stiffness_modification') @@ -16,6 +35,66 @@ def __init__(self, # Surface Stifness Modification No. clientObject.no = no + # Modification Type + clientObject.type = type.name + + # Stiffeness factors + if type == SurfaceStiffnessModificationType.TYPE_TOTAL_STIFFNESS_FACTOR: + clientObject.factor_of_total_stiffness = factors[0] + elif type == SurfaceStiffnessModificationType.TYPE_PARTIAL_STIFFNESSES_FACTORS: + clientObject.factor_of_bending_stiffness = factors[0] + clientObject.factor_of_shear_stiffness = factors[1] + clientObject.factor_of_membrane_stiffness = factors[2] + clientObject.factor_of_eccentric_effects = factors[3] + clientObject.factor_of_weight = factors[4] + elif type == SurfaceStiffnessModificationType.TYPE_STIFFNESS_MATRIX_ELEMENTS_FACTORS: + if len(factors) == 1: + clientObject.kd11 = factors[0] + clientObject.kd12 = factors[0] + clientObject.kd13 = factors[0] + clientObject.kd22 = factors[0] + clientObject.kd23 = factors[0] + clientObject.kd33 = factors[0] + clientObject.kd44 = factors[0] + clientObject.kd45 = factors[0] + clientObject.kd55 = factors[0] + clientObject.kd66 = factors[0] + clientObject.kd67 = factors[0] + clientObject.kd68 = factors[0] + clientObject.kd77 = factors[0] + clientObject.kd78 = factors[0] + clientObject.kd88 = factors[0] + clientObject.kd16 = factors[0] + clientObject.kd17 = factors[0] + clientObject.kd18 = factors[0] + clientObject.kd27 = factors[0] + clientObject.kd28 = factors[0] + clientObject.kd38 = factors[0] + elif len(factors) == 21: + clientObject.kd11 = factors[0] + clientObject.kd12 = factors[1] + clientObject.kd13 = factors[2] + clientObject.kd22 = factors[3] + clientObject.kd23 = factors[4] + clientObject.kd33 = factors[5] + clientObject.kd44 = factors[6] + clientObject.kd45 = factors[7] + clientObject.kd55 = factors[8] + clientObject.kd66 = factors[9] + clientObject.kd67 = factors[10] + clientObject.kd68 = factors[11] + clientObject.kd77 = factors[12] + clientObject.kd78 = factors[13] + clientObject.kd88 = factors[14] + clientObject.kd16 = factors[15] + clientObject.kd17 = factors[16] + clientObject.kd18 = factors[17] + clientObject.kd27 = factors[18] + clientObject.kd28 = factors[19] + clientObject.kd38 = factors[20] + else: + raise IndexError('Size of "factors" can by either 1 or 21.') + # Comment clientObject.comment = comment diff --git a/RFEM/TypesForSurfaces/surfaceSupport.py b/RFEM/TypesForSurfaces/surfaceSupport.py index fff134f8..afcf9f8b 100644 --- a/RFEM/TypesForSurfaces/surfaceSupport.py +++ b/RFEM/TypesForSurfaces/surfaceSupport.py @@ -1,44 +1,59 @@ -from RFEM.initModel import Model, ConvertToDlString, clearAtributes - -class SurfaceSupport(): - def __init__(self, - no: int = 1, - surfaces_no: str = '1', - c_1_x: float = 0.0, - c_1_y: float = 0.0, - c_1_z: float = 0.0, - c_2_x: float = 0.0, - c_2_y: float = 0.0, - comment: str = '', - params: dict = None, - model = Model): - - # Client model | Surface Support - clientObject = model.clientModel.factory.create('ns0:surface_support') - - # Clears object atributes | Sets all atributes to None - clearAtributes(clientObject) - - # Surface Support No. - clientObject.no = no - - # Surface No. (e.g. "5 6 7 12") - clientObject.surfaces = ConvertToDlString(surfaces_no) - - # Surface Support Conditions - clientObject.translation_x = c_1_x - clientObject.translation_y = c_1_y - clientObject.translation_z = c_1_z - clientObject.shear_xz = c_2_x - clientObject.shear_yz = c_2_y - - # Comment - clientObject.comment = comment - - # Adding optional parameters via dictionary - if params: - for key in params: - clientObject[key] = params[key] - - # Add Surface Support to client model - model.clientModel.service.set_surface_support(clientObject) +from RFEM.initModel import Model, ConvertToDlString, clearAtributes +from RFEM.dataTypes import inf + +class SurfaceSupport(): + def __init__(self, + no: int = 1, + surfaces_no: str = '1', + c_ux: float = 10000.0, + c_uy: float = 0.0, + c_uz: float = inf, + c_vxz: float = inf, + c_vyz: float = inf, + comment: str = '', + params: dict = None, + model = Model): + """ + Surface Support + + Args: + no (int, optional): Number + surfaces_no (str, optional): Assignet du surfaces no + c_ux (float, optional): Translational Support in X direction + c_uy (float, optional): Translational Support in Y direction + c_uz (float, optional): Translational Support in Z direction + c_vxz (float, optional): Shear Support in XZ direction + c_vyz (float, optional): Shear Support in YZ direction + comment (str, optional): Comments + params (dict, optional): Any WS Parameter relevant to the object and its value in form of a dictionary + """ + + # Client model | Surface Support + clientObject = model.clientModel.factory.create('ns0:surface_support') + + # Clears object atributes | Sets all atributes to None + clearAtributes(clientObject) + + # Surface Support No. + clientObject.no = no + + # Surface No. (e.g. "5 6 7 12") + clientObject.surfaces = ConvertToDlString(surfaces_no) + + # Surface Support Conditions + clientObject.translation_x = c_ux + clientObject.translation_y = c_uy + clientObject.translation_z = c_uz + clientObject.shear_xz = c_vxz + clientObject.shear_yz = c_vyz + + # Comment + clientObject.comment = comment + + # Adding optional parameters via dictionary + if params: + for key in params: + clientObject[key] = params[key] + + # Add Surface Support to client model + model.clientModel.service.set_surface_support(clientObject) diff --git a/RFEM/enums.py b/RFEM/enums.py index 5a65ddd5..8db2420c 100644 --- a/RFEM/enums.py +++ b/RFEM/enums.py @@ -1742,6 +1742,7 @@ class SteelMemberRotationalRestraintRotationalStiffness(Enum): Steel Member Rotational Restraint Rotational Stiffness ''' ROTATIONAL_STIFFNESS_INFINITELY, ROTATIONAL_STIFFNESS_MANUALLY = range(2) + class SteelBoundaryConditionsSupportType(Enum): ''' Steel Boundary Conditions Support Type @@ -1750,7 +1751,6 @@ class SteelBoundaryConditionsSupportType(Enum): SUPPORT_TYPE_FIXED_IN_Y_AND_WARPING, SUPPORT_TYPE_INDIVIDUALLY, SUPPORT_TYPE_NONE, SUPPORT_TYPE_TORSION, SUPPORT_TYPE_TORSION_AND_WARPING = range( 9) - class SteelBoundaryConditionsEccentricityTypeZ(Enum): ''' Steel Boundary Conditions Eccentricity Type Z Type @@ -1758,6 +1758,17 @@ class SteelBoundaryConditionsEccentricityTypeZ(Enum): ECCENTRICITY_TYPE_AT_LOWER_FLANGE, ECCENTRICITY_TYPE_AT_UPPER_FLANGE, ECCENTRICITY_TYPE_NONE, ECCENTRICITY_TYPE_USER_VALUE = range( 4) +class SurfaceStiffnessModificationType(Enum): + ''' + Surface Stiffness Modification Type + ''' + TYPE_PARTIAL_STIFFNESSES_FACTORS, TYPE_STIFFNESS_MATRIX_ELEMENTS_FACTORS, TYPE_TOTAL_STIFFNESS_FACTOR = range(3) + +class SurfaceEccentricityAlignment(Enum): + ''' + Surface Eccentricity Alignment + ''' + ALIGN_TOP, ALIGN_MIDDLE, ALIGN_BOTTOM = range(3) class ActionCategoryType(Enum): ''' diff --git a/UnitTests/template.py b/UnitTests/template.py index 0e6dd9f7..b1a1d16b 100644 --- a/UnitTests/template.py +++ b/UnitTests/template.py @@ -63,6 +63,10 @@ def template(): #assert member.length == 5 #assert member.result_beam_z_minus == 4 + # Errors + # To test various errors like ValueError, just put 'with pytest.raises(ValueError):' + # before expression that should raise a ValueError. + # COMMENTS # Broken object or type can by commented out assuming author will add # associated bug number so everybody else can understand and track the issue. diff --git a/UnitTests/test_RigidLinks.py b/UnitTests/test_RigidLinks.py index a20afa80..cb20dc27 100644 --- a/UnitTests/test_RigidLinks.py +++ b/UnitTests/test_RigidLinks.py @@ -56,7 +56,7 @@ def test_rigid_links(): RigidLink(1, 3, 6) RigidLink.LineToLine(2, 3, 8) - # RigidLink.LineToSurface(0, 3, 3, 2) # bug 24282 + # RigidLink.LineToSurface(0, 3, 3, 2) # TODO: bug 24282 RigidLink.Diapragm(4,'3 4', '6 9') Model.clientModel.service.finish_modification() diff --git a/UnitTests/test_SurfaceLoad_test.py b/UnitTests/test_SurfaceLoad_test.py index 45f6ee54..3fe11eb7 100644 --- a/UnitTests/test_SurfaceLoad_test.py +++ b/UnitTests/test_SurfaceLoad_test.py @@ -9,12 +9,13 @@ from RFEM.LoadCasesAndCombinations.loadCase import LoadCase from RFEM.LoadCasesAndCombinations.staticAnalysisSettings import StaticAnalysisSettings from RFEM.TypesForNodes.nodalSupport import NodalSupport +from RFEM.TypesForSurfaces.surfaceSupport import SurfaceSupport from RFEM.BasicObjects.surface import Surface from RFEM.BasicObjects.line import Line from RFEM.BasicObjects.node import Node from RFEM.BasicObjects.thickness import Thickness from RFEM.BasicObjects.material import Material -from RFEM.initModel import Model, Calculate_all +from RFEM.initModel import Model from RFEM.enums import * if Model.clientModel is None: @@ -101,6 +102,8 @@ def test_surface_loads(): ## Mass Type Surface Load ## SurfaceLoad.Mass(14, 1, '1', individual_mass_components=True, mass_parameter=[500, 600, 700]) + SurfaceSupport(1,'1') + #Calculate_all() # Don't use in unit tests. See template for more info. Model.clientModel.service.finish_modification() diff --git a/UnitTests/test_TypesForSurfaces.py b/UnitTests/test_TypesForSurfaces.py new file mode 100644 index 00000000..f1ff0704 --- /dev/null +++ b/UnitTests/test_TypesForSurfaces.py @@ -0,0 +1,119 @@ +import sys +import os +PROJECT_ROOT = os.path.abspath(os.path.join( + os.path.dirname(__file__), + os.pardir) +) +sys.path.append(PROJECT_ROOT) + +import pytest +from RFEM.dataTypes import inf +from RFEM.BasicObjects.surface import Surface +from RFEM.BasicObjects.line import Line +from RFEM.BasicObjects.node import Node +from RFEM.BasicObjects.thickness import Thickness +from RFEM.BasicObjects.material import Material +from RFEM.initModel import Model +from RFEM.enums import SurfaceStiffnessModificationType +from RFEM.TypesForSurfaces.surfaceSupport import SurfaceSupport +from RFEM.TypesForSurfaces.surfaceEccentricity import SurfaceEccentricity, TransverseOffsetObject +from RFEM.TypesForSurfaces.surfaceStiffnessModification import SurfaceStiffnessModification +from RFEM.TypesForSurfaces.surfaceMeshRefinements import SurfaceMeshRefinement + + +if Model.clientModel is None: + Model() + +def test_types_for_surfaces(): + + Model.clientModel.service.delete_all() + Model.clientModel.service.begin_modification() + + # Create Material + Material(1, 'S235') + + # Create Thickness + Thickness(1, '1', 1, 0.01) + + # Create Nodes + Node(1, 0.0, 0.0, 0.0) + Node(2, 0.0, 2.0, 0.0) + Node(3, 2.0, 2.0, 0.0) + Node(4, 2.0, 0.0, 0.0) + Node(5, 0.0, 4.0, 0.0) + Node(6, 2.0, 4.0, 0.0) + + Node(7, 5, 0, 0) + Node(8, 7, 0, 0) + Node(9, 5, 0, 2) + Node(10, 7, 0, 2) + Node(11, 5, 0, -2) + Node(12, 7, 0, -2) + + # Create Lines + Line(1, '1 2') + Line(2, '2 3') + Line(3, '3 4') + Line(4, '4 1') + Line(5, '2 5') + Line(6, '5 6') + Line(7, '6 3') + + Line(8, '9 7') + Line(9, '7 8') + Line(10, '8 10') + Line(11, '10 9') + Line(12, '8 12') + Line(13, '12 11') + Line(14, '11 7') + + # Create Surfaces + Surface(1, '1 2 3 4', 1) + Surface(2, '2 5 6 7', 1) + + Surface(3, '8 9 10 11', 1) + Surface(4, '12 13 14 9', 1) + + # Surface Support + SurfaceSupport() + + # Surface Eccentricities + SurfaceEccentricity(1, 0.15, '') + + # Surface Stiffness Modification + SurfaceStiffnessModification(1, SurfaceStiffnessModificationType.TYPE_TOTAL_STIFFNESS_FACTOR, factors=[1.09]) + SurfaceStiffnessModification(2, SurfaceStiffnessModificationType.TYPE_PARTIAL_STIFFNESSES_FACTORS, factors=[1.01, 1.02, 1.03, 1.04, 1.05]) + SurfaceStiffnessModification(3, SurfaceStiffnessModificationType.TYPE_STIFFNESS_MATRIX_ELEMENTS_FACTORS, factors=[1.09]) + SurfaceStiffnessModification(4, SurfaceStiffnessModificationType.TYPE_STIFFNESS_MATRIX_ELEMENTS_FACTORS, factors=[1, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17, 1.18, 1.19, 1.20]) + with pytest.raises(IndexError): + SurfaceStiffnessModification(4, SurfaceStiffnessModificationType.TYPE_STIFFNESS_MATRIX_ELEMENTS_FACTORS, factors=[1, 1.01, 1.02, 1.03, 1.04, 1.05, 1.06, 1.07, 1.08, 1.09, 1.10, 1.11, 1.12, 1.13, 1.14, 1.15, 1.16, 1.17]) + + # Surface Mesh Refinements + SurfaceMeshRefinement() + + Model.clientModel.service.finish_modification() + + surfaceSupport = Model.clientModel.service.get_surface_support(1) + assert surfaceSupport.translation_x == 10000 + assert surfaceSupport.translation_z == inf + + surfaceEccentricity = Model.clientModel.service.get_surface_eccentricity(1) + assert surfaceEccentricity.transverse_offset_reference_type == 'TRANSVERSE_OFFSET_TYPE_FROM_SURFACE_THICKNESS' + assert surfaceEccentricity.transverse_offset_reference_surface == 1 + + surfaceStiffnessModification1 = Model.clientModel.service.get_surface_stiffness_modification(2) + assert surfaceStiffnessModification1.factor_of_shear_stiffness == 1.02 + assert surfaceStiffnessModification1.factor_of_weight == 1.05 + + surfaceStiffnessModification2 = Model.clientModel.service.get_surface_stiffness_modification(3) + assert surfaceStiffnessModification2.kd11 == 1.09 + assert surfaceStiffnessModification2.kd38 == 1.09 + + surfaceStiffnessModification3 = Model.clientModel.service.get_surface_stiffness_modification(4) + assert surfaceStiffnessModification3.kd11 == 1 + assert surfaceStiffnessModification3.kd38 == 1.2 + + surfaceMeshRefinement = Model.clientModel.service.get_surface_mesh_refinement(1) + assert surfaceMeshRefinement.surfaces == '1' + assert round(surfaceMeshRefinement.target_length, 2) == 0.2 + diff --git a/UnitTests/test_member.py b/UnitTests/test_member.py index 5d677fe3..c4ee899d 100644 --- a/UnitTests/test_member.py +++ b/UnitTests/test_member.py @@ -12,7 +12,6 @@ from RFEM.BasicObjects.section import Section from RFEM.BasicObjects.node import Node from RFEM.BasicObjects.member import Member -from RFEM.TypesForMembers.memberDefinableStiffness import MemberDefinableStiffness if Model.clientModel is None: Model() diff --git a/UnitTests/test_solids.py b/UnitTests/test_solids.py index 6314b28c..dc88d24a 100644 --- a/UnitTests/test_solids.py +++ b/UnitTests/test_solids.py @@ -177,31 +177,28 @@ def test_solids_and_solid_sets(): Material(4, 'Krypton') SolidGas(1,params={'pressure':21000000, 'temperature':293.1}) Solid.Gas(4, '18-23', 4,params={'gas':1}) + SolidSet(1,'2 3') + SolidSet.ContinuousSolids(2, '2 3') + SolidSet.GroupOfSolids(3, '1 4') Model.clientModel.service.finish_modification() solid = Model.clientModel.service.get_solid(4) assert round(solid.volume, 1) == 1000 assert solid.type == 'TYPE_GAS' + gas = Model.clientModel.service.get_solid_gas(1) assert round(gas.pressure, 1) == 21000000.0 # 210 bar assert round(gas.temperature, 1) == 293.1 # 20°C - # Testing Solid Sets - SolidSet(1,'2 3') - solidSet = Model.clientModel.service.get_solid_set(1) - solidSet.set_type == SetType.SET_TYPE_GROUP - solidSet.solids == '2 3' - - SolidSet.ContinuousSolids(2, '2 3') + assert solidSet.set_type == SetType.SET_TYPE_GROUP.name + assert solidSet.solids == '2 3' solidSet = Model.clientModel.service.get_solid_set(2) - solidSet.set_type == SetType.SET_TYPE_CONTINUOUS - solidSet.solids == '2 3' - - SolidSet.GroupOfSolids(3, '1 4') + assert solidSet.set_type == SetType.SET_TYPE_CONTINUOUS.name + assert solidSet.solids == '2 3' solidSet = Model.clientModel.service.get_solid_set(3) - solidSet.set_type == SetType.SET_TYPE_GROUP - solidSet.solids == '1 4' + assert solidSet.set_type == SetType.SET_TYPE_GROUP.name + assert solidSet.solids == '1 4'