Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEM CalculiX 2D mechanical analyses (plane stress, plane strain and axisymmetric) #12562

Merged
merged 7 commits into from Mar 2, 2024

Conversation

FEA-eng
Copy link
Contributor

@FEA-eng FEA-eng commented Feb 23, 2024

resolves #10864

This PR implements 2D mechanical analyses (plane stress, plane strain and axisymmetric) with CalculiX.

Usage:

  1. Prepare the model in the same way as for analysis with shells - surface geometry and thickness defined. The geometry has to lie on the XY plane (and on the right side of the Y axis for axisymmetric).
  2. Apply constraints to the edges of the model. Just don't use the fixed boundary condition since CalculiX doesn't support it in 2D at the moment (it may change in the next versions). Use the displacement boundary condition instead - X and Y translation and Z rotation are available for this type of analysis.
  3. Switch Model Space in CalculiX solver settings from the default 3D to plane stress, plane strain or axisymmetric and run the analysis.

@marioalexis84 and @chennes

@github-actions github-actions bot added the WB FEM Related to the FEM Workbench label Feb 23, 2024
Copy link
Member

@marioalexis84 marioalexis84 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested and works correctly.
Just some comments about duplicate code.
In my opinion, it would be enough to remove the duplicate code in write_femelement_geometry.py; The other functions can remain as they are, in any case, in the future I plan to extend the C++ writing function to avoid systematic editing of the already written file.

Comment on lines 2526 to 2579
f.truncate()
f.close()
def plane_stress(
fileName
):
# replace shell elements with plane stress elements
f = open(fileName, "r+")
lines = f.readlines()
f.seek(0)
for line in lines:
if line.find("S3") != -1:
line = line.replace("S3", "CPS3")
if line.find("S6") != -1:
line = line.replace("S6", "CPS6")
if line.find("S4") != -1:
line = line.replace("S4", "CPS4")
f.write(line)

f.truncate()
f.close()
def plane_strain(
fileName
):
# replace shell elements with plane strain elements
f = open(fileName, "r+")
lines = f.readlines()
f.seek(0)
for line in lines:
if line.find("S3") != -1:
line = line.replace("S3", "CPE3")
if line.find("S6") != -1:
line = line.replace("S6", "CPE6")
if line.find("S4") != -1:
line = line.replace("S4", "CPE4")
f.write(line)

f.truncate()
f.close()
def axisymmetric(
fileName
):
# replace shell elements with axisymmetric elements
f = open(fileName, "r+")
lines = f.readlines()
f.seek(0)
for line in lines:
if line.find("S3") != -1:
line = line.replace("S3", "CAX3")
if line.find("S6") != -1:
line = line.replace("S6", "CAX6")
if line.find("S4") != -1:
line = line.replace("S4", "CAX4")
f.write(line)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These functions plus beam_reduced_integration could be compacted into a single function that takes the appropriate parameters or use a base function that does the replacement and then called inside the others.

Comment on lines 111 to 124
if ccxwriter.solver_obj.ModelSpace == "3D":
shellth_obj = matgeoset["shellthickness_obj"]
section_def = "*SHELL SECTION, {}{}\n".format(elsetdef, material)
thickness = shellth_obj.Thickness.getValueAs("mm").Value
section_geo = "{:.13G}\n".format(thickness)
f.write(section_def)
f.write(section_geo)
else:
shellth_obj = matgeoset["shellthickness_obj"]
section_def = "*SOLID SECTION, {}{}\n".format(elsetdef, material)
thickness = shellth_obj.Thickness.getValueAs("mm").Value
section_geo = "{:.13G}\n".format(thickness)
f.write(section_def)
f.write(section_geo)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better not to repeat code in the if-else block. Move duplicate code out of conditional block.

Comment on lines +57 to +65

# Use 2D elements if model space is not set to 3D
if ccxwriter.solver_obj.ModelSpace == "plane stress":
meshtools.plane_stress(ccxwriter.femmesh_file)
if ccxwriter.solver_obj.ModelSpace == "plane strain":
meshtools.plane_strain(ccxwriter.femmesh_file)
if ccxwriter.solver_obj.ModelSpace == "axisymmetric":
meshtools.axisymmetric(ccxwriter.femmesh_file)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that by properly adapting the functions in meshtools.py, these conditionals could be replaced by a call to a single function.

Comment on lines +88 to +95
# Use 2D elements if model space is not set to 3D
if ccxwriter.solver_obj.ModelSpace == "plane stress":
meshtools.plane_stress(ccxwriter.femmesh_file)
if ccxwriter.solver_obj.ModelSpace == "plane strain":
meshtools.plane_strain(ccxwriter.femmesh_file)
if ccxwriter.solver_obj.ModelSpace == "axisymmetric":
meshtools.axisymmetric(ccxwriter.femmesh_file)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

@FEA-eng
Copy link
Contributor Author

FEA-eng commented Feb 23, 2024

In my opinion, it would be enough to remove the duplicate code in write_femelement_geometry.py; The other functions can remain as they are, in any case, in the future I plan to extend the C++ writing function to avoid systematic editing of the already written file.

Ok, done. Thank you for reviewing. So it can be merged ?

@FEA-eng
Copy link
Contributor Author

FEA-eng commented Feb 24, 2024

@chennes Can you merge it ?

@chennes chennes self-assigned this Feb 26, 2024
@FEA-eng
Copy link
Contributor Author

FEA-eng commented Feb 26, 2024

@chennes The required tests passed. Some other tests failed but apparently because of Part Design Helix:

Traceback (most recent call last):
  File "/Users/runner/work/FreeCAD/FreeCAD/.conda/freecad/opt/freecad/Mod/PartDesign/PartDesignTests/TestHelix.py", line 126, in testRectangle
    self.assertAlmostEqual(helix.Shape.Volume, 1178.0961742825648,places=5)
AssertionError: 1178.0962040829334 != 1178.0961742825648 within 5 places (2.980036856570223e-05 difference)

So it shouldn't be related to the PR.

FlachyJoe referenced this pull request Feb 26, 2024
use the wires of the computed face instead of the selected ones.
@chennes chennes merged commit 7eae061 into FreeCAD:main Mar 2, 2024
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
WB FEM Related to the FEM Workbench
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Support for 2D mechanical analyses can be easily added to the FEM workbench
3 participants