Skip to content

Commit

Permalink
FEM: calculix writer, beam cross section angle, improvements and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
berndhahnebach committed Aug 4, 2021
1 parent d3b503b commit e197c3a
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 22 deletions.
18 changes: 9 additions & 9 deletions src/Mod/Fem/femmesh/meshsetsgetter.py
Expand Up @@ -729,7 +729,7 @@ def get_element_sets_material_and_femelement_geometry(self):
# "beamsection_obj" : "beamsection_obj" if exists
# "fluidsection_obj" : "fluidsection_obj" if exists
# "shellthickness_obj" : shellthickness_obj" if exists
# "beam_normal" : normal vector for beams only
# "beam_axis_m" : main local beam axis for beams only
# },
# {}, ... , {} ]

Expand All @@ -756,8 +756,8 @@ def get_mat_geo_sets_single_mat_single_beam(self):
matgeoset["mat_obj_name"] = mat_obj.Name
matgeoset["ccx_mat_name"] = mat_obj.Material["Name"]
matgeoset["beamsection_obj"] = beamsec_obj
# normal for this direction
matgeoset["beam_normal"] = beamdirection["normal"]
# beam_axis_m for this direction
matgeoset["beam_axis_m"] = beamdirection["beam_axis_m"]
self.mat_geo_sets.append(matgeoset)

def get_mat_geo_sets_single_mat_multiple_beam(self):
Expand All @@ -783,8 +783,8 @@ def get_mat_geo_sets_single_mat_multiple_beam(self):
matgeoset["mat_obj_name"] = mat_obj.Name
matgeoset["ccx_mat_name"] = mat_obj.Material["Name"]
matgeoset["beamsection_obj"] = beamsec_obj
# normal for this direction
matgeoset["beam_normal"] = beamdirection["normal"]
# beam_axis_m for this direction
matgeoset["beam_axis_m"] = beamdirection["beam_axis_m"]
self.mat_geo_sets.append(matgeoset)

def get_mat_geo_sets_multiple_mat_single_beam(self):
Expand All @@ -809,8 +809,8 @@ def get_mat_geo_sets_multiple_mat_single_beam(self):
matgeoset["mat_obj_name"] = mat_obj.Name
matgeoset["ccx_mat_name"] = mat_obj.Material["Name"]
matgeoset["beamsection_obj"] = beamsec_obj
# normal for this direction
matgeoset["beam_normal"] = beamdirection["normal"]
# beam_axis_m for this direction
matgeoset["beam_axis_m"] = beamdirection["beam_axis_m"]
self.mat_geo_sets.append(matgeoset)

def get_mat_geo_sets_multiple_mat_multiple_beam(self):
Expand Down Expand Up @@ -840,8 +840,8 @@ def get_mat_geo_sets_multiple_mat_multiple_beam(self):
matgeoset["mat_obj_name"] = mat_obj.Name
matgeoset["ccx_mat_name"] = mat_obj.Material["Name"]
matgeoset["beamsection_obj"] = beamsec_obj
# normal for this direction
matgeoset["beam_normal"] = beamdirection["normal"]
# beam_axis_m for this direction
matgeoset["beam_axis_m"] = beamdirection["beam_axis_m"]
self.mat_geo_sets.append(matgeoset)

# fluid
Expand Down
34 changes: 29 additions & 5 deletions src/Mod/Fem/femmesh/meshtools.py
Expand Up @@ -537,14 +537,14 @@ def get_femelement_direction1D_set(
theshape=None
):
"""
get for each geometry edge direction, the normal and the element ids and
get for each geometry edge direction, the local direction m and the element ids and
# write all into the beamrotation_objects
means no return value, we're going to write into the beamrotation_objects dictionary
FEMRotations1D is a list of dictionaries for every beamdirection of all edges
beamrot_obj["FEMRotations1D"] = [{
"ids" : [theids],
"direction" : direction,
"normal" : normal
"beam_axis_m" : beam_axis_m
}, ... ]
"""
if len(beamrotation_objects) == 0:
Expand All @@ -555,7 +555,7 @@ def get_femelement_direction1D_set(
# add normals for each direction
rotation_angle = 0
for rot in rotations_ids:
rot["normal"] = get_beam_normal(rot["direction"], rotation_angle)
rot["beam_axis_m"] = get_beam_main_axis_m(rot["direction"], rotation_angle)
# key "Object" will be empty
beamrotation_objects.append({"FEMRotations1D": rotations_ids, "ShortName": "Rstd"})
elif len(beamrotation_objects) == 1:
Expand All @@ -567,7 +567,7 @@ def get_femelement_direction1D_set(
# add normals for each direction
rotation_angle = beamrotation_objects[0]["Object"].Rotation
for rot in rotations_ids:
rot["normal"] = get_beam_normal(rot["direction"], rotation_angle)
rot["beam_axis_m"] = get_beam_main_axis_m(rot["direction"], rotation_angle)
beamrotation_objects[0]["FEMRotations1D"] = rotations_ids
beamrotation_objects[0]["ShortName"] = "R0"
elif len(beamrotation_objects) > 1:
Expand Down Expand Up @@ -611,7 +611,30 @@ def get_femelement_directions_theshape(femmesh, femelement_table, theshape):


# ************************************************************************************************
def get_beam_normal(beam_direction, defined_angle):
def get_beam_main_axis_m(beam_direction, defined_angle):

# former name was get_beam_normal
# see forum topic https://forum.freecadweb.org/viewtopic.php?f=18&t=24878
# beam_direction ... FreeCAD vector
# defined_angle ... degree
# base for the rotation:
# a beam_direction = (1, 0, 0) and angle = 0, returns (-0, 1, 0)
# https://forum.freecadweb.org/viewtopic.php?f=18&t=24878&start=30#p195567
# https://forum.freecadweb.org/viewtopic.php?f=13&t=59239&start=140#p521999
# changing the angle, changes the normal accordingly, 360 would again return (0,1,0)

# CalxuliX uses negative z axis as base, if nothing is given in input file
# see the standard direction of 1-direction in CalxuliX manual

# here the local main axis is called beam_axis_m the minor axis will be beam_axis_n

# eventually a better name might be get_beam_rotation

# FIXME: since we fix the base ange we would get this information out of the mesh edge too
print("beam_axis_m is retrieved from the geometry but we could get if from mesh edge too")
# print("beam_direction: {}".format(beam_direction))
# print("defined_angle: {}".format(defined_angle))

import math
vector_a = beam_direction
angle_rad = (math.pi / 180) * defined_angle
Expand Down Expand Up @@ -667,6 +690,7 @@ def get_beam_normal(beam_direction, defined_angle):
# dummy usage of the axis dot to get flake8 quiet
del dot_x, dot_y, dot_z, dot, dot_nt

# print("normal_n: {}".format(normal_n))
return normal_n


Expand Down
24 changes: 16 additions & 8 deletions src/Mod/Fem/femsolver/calculix/write_femelement_geometry.py
Expand Up @@ -39,17 +39,25 @@ def write_femelement_geometry(f, ccxwriter):

if "beamsection_obj"in matgeoset: # beam mesh
beamsec_obj = matgeoset["beamsection_obj"]
normal = matgeoset["beam_normal"]
beam_axis_m = matgeoset["beam_axis_m"]
# in CalxuliX called the 1direction
# see meshtools.get_beam_main_axis_m(beam_direction, defined_angle)
section_nor = "{:.13G}, {:.13G}, {:.13G}\n".format(
normal[0],
normal[1],
normal[2]
beam_axis_m[0],
beam_axis_m[1],
beam_axis_m[2]
)
print(section_nor)
if beamsec_obj.SectionType == "Rectangular":
height = beamsec_obj.RectHeight.getValueAs("mm").Value
width = beamsec_obj.RectWidth.getValueAs("mm").Value
# see meshtools.get_beam_main_axis_m(beam_direction, defined_angle)
# the method get_beam_main_axis_m() which calculates the beam_axis_m vector
# returns for a line in x direction and angle 0 degree
# the y-axis as local main direction (beam_axis_m vector)
# in users head and in beam section object this is the Width
len_beam_axis_m = beamsec_obj.RectWidth.getValueAs("mm").Value
len_beam_axis_n = beamsec_obj.RectHeight.getValueAs("mm").Value
section_type = ", SECTION=RECT"
section_geo = "{:.13G},{:.13G}\n".format(height, width)
section_geo = "{:.13G},{:.13G}\n".format(len_beam_axis_m, len_beam_axis_n)
section_def = "*BEAM SECTION, {}{}{}\n".format(
elsetdef,
material,
Expand Down Expand Up @@ -77,7 +85,7 @@ def write_femelement_geometry(f, ccxwriter):
f.write(section_def)
f.write(section_geo)
f.write(section_nor)
elif "fluidsection_obj"in matgeoset: # fluid mesh
elif "fluidsection_obj" in matgeoset: # fluid mesh
fluidsec_obj = matgeoset["fluidsection_obj"]
if fluidsec_obj.SectionType == "Liquid":
section_type = fluidsec_obj.LiquidSectionType
Expand Down

0 comments on commit e197c3a

Please sign in to comment.