This example introduces how to use the NastranIO class to read mesh information defined using Nastran bulk data format (BDF).
This example requires that MAST is compiled with the option ENABLE_NASTRANIO=ON
and requires a Python interpreter with the pyNastran package be detectable by the MAST CMake build process on your system.
The mesh data that is read from the BDF input includes nodes, elements, subdomains for assigning properties, and node boundary domains for assigning boundary conditions.
The geometry used in this example is a modified version of the of ACOSS-II (Active Control of Space Structures - Model 2) described in references [1] and [2], which has a compact BDF input suitable for use as a tutorial example. The ACOSS-II model has historical relevance as a demo case for optimal control of flexible structures and structural optimization with frequency constraints throughout the 1980's.
The mesh used in the example is taken from the ASTROS applications manual [3] and differs slightly from that in [2]. The basic geometry of the model is shown below:
![]() | ![]() | ![]() |
(a) ACOSS-II configuration (from [2]) | (b) ACOSS-II FEM representation (from [2]) | (c) ACOSS-II MAST finite element model |
We assume that the structure is modeled with beam elements and is made of a graphite epoxy material having Young's modulus 18.5x10 psi and mass density of 0.55 lb/in^3. We also assume currently that all elements have square cross section with dimensions 3.16 in by 3.16 in.
In the source listing below, we utilize components from the MAST library to setup a modal analysis of the modified ACOSS-II structure and calculate the first 10 vibration frequencies (eigenvalues) and mode shapes (eigenvectors). The structural mesh is read into libMesh/MAST using the NastranIO class.
The Nastran BDF mesh is located in the MAST source at: examples/structural/example_7/example_7_acoss_mesh.bdf
.
To run this example with a direct solver (when linear solves are required inside the eigenvalue solver) use: mpirun -np #procs structural_example_7 -ksp_type preonly -pc_type lu
.
TODO: Update this example to use actual truss elements with non-rectangular cross-section.
References:
# Documented Source Listing
Initialize libMesh library.
Create Mesh object on default MPI communicator. – note that currently, NastranIO only works with ReplicatedMesh.
Create a NastranIO object and read in the mesh from the specified .bdf. Print out some diagnostic info for the mesh/boundary to see what was read in.
Create EquationSystems object (a container for multiple systems of equations that are defined on a given mesh) and add a nonlinear system named "structural" to it. Set the eigen-problem type for the system so MAST knows we are eventually going to execute that solver. Also create a finite element type for the new system. Here we will use 1st order Lagrange-type elements and attach it to an initialization object, which provides the state variable setup for the equations corresponding to structural analysis.
Initialize a new discipline, which we will utilize to attach boundary conditions.
Create and add boundary conditions to the structural system. We use a Dirichlet BC to fix all of the nodes in SPC ID 1 in the .bdf file, which have been placed in a libMesh/MAST node boundary condition set with id of 1. Note that boundary condition application is not taken directly from the BDF definition, but simply the identification of which nodes are placed in the libMesh/MAST node boundary set. We specify which degrees-of-freedom for these nodes with DirichletBoundaryCondition.init(<boundary_id>, <variables>)
.
Initialize the equation systems.
Initialize the eigen-problem and eigenvalue solver. Specify the number of eigenvalues that we want to compute.
Create parameters.
Create ConstantFieldFunctions used to spread parameters throughout the model.
Create the material property card ("card" is NASTRAN lingo) and add the relevant field functions to it. An isotropic material in dynamics needs elastic modulus (E), Poisson ratio (nu), and density (rho) to describe its behavior.
Create the section property card. Attach all the required field functions to it. A 1D structural beam-type element with square cross-section requires two thickness dimensions and two offset dimensions. Here we assume the offsets are zero, which aligns the bending stiffness along the center axis of the element.
Specify a section orientation point and add it to the section. – Currently this orientation is arbitrary and we assume all beam sections are oriented in the same direction.
Attach the material to the section property, initialize the section, and then assign it to the subdomain in the mesh that it applies to. We note that we can reference the map between Nastran property IDs and libMesh/MAST subdomain IDs identify specific subdomains.
Create the structural modal assembly/element operations objects and initialize the condensed DOFs.
Solve eigenvalue problem.
Post-process the eigenvalue results. Get number of converged eigen pairs and variables to hold them.
Pre-allocate storage for calculations using the eigenvalues as well as storage for the eigenvector solution.
Setup table for eigenvalue/frequency console output.
Setup output files to save frequency data and mode shapes.
Exodus output file for mode shapes.
Loop over and process data for each vibration mode.
Get eigenvalue/eigenvector pair.
Get eigenvector on Rank 0 solution.
Calculate frequency for current eigenvalue.
Add data to console output table.
Write frequency results to text file (only from rank 0 processor).
Write currently active eigenvalue into Exodus file.
Output eigenvalue/frequency table to console.
Successful execution of the example should produce both console output and files. Tabular output showing eigenvalues, angular frequencies (in rad/s), and frequencies (in Hz) correpsonding to the first 10 vibration modes should be output to the console. This output should be similar to the following values:
Mode No. | Eigenvalue | Frequency (rad/s) | Frequency (Hz) |
---|---|---|---|
1 | 520.408008 | 22.812453 | 3.630715 |
2 | 2263.881979 | 47.580269 | 7.572635 |
3 | 3475.185118 | 58.950701 | 9.382295 |
4 | 7543.959254 | 86.855968 | 13.823557 |
5 | 7824.872647 | 88.458310 | 14.078577 |
6 | 11756.804335 | 108.428798 | 17.256979 |
7 | 13055.444785 | 114.260425 | 18.185111 |
8 | 53884.048267 | 232.129378 | 36.944538 |
9 | 63204.791232 | 251.405631 | 40.012449 |
10 | 86174.214772 | 293.554449 | 46.720642 |
In addition, two output files should be produced. freq_data.csv
contains console output in .csv format that is suitable for external post-processing. mode_shapes.exo
contains the mode shape data in the Exodus-ii format, which can be opened for visualization in Paraview.
The mode shapes corresponding to the first 9 vibration modes are shown below:
![]() | ![]() | ![]() |
Mode 1 | Mode 2 | Mode 3 |
![]() | ![]() | ![]() |
Mode 4 | Mode 5 | Mode 6 |
![]() | ![]() | ![]() |
Mode 7 | Mode 8 | Mode 9 |