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

Fixing face inconsistencies in LinearHex element #199

Merged
merged 2 commits into from
Apr 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/elements/basis/TACSHexaBasis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ static void getFaceTangents(int face, double t[]) {
t[1] = 0.0;
t[2] = 0.0;
t[3] = 0.0;
t[4] = 0.0;
t[5] = 1.0;
t[4] = 1.0;
t[5] = 0.0;
}
}

Expand Down
4 changes: 2 additions & 2 deletions tacs/problems/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1006,11 +1006,11 @@ def _addPressureFromPLOAD4(self, auxElems, loadInfo, scale=1.0):
Add pressure to tacs static/transient problem from pynastran PLOAD4 card.
Should only be called by createTACSProbsFromBDF and not directly by user.
"""
# Dictionary mapping nastran element face indices to TACS equivilent numbering
# Dictionary mapping nastran element face indices to TACS equivalent numbering
nastranToTACSFaceIDDict = {
"CTETRA4": {1: 1, 2: 3, 3: 2, 4: 0},
"CTETRA": {2: 1, 4: 3, 3: 2, 1: 0},
"CHEXA": {1: 4, 2: 2, 3: 0, 4: 3, 5: 0, 6: 5},
"CHEXA": {1: 4, 2: 2, 3: 1, 4: 3, 5: 0, 6: 5},
}

# We don't support pressure variation across elements, for now just average it
Expand Down
101 changes: 101 additions & 0 deletions tests/integration_tests/input_files/two_hexs.bdf
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
INIT MASTER(S)
NASTRAN SYSTEM(442)=-1,SYSTEM(319)=1
ID FEMAP,FEMAP
SOL SESTATIC
CEND
TITLE = Simcenter Nastran Static Analysis Set
ECHO = NONE
DISPLACEMENT(PLOT) = ALL
SPCFORCE(PLOT) = ALL
OLOAD(PLOT) = ALL
FORCE(PLOT,CORNER) = ALL
STRESS(PLOT,CORNER) = ALL
SUBCASE 1
SUBTITLE = Clamp_+X
SPC = 1
LOAD = 1
SUBCASE 2
SUBTITLE = Clamp_+Y
SPC = 1
LOAD = 2
SUBCASE 3
SUBTITLE = Clamp_-X
SPC = 1
LOAD = 3
SUBCASE 4
SUBTITLE = Clamp_-Y
SPC = 1
LOAD = 4
SUBCASE 5
SUBTITLE = Clamp_+Z
SPC = 1
LOAD = 5
SUBCASE 6
SUBTITLE = Clamp_-Z
SPC = 1
LOAD = 6
BEGIN BULK
$ ***************************************************************************
$ Written by : Femap
$ Version : 2021.1.0
$ Translator : Simcenter Nastran
$ From Model :
$ Date : Thu Apr 13 10:18:32 2023
$ Output To : C:\Users\trbrooks\AppData\Local\Temp\2\
$ ***************************************************************************
$
PARAM,PRGPST,YES
PARAM,POST,-1
PARAM,OGEOM,NO
PARAM,AUTOSPC,YES
PARAM,K6ROT,100.
PARAM,GRDPNT,0
CORD2C 1 0 0. 0. 0. 0. 0. 1.+FEMAPC1
+FEMAPC1 1. 0. 1.
CORD2S 2 0 0. 0. 0. 0. 0. 1.+FEMAPC2
+FEMAPC2 1. 0. 1.
$ Femap Load Set 1 : Forces
PLOAD4 1 3-100000. 2 9
PLOAD4 1 4-100000. 3 10
$ Femap Load Set 2 : +Y
PLOAD4 2 4-100000. 4 11
$ Femap Load Set 3 : -X
PLOAD4 3 3-100000. 6 7
PLOAD4 3 4-100000. 5 12
$ Femap Load Set 4 : -Y
PLOAD4 4 3-100000. 1 8
$ Femap Load Set 5 : +Z
PLOAD4 5 3-100000. 7 9
PLOAD4 5 4-100000. 12 10
$ Femap Load Set 6 : -Z
PLOAD4 6 3-100000. 1 3
PLOAD4 6 4-100000. 6 4
$ Femap Constraint Set 1 : Clamp
SPC1 1 123456 1
SPC1 1 123456 5
SPC1 1 123456 6
SPC1 1 123456 7
SPC1 1 123456 11
SPC1 1 123456 12
$ Femap Property 1 : Dummy
PSOLID 1 1 0
$ Femap Material 1 : Aluminum
MAT1 1 7.+5 .3 2.700 0. 0. +
+ 2.7+3
GRID 1 0 0. 0. 0. 0
GRID 2 0 1. 0. 0. 0
GRID 3 0 1. 1. 0. 0
GRID 4 0 1. 2. 0. 0
GRID 5 0 0. 2. 0. 0
GRID 6 0 0. 1. 0. 0
GRID 7 0 0. 0. 1. 0
GRID 8 0 1. 0. 1. 0
GRID 9 0 1. 1. 1. 0
GRID 10 0 1. 2. 1. 0
GRID 11 0 0. 2. 1. 0
GRID 12 0 0. 1. 1. 0
CHEXA 3 1 1 2 3 6 7 8+
+ 9 12
CHEXA 4 1 6 3 4 5 12 9+
+ 10 11
ENDDATA
147 changes: 147 additions & 0 deletions tests/integration_tests/test_elast_linhexa_pressure_3d.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
import os

from pytacs_analysis_base_test import PyTACSTestCase
from tacs import pytacs, functions

"""
This model features two adjacent linear hex elements, clamped on one face.
Six load conditions are considered: a pressure applied to each of the six faces using PLOAD4 cards.
This test verifies that pyTACS/TACS applies pressure load on the consistent face based on the PLOAD4 information.

tests KSDisplacement, StructuralMass, and Compliance functions and sensitivities.
"""

base_dir = os.path.dirname(os.path.abspath(__file__))
bdf_file = os.path.join(base_dir, "./input_files/two_hexs.bdf")

ksweight = 10.0


class ProblemTest(PyTACSTestCase.PyTACSTest):
N_PROCS = 2 # this is how many MPI processes to use for this TestCase.

FUNC_REFS = {
"Clamp_+X_-x_disp": -0.2716543418951961,
"Clamp_+X_-y_disp": 0.1944965504786221,
"Clamp_+X_-z_disp": 0.1122082988741163,
"Clamp_+X_compliance": 25788.7451098405,
"Clamp_+X_mass": 5.400000000000001,
"Clamp_+X_x_disp": 1.0274069094117648,
"Clamp_+X_y_disp": 0.19449655047862183,
"Clamp_+X_z_disp": 0.11220829887411632,
"Clamp_+Y_-x_disp": 0.372199546911399,
"Clamp_+Y_-y_disp": -0.2108822590307131,
"Clamp_+Y_-z_disp": 0.07859767285648897,
"Clamp_+Y_compliance": 11409.61367995888,
"Clamp_+Y_mass": 5.400000000000001,
"Clamp_+Y_x_disp": 0.10005467583046843,
"Clamp_+Y_y_disp": 1.4357366919830612,
"Clamp_+Y_z_disp": 0.07859767285648912,
"Clamp_-X_-x_disp": 0.06931471805599453,
"Clamp_-X_-y_disp": 0.06931471805599453,
"Clamp_-X_-z_disp": 0.06931471805599453,
"Clamp_-X_compliance": 0.0,
"Clamp_-X_mass": 5.400000000000001,
"Clamp_-X_x_disp": 0.06931471805599453,
"Clamp_-X_y_disp": 0.06931471805599453,
"Clamp_-X_z_disp": 0.06931471805599453,
"Clamp_-Y_-x_disp": 0.37219954691139895,
"Clamp_-Y_-y_disp": 1.435736691983061,
"Clamp_-Y_-z_disp": 0.0785976728564891,
"Clamp_-Y_compliance": 11409.61367995888,
"Clamp_-Y_mass": 5.400000000000001,
"Clamp_-Y_x_disp": 0.10005467583046848,
"Clamp_-Y_y_disp": -0.21088225903071312,
"Clamp_-Y_z_disp": 0.07859767285648898,
"Clamp_+Z_-x_disp": 0.6483960432371099,
"Clamp_+Z_-y_disp": 0.1708538959664814,
"Clamp_+Z_-z_disp": -0.6532709558080134,
"Clamp_+Z_compliance": 36425.924866297384,
"Clamp_+Z_mass": 5.400000000000001,
"Clamp_+Z_x_disp": 0.423860759605031,
"Clamp_+Z_y_disp": 0.1708538959664828,
"Clamp_+Z_z_disp": 2.6861025015727664,
"Clamp_-Z_-x_disp": 0.6483960432371095,
"Clamp_-Z_-y_disp": 0.17085389596648218,
"Clamp_-Z_-z_disp": 2.6861025015727664,
"Clamp_-Z_compliance": 36425.924866297384,
"Clamp_-Z_mass": 5.400000000000001,
"Clamp_-Z_x_disp": 0.4238607596050309,
"Clamp_-Z_y_disp": 0.17085389596648243,
"Clamp_-Z_z_disp": -0.6532709558080131,
}

def setup_tacs_problems(self, comm):
"""
Setup mesh and pytacs object for problem we will be testing.
"""

# Overwrite default check values
if self.dtype == complex:
self.rtol = 1e-6
self.atol = 1e-6
self.dh = 1e-50
else:
self.rtol = 2e-1
self.atol = 1e-3
self.dh = 1e-6

# Instantiate FEA Assembler
struct_options = {}

fea_assembler = pytacs.pyTACS(bdf_file, comm, options=struct_options)

# Set up constitutive objects and elements
fea_assembler.initialize()

# Read in forces from BDF and create tacs struct problems
tacs_probs = fea_assembler.createTACSProbsFromBDF()
# Convert from dict to list
tacs_probs = tacs_probs.values()
# Set convergence to be tight for test
for problem in tacs_probs:
problem.setOption("L2Convergence", 1e-20)
problem.setOption("L2ConvergenceRel", 1e-20)

# Add Functions
for problem in tacs_probs:
problem.addFunction("mass", functions.StructuralMass)
problem.addFunction("compliance", functions.Compliance)
problem.addFunction(
"x_disp",
functions.KSDisplacement,
ksWeight=ksweight,
direction=[10.0, 0.0, 0.0],
)
problem.addFunction(
"y_disp",
functions.KSDisplacement,
ksWeight=ksweight,
direction=[0.0, 10.0, 0.0],
)
problem.addFunction(
"z_disp",
functions.KSDisplacement,
ksWeight=ksweight,
direction=[0.0, 0.0, 10.0],
)
problem.addFunction(
"-x_disp",
functions.KSDisplacement,
ksWeight=ksweight,
direction=[-10.0, 0.0, 0.0],
)
problem.addFunction(
"-y_disp",
functions.KSDisplacement,
ksWeight=ksweight,
direction=[0.0, -10.0, 0.0],
)
problem.addFunction(
"-z_disp",
functions.KSDisplacement,
ksWeight=ksweight,
direction=[0.0, 0.0, -10.0],
)

return tacs_probs, fea_assembler