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

BladeStiffenedShellConstitutive and documentation improvements #226

Merged
merged 13 commits into from
Jul 7, 2023
Merged
4 changes: 2 additions & 2 deletions docs/source/pytacs/buckling.rst
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
BucklingProblem
------------
---------------
.. automodule:: tacs.problems.buckling

Options
Expand All @@ -16,4 +16,4 @@ API Reference
^^^^^^^^^^^^^
.. autoclass:: tacs.problems.BucklingProblem
:members:
:inherited-members:
:inherited-members:
8 changes: 4 additions & 4 deletions src/constitutive/TACSBladeStiffenedShellConstitutive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ TACSBladeStiffenedShellConstitutive::TACSBladeStiffenedShellConstitutive(
this->numDesignVars++;
this->numPanelDV++;
}
this->panelPlyFracLowerBounds[ii] = 0.1;
this->panelPlyFracUpperBounds[ii] = 0.9;
this->panelPlyFracLowerBounds[ii] = 0.0;
this->panelPlyFracUpperBounds[ii] = 1.0;
}

// --- Stiffener DVs ---
Expand Down Expand Up @@ -154,8 +154,8 @@ TACSBladeStiffenedShellConstitutive::TACSBladeStiffenedShellConstitutive(
this->numDesignVars++;
this->numStiffenerDV++;
}
this->stiffenerPlyFracLowerBounds[ii] = 0.1;
this->stiffenerPlyFracUpperBounds[ii] = 0.9;
this->stiffenerPlyFracLowerBounds[ii] = 0.0;
this->stiffenerPlyFracUpperBounds[ii] = 1.0;
}

// --- Stiffener flange fraction ---
Expand Down
10 changes: 10 additions & 0 deletions src/constitutive/TACSBladeStiffenedShellConstitutive.h
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ class TACSBladeStiffenedShellConstitutive : public TACSShellConstitutive {
int getDesignVarRange(int elemIndex, int dvLen, TacsScalar lb[],
TacsScalar ub[]);

/**
* @brief Get the number of panel plies
*/
int getNumPanelPlies() { return this->numPanelPlies; }

/**
* @brief Get the number of stiffener plies
*/
int getNumStiffenerPlies() { return this->numStiffenerPlies; }

// ==============================================================================
// Evaluate mass properties
// ==============================================================================
Expand Down
2 changes: 2 additions & 0 deletions tacs/constitutive.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ cdef extern from "TACSBladeStiffenedShellConstitutive.h":
int[], # stiffenerPlyFracNums
TacsScalar # flangeFraction
)
int getNumPanelPlies()
int getNumStiffenerPlies()
void setKSWeight(double ksWeight)
void setStiffenerPitchBounds(TacsScalar lowerBound, TacsScalar upperBound)
void setStiffenerHeightBounds(TacsScalar lowerBound, TacsScalar upperBound)
Expand Down
185 changes: 156 additions & 29 deletions tacs/constitutive.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -764,10 +764,89 @@ cdef class CompositeShellConstitutive(ShellConstitutive):

self.props = [prop.getMaterialProperties() for prop in ply_list]

def generateBDFCard(self):
"""
Generate pyNASTRAN card class based on current design variable values.

Returns:
card (pyNastran.bdf.cards.properties.shell.PCOMP): pyNastran card holding property information
"""
num_plies = len(self.props)
cdef TACSCompositeShellConstitutive* comp_ptr = <TACSCompositeShellConstitutive*>self.cptr
cdef np.ndarray ply_thicknesses = np.zeros(num_plies, dtype)
cdef np.ndarray ply_angles = np.zeros(num_plies, dtype)

comp_ptr.getPlyThicknesses(<TacsScalar*>ply_thicknesses.data)
comp_ptr.getPlyAngles(<TacsScalar*>ply_angles.data)

mat_ids = []
for i in range(num_plies):
ply_id = self.props[i].getNastranID()
mat_ids.append(ply_id)

prop = nastran_cards.properties.shell.PCOMP(self.nastranID, mat_ids,
ply_thicknesses.astype(float),
np.rad2deg(ply_angles, dtype=float))
return prop

cdef class BladeStiffenedShellConstitutive(ShellConstitutive):
"""This constitutive class models a shell stiffened with T-shaped stiffeners.
The stiffeners are not explicitly modelled.
Instead, their stiffness is "smeared" across the shell.

Parameters
----------
panelPly : tacs.constitutive.OrthotropicPly object
Ply model to use for the panel
stiffenerPly : tacs.constitutive.OrthotropicPly object
Ply model to use for the stiffener
kcorr : TacsScalar
Shear correction factor, usually 5.0/6.0
panelLength : TacsScalar
Panel length DV value
panelLengthNum : int
Panel lenth DV number, passing a negative value tells TACS not to treat this as a DV
stiffenerPitch : TacsScalar
Stiffener pitch DV value
stiffenerPitchNum : int
DV number, passing a negative value tells TACS not to treat this as a DV
panelThick : TacsScalar
Panel thickness DV value
panelThickNum : int
DV number, passing a negative value tells TACS not to treat this as a DV
numPanelPlies : int
Number of distinct ply angles in the panel
panelPlyAngles : np.array of numPanelPlies TacsScalars
Array of ply angles in the panel
panelPlyFracs : np.array of numPanelPlies TacsScalars
Array of ply fractions in the panel
panelPlyFracNums : np.array of numPanelPlies int
Array of ply fraction DV numbers in the panel, passing negative values tells TACS not to treat that ply fraction as a DV
stiffenerHeight : TacsScalar
Stiffener height DV value
stiffenerHeightNum : int
DV number, passing a negative value tells TACS not to treat this as a DV
timryanb marked this conversation as resolved.
Show resolved Hide resolved
stiffenerThick : TacsScalar
Stiffener thickness DV value
stiffenerThickNum : int
DV number, passing a negative value tells TACS not to treat this as a DV
numStiffenerPlies : int
Number of distinct ply angles in the stiffener
stiffenerPlyAngles : np.array of numPanelPlies TacsScalars
Array of ply angles for the stiffener
stiffenerPlyFracs : np.array of numPanelPlies TacsScalars
Array of ply fractions for the stiffener
stiffenerPlyFracNums : np.array of numPanelPlies int
Array of ply fraction DV numbers for the stiffener, passing negative values tells TACS not to treat that ply fraction as a DV
flangeFraction : float, optional
Ratio of the stiffener base width to the stiffener height, by default 1.0

Raises
------
ValueError
Raises error if panelPlyAngles, panelPlyFracs, or panelPlyFracNums do not have numPanelPlies entries
ValueError
Raises error if stiffenerPlyAngles, stiffenerPlyFracs, or stiffenerPlyFracNums do not have numStiffenerPlies entries
"""
def __cinit__(
self,
Expand Down Expand Up @@ -797,19 +876,22 @@ cdef class BladeStiffenedShellConstitutive(ShellConstitutive):

if len(panelPlyAngles) != numPanelPlies:
raise ValueError('panelPlyAngles must have length numPanelPlies')
if len(panelPlyAngles) != numPanelPlies:
raise ValueError('panelPlyNums must have length numPanelPlies')
if len(panelPlyFracs) != numPanelPlies:
raise ValueError('panelPlyFracs must have length numPanelPlies')
if len(panelPlyFracNums) != numPanelPlies:
raise ValueError('panelPlyFracNums must have length numPanelPlies')
if len(stiffenerPlyAngles) != numStiffenerPlies:
raise ValueError('stiffenerPlyAngles must have length numStiffenerPlies')
if len(stiffenerPlyAngles) != numStiffenerPlies:
raise ValueError('stiffenerPlyNums must have length numStiffenerPlies')
if len(stiffenerPlyFracs) != numStiffenerPlies:
raise ValueError('stiffenerPlyFracs must have length numStiffenerPlies')
if len(stiffenerPlyFracNums) != numStiffenerPlies:
raise ValueError('stiffenerPlyFracNums must have length numStiffenerPlies')

# Numpy's default int type is int64, but this is interpreted by Cython as a long.
if panelPlyFracNums.dtype != np.intc:
panelPlyFracNums = panelPlyFracNums.astype(np.intc)
if stiffenerPlyFracNums.dtype != np.intc:
stiffenerPlyFracNums = stiffenerPlyFracNums.astype(np.intc)
# raise ValueError('panelPlyFracNums must be of type int32')

self.blade_ptr = new TACSBladeStiffenedShellConstitutive(
panelPly.ptr,
Expand Down Expand Up @@ -849,20 +931,64 @@ cdef class BladeStiffenedShellConstitutive(ShellConstitutive):
self.blade_ptr.setKSWeight(ksWeight)

def setStiffenerPitchBounds(self, TacsScalar lowerBound, TacsScalar upperBound):
"""Set the lower and upper bounds for the stiffener pitch design variable

The default bounds are 1e-3 and 1e20

Parameters
----------
lowerBound : TacsScalar
Lower bound
upperBound : TacsScalar
Upper bound
"""
if self.blade_ptr:
self.blade_ptr.setStiffenerPitchBounds(lowerBound, upperBound)

def setStiffenerHeightBounds(self, TacsScalar lowerBound, TacsScalar upperBound):
"""Set the lower and upper bounds for the stiffener height design variable

The default bounds are 1e-3 and 1e20

Parameters
----------
lowerBound : TacsScalar
Lower bound
upperBound : TacsScalar
Upper bound
"""

if self.blade_ptr:
self.blade_ptr.setStiffenerHeightBounds(lowerBound, upperBound)

def setStiffenerThicknessBounds(self, TacsScalar lowerBound, TacsScalar upperBound):
"""Set the lower and upper bounds for the stiffener thickness design variable

The default bounds are 1e-4 and 1e20

Parameters
----------
lowerBound : TacsScalar
Lower bound
upperBound : TacsScalar
Upper bound
"""

if self.blade_ptr:
self.blade_ptr.setStiffenerThicknessBounds(lowerBound, upperBound)

def setPanelThicknessBounds(self, TacsScalar lowerBound, TacsScalar upperBound):
"""Set the lower and upper bounds for the panel thickness design variable

The default bounds are 1e-4 and 1e20

Parameters
----------
lowerBound : TacsScalar
Lower bound
upperBound : TacsScalar
Upper bound
"""

if self.blade_ptr:
self.blade_ptr.setPanelThicknessBounds(lowerBound, upperBound)
Expand All @@ -872,43 +998,44 @@ cdef class BladeStiffenedShellConstitutive(ShellConstitutive):
np.ndarray[TacsScalar, ndim=1, mode='c'] lowerBound,
np.ndarray[TacsScalar, ndim=1, mode='c'] upperBound
):
"""Set the lower and upper bounds for the stiffener ply fraction design variables

The default bounds are 0 and 1

Raises
------
ValueError
Raises error if the length of lowerBound or upperBound is not equal to the number of stiffener plies
"""

if self.blade_ptr:
if len(lowerBound) != self.blade_ptr.getNumStiffenerPlies():
raise ValueError('lowerBound must have length numStiffenerPlies')
if len(upperBound) != self.blade_ptr.getNumStiffenerPlies():
raise ValueError('upperBound must have length numStiffenerPlies')
self.blade_ptr.setStiffenerPlyFractionBounds(<TacsScalar*>lowerBound.data, <TacsScalar*>upperBound.data)

def setPanelPlyFractionBounds(
self,
np.ndarray[TacsScalar, ndim=1, mode='c'] lowerBound,
np.ndarray[TacsScalar, ndim=1, mode='c'] upperBound
):
"""Set the lower and upper bounds for the panel ply fraction design variables

if self.blade_ptr:
self.blade_ptr.setPanelPlyFractionBounds(<TacsScalar*>lowerBound.data, <TacsScalar*>upperBound.data)

def generateBDFCard(self):
"""
Generate pyNASTRAN card class based on current design variable values.
The default bounds are 0 and 1

Returns:
card (pyNastran.bdf.cards.properties.shell.PCOMP): pyNastran card holding property information
Raises
------
ValueError
Raises error if the length of lowerBound or upperBound is not equal to the number of panel plies
"""
num_plies = len(self.props)
cdef TACSCompositeShellConstitutive* comp_ptr = <TACSCompositeShellConstitutive*>self.cptr
cdef np.ndarray ply_thicknesses = np.zeros(num_plies, dtype)
cdef np.ndarray ply_angles = np.zeros(num_plies, dtype)

comp_ptr.getPlyThicknesses(<TacsScalar*>ply_thicknesses.data)
comp_ptr.getPlyAngles(<TacsScalar*>ply_angles.data)

mat_ids = []
for i in range(num_plies):
ply_id = self.props[i].getNastranID()
mat_ids.append(ply_id)

prop = nastran_cards.properties.shell.PCOMP(self.nastranID, mat_ids,
ply_thicknesses.astype(float),
np.rad2deg(ply_angles, dtype=float))
return prop
if self.blade_ptr:
if len(lowerBound) != self.blade_ptr.getNumPanelPlies():
raise ValueError('lowerBound must have length numPanelPlies')
if len(upperBound) != self.blade_ptr.getNumPanelPlies():
raise ValueError('upperBound must have length numPanelPlies')
self.blade_ptr.setPanelPlyFractionBounds(<TacsScalar*>lowerBound.data, <TacsScalar*>upperBound.data)

cdef class LamParamShellConstitutive(ShellConstitutive):
def __cinit__(self, OrthotropicPly ply, **kwargs):
Expand Down
Loading