Mystran Analysis Interface Module (AIM)
Mystran Analysis Interface Module (AIM)
Mystran AIM Basic Example

Table of Contents

This is a walkthrough for using MYSTRAN AIM to analyze a three-dimensional wing with internal ribs and spars.

Prerequisites

It is presumed that ESP and CAPS have been already installed, as well as MYSTRAN.

Script files

Two scripts are used for this illustration:

  1. feaWingBEM.csm: Creates geometry, as described in the next section (Creating Geometry using ESP ).
  2. mystran_PyTest.py: pyCAPS script for performing analysis, as described in Performing analysis using pyCAPS .

Creating Geometry using ESP

In our example *.csm file setting up the CAPS fidelity is the first step. If multiple bodies exist in the *.csm file the tag, capsIntent, can be used to distinguish what type of analysis the body may be used for. In this example, the geometry model generated can be used for structural analysis, as shown:

attribute capsIntent STRUCTURE

A typical geometry model can be created and interactively modified using design parameters. These design parameters are either design- or geometry- based. In this example, a wing configuration is created using following design parameters.

# Design Parameters for OML
despmtr thick 0.12 frac of local chord
despmtr camber 0.04 frac of loacl chord
despmtr area 10.0
despmtr aspect 6.00
despmtr taper 0.60
despmtr sweep 20.0 deg (of c/4)
despmtr washout 5.00 deg (down at tip)
despmtr dihedral 4.00 deg
# Design Parameters for BEM
despmtr nrib 11 number of ribs
despmtr spar1 0.20 frac of local chord
despmtr spar2 0.75 frac of local chord

After our design parameters are defined they are used to setup other local variables (analytically) for the outer model line (OML).

# OML
set span sqrt(aspect*area)
set croot 2*area/span/(1+taper)
set ctip croot*taper
set dxtip (croot-ctip)/4+span/2*tand(sweep)
set dytip span/2*tand(dihedral)

In a similar manner, local variables are defined for the ribs and spars.

# wing ribs
dimension waffle nrib+4 4 0
set Nrib nint(nrib)
patbeg i Nrib
set waffle[i,1] (span/2)*(2*i-Nrib-1)/Nrib
set waffle[i,2] -0.01*croot
set waffle[i,3] (span/2)*(2*i-Nrib-1)/Nrib
set waffle[i,4] max(croot,dxtip+ctip)
patend
# wing spars
set eps 0.01*span
set waffle[Nrib+1,1] -span/2-eps
set waffle[Nrib+1,2] spar1*ctip+dxtip
set waffle[Nrib+1,3] 0
set waffle[Nrib+1,4] spar1*croot
set waffle[Nrib+2,1] span/2+eps
set waffle[Nrib+2,2] spar1*ctip+dxtip
set waffle[Nrib+2,3] 0
set waffle[Nrib+2,4] spar1*croot
set waffle[Nrib+3,1] -span/2-eps
set waffle[Nrib+3,2] spar2*ctip+dxtip
set waffle[Nrib+3,3] 0
set waffle[Nrib+3,4] spar2*croot
set waffle[Nrib+4,1] span/2+eps
set waffle[Nrib+4,2] spar2*ctip+dxtip
set waffle[Nrib+4,3] 0
set waffle[Nrib+4,4] spar2*croot

Once all design and local variables are defined, a full span, solid model is created by "ruling" together NACA series airfoils (following a series of scales, rotations, and translations).

mark
# Right tip
udprim naca Thickness thick Camber camber
scale ctip
rotatez washout ctip/4 0
translate dxtip dytip -span/2
# root
udprim naca Thickness thick Camber camber
scale croot
# left tip
udprim naca Thickness thick Camber camber
scale ctip
rotatez washout ctip/4 0
translate dxtip dytip +span/2
rule
attribute OML 1

Once complete, the wing is stored for later use under the name OML.

store OML

Next, the inner layout of the ribs and spars are created using the waffle udprim.

udprim waffle Depth +6*thick*croot Segments waffle

An attribute is then placed on ribs and spars so that the geometry components may be reference by the MYSTRAN AIM.

attribute capsGroup $Ribs_and_Spars

Following a series of rotations and translations the ribs and spars are stored for later use.

translate 0 0 -3*thick*croot
rotatey 90 0 0
rotatez -90 0 0
store layoutRibSpar

Next, the layout of the ribs and spars are intersected the outer mold line of wing, which results in only keeping the part of layout that is inside the OML.

restore layoutRibSpar
restore OML
intersect

Finally, select faces (airfoil sections at the root) are tagged, so that a constraint may be applied later.

select face 31
attribute capsConstraint $Rib_Constraint
select face 27
attribute capsConstraint $Rib_Constraint
select face 26
attribute capsConstraint $Rib_Constraint

The above *.csm file results in the follow geometry model:

exampleWingBEM.png
Wing built up element model

Performing analysis using pyCAPS

The first step in the pyCAPS script is to import the required modules. For this example the following modules are used,

from __future__ import print_function
try:
import os
except:
print ("Unable to import os module")
raise SystemError

In order to create a new capsProblem the pyCAPS module also needs to be imported; on Linux and OSX this is the pyCAPS.so file, while on Windows it is the pyCAPS.pyd file. For convenience, it is recommended that the path to this file is added to the environmental variable PYTHONPATH.

from pyCAPS import capsProblem

Similarly, local variables used throughout the script may be defined.

workDir = "MystranModalWingBEM"
projectName = workDir

Once the required modules have been loaded, a capsProblem can be instantiated.

myProblem = capsProblem()

Next, using the loadCAPS() function, the desired geometry file is then loaded into the problem.

myProblem.loadCAPS("./csmData/feaWingBEM.csm")

After the geometry is loaded, the MYSTRAN AIM needs to be instantiated. Note that below, the capsIntent is set to "ALL" as opposed to "STRUCTURE" as specified above in the *.csm file. This is only valid since there is only one body in the *.csm file. If more than one body existed in the *.csm file the capsIntent during the loadAIM() function call should be set "STRUCTURE".

mystranAIM = myProblem.loadAIM(aim = "mystranAIM",
altName = "mystran",
analysisDir= workDir,
capsIntent = "ALL")

Once loaded analysis parameters specific to MYSTRAN need to be set (see AIM Inputs). These parameters are automatically converted into MYSTRAN specific format and transferred into the MYSTRAN configuration file. One will note in the following snippet the instance of the AIM is referenced in two different manners: 1. Using the returned object from load call and 2. Using the "altName" name reference in the analysis dictionary. While syntactically different, these two forms are essentially identical.

# Set project name so a mesh file is generated
mystranAIM.setAnalysisVal("Proj_Name", projectName)
# Set meshing inputs
myProblem.analysis["mystran"].setAnalysisVal("Edge_Point_Max", 4)
myProblem.analysis["mystran"].setAnalysisVal("Quad_Mesh", True)

Along the same lines of setting the input values above the "Analysis" (see FEA Analysis), "Material" (see FEA Material), "Property" (see FEA Property), and "Constraint" (see FEA Constraint) tuples are used to set more complex information. The user is encouraged to read the additional documentation on these inputs for further explanations. Once provided this information is converted into MYSTRAN specific syntax and set in the MYSTRAN configuration file.

# Set analysis
eigen = { "extractionMethod" : "Lanczos",
"frequencyRange" : [0, 50],
"numEstEigenvalue" : 1,
"eigenNormaliztion" : "MASS"}
mystranAIM.setAnalysisVal("Analysis", ("EigenAnalysis", eigen))
# Set materials
unobtainium = {"youngModulus" : 2.2E11 ,
"poissonRatio" : .33,
"density" : 7850}
madeupium = {"materialType" : "isotropic",
"youngModulus" : 1.2E9 ,
"poissonRatio" : .5,
"density" : 7850}
mystranAIM.setAnalysisVal("Material", [("Unobtainium", unobtainium),
("Madeupium", madeupium)])
# Set property
shell = {"propertyType" : "Shell",
"membraneThickness" : 0.2,
"bendingInertiaRatio" : 1.0, # Default
"shearMembraneRatio" : 5.0/6.0} # Default }
mystranAIM.setAnalysisVal("Property", ("Ribs_and_Spars", shell))
# Set constraints
constraint = {"groupName" : ["Rib_Constraint"],
"dofConstraint" : 123456}
mystranAIM.setAnalysisVal("Constraint", ("ribConstraint", constraint))

After all desired options are set aimPreAnalysis needs to be executed. Based on the input provided, MYSTRAN specific files are generated during this call.

mystranAIM.aimPreAnalysis()

At this point the required files necessary run MYSTRAN should have be created and placed in the specified analysis working directory. Next MYSTRAN needs to executed. In this example an OS system is made such as,

print ("\n\nRunning MYSTRAN......")
currentDirectory = os.getcwd() # Get our current working directory
os.chdir(mystranAIM.analysisDir) # Move into test directory
os.system("mystran.exe " + projectName + ".dat"); # Run MYSTRAN via system call
os.chdir(currentDirectory) # Move back to working directory
print ("Done running MYSTRAN!")

After MYSTRAN is finished running aimPostAnalysis needs to be executed.

mystranAIM.aimPostAnalysis()

Finally, available AIM outputs (see AIM Outputs) may be retrieved, for example:

print ("\nGetting results for natural frequencies.....")
natrualFreq = mystranAIM.getAnalysisOutVal("EigenFrequency")
mode = 1
for i in natrualFreq:
print ("Natural freq ( Mode", mode, ") = ", i, "(Hz)")
mode += 1

results in,

Natural freq (Mode 1) = 1.89166 (Hz)
Natural freq (Mode 2) = 6.33335 (Hz)
Natural freq (Mode 3) = 6.51397 (Hz)
Natural freq (Mode 4) = 23.88463 (Hz)
Natural freq (Mode 5) = 24.98205 (Hz)
Natural freq (Mode 6) = 28.23676 (Hz)
Natural freq (Mode 7) = 32.53667 (Hz)
Natural freq (Mode 8) = 33.92054 (Hz)
Natural freq (Mode 9) = 43.49964 (Hz)

When finally finished with the script, the open CAPS problem should be closed.

myProblem.closeCAPS()

Executing pyCAPS script

Issuing the following command executes the script:

python mystran_PyTest.py