The iPython notebook for this demo can be found in:
Import pyNastran
In [1]:
import os
import pyNastran
print (pyNastran.__file__)
print (pyNastran.__version__)
pkg_path = pyNastran.__path__[0]
from pyNastran.bdf.bdf import BDF, read_bdf
from pyNastran.utils import object_attributes, object_methods
print("pkg_path = %s" % pkg_path)
it's a .dat file, so instead of:
>>> pyNastranGUI -i bdf_filename
we need to include the format:
>>> pyNastranGUI -f nastran -i bdf_filename
Alternatively, we could load the model and the results, but in this demo we're just showing off the geometry. To do that instead:
>>> pyNastranGUI -f nastran -i bdf_filename -o op2_filename
In [2]:
bdf_filename = os.path.abspath(os.path.join(pkg_path, '..', 'models', 'iSat', 'ISat_Launch_Sm_Rgd.dat'))
print(bdf_filename)
# look at the model
!pyNastranGUI -f nastran -i {bdf_filename} > junk.out
There are two ways to load a BDF; the long way or the short way.
The short way instantiates the BDF class and the short way uses the read_bdf function.
As this demo was written for the Jupyter Notebook, we'll use read_bdf and then mention the other method. The class-based method allows finer control over things like:
In [3]:
print(bdf_filename)
# create the BDF object
bdf = BDF()
# read the file from the GUI
# don't cross-reference
bdf.read_bdf(bdf_filename, xref=False)
In [4]:
bdf = read_bdf(bdf_filename, xref=False)
For simplicity of using the demo, we'll again use the read_bdf method
In [5]:
#bdf_filename = r'D:\work\pynastran_0.8.0_py27\models\iSat\ISat_Launch_Sm_Rgd.dat'
bdf_filename = os.path.abspath(os.path.join(pkg_path, '..', 'models', 'iSat', 'ISat_Launch_Sm_Rgd.dat'))
# read the file as a path
bdf_xref = read_bdf(bdf_filename, xref=True)
IDE's like WingIDE, PyCharm, Spyder and "Python Tools for Visual Studio" make it very easy to program with their object introspection ability. Unfortunately, because pyNastran has so many functions, it can be difficult to learn the code.
Some handy object introspection methods were created that will work on all pyNastran objects and even non-pyNastran objects. By convention, private data members/functions start with an underscore _, and public ones do not.
We can use the generic object attributes/methods functions
In [6]:
print(object_attributes(bdf))
print(object_methods(bdf))
In [7]:
print("attributes = [%s]\n" % ', '.join(bdf.object_attributes()))
print("methods = [%s]\n" % ', '.join(bdf.object_methods()))
In [8]:
print(bdf.get_bdf_stats())
print("card_count = %s\n" % bdf.card_count)
print("reject_count = %s" % bdf.reject_count)
Cross-referencing a BDF allows improved usability of the BDF class. It comes with some negative side effects, but in general is a very useful thing. It dramatically minimizes the amount of code you need to write, greatly simplifies future operations, and is highly recommended.
The major downside is it prevents decks from being saved to object files for faster loading.
Here the raw values of the the data objects are returned to us
In [9]:
cquad = bdf.elements[1]
print(cquad)
nid1 = cquad.nodes[0]
print("nid1 = %s" % nid1)
n1 = bdf.nodes[nid1]
cd4 = n1.cd
c4 = bdf.coords[cd4]
print("i xref=False %s" % str(c4.i))
#print object_attributes(c4)
In [10]:
print("i xref=True %s" % bdf_xref.elements[1].nodes[0].cd.i)
So how is this done?
In [11]:
cquad.nodes[0] = n1
print(cquad.nodes[0])
In [12]:
# some Grid methods
n1 = bdf_xref.nodes[1]
print(n1)
# the comment
c1 = bdf_xref.nodes[1].comment
c2 = bdf_xref.nodes[2].comment
print("c1=%r" % c1)
print("c2=%r" % c2)
# get the position of a node
# in the local cooordinate system
print("xyz = %s" % n1.xyz)
# in the global frame
print("position = %s" % n1.get_position())
# in an arbitrary frame
print("wrt5 = %s" % n1.get_position_wrt(bdf, 5))
print("wrt4 = %s" % n1.get_position_wrt(bdf, 4))
Now let's modify the GRID card and write it out
In [13]:
n1 = bdf_xref.nodes[1]
n1.xyz[1] = -7.5
print("repr = %s" % n1.repr_fields())
print("raw = %s" % n1.repr_fields())
#n1.xyz[1] = 100000000000.
print("repr2 = %s" % n1.repr_fields())
print(n1)
print(n1.write_card(size=8))
print(n1.write_card(size=16, is_double=False))
print(n1.write_card(size=16, is_double=True))
In [14]:
mass, cg, I = bdf_xref.mass_properties()
print("mass = %s" % mass)
In [15]:
eid100 = bdf_xref.elements[100]
print(eid100)
print("nodes = %s" % eid100.nodes)
print("--node0--\n%s" % eid100.nodes[0])
print("--cd--\n%s" % eid100.nodes[0].cd)
print("cd.cid = %s" % eid100.nodes[0].cd.cid)
print("area = %s" % eid100.Area())
print("mass = %s" % eid100.Mass())
print("--pid--\n%s" % eid100.pid)
print("pid.pid = %s" % eid100.pid.pid)
print("pid.Pid() = %s" % eid100.Pid())
print(eid100.pid.mid1)
print("type = %s" % eid100.pid.mid1.type)
print("nu12 = %s" % eid100.pid.mid1.nu12)
print("mass = %s" % eid100.Mass())
In [16]:
import getpass
name = getpass.getuser()
os.chdir(os.path.join(r'C:\Users', name, 'Desktop'))
In [17]:
pwd
Out[17]:
There are two ways to write a deck
We can also use 8 or 16 character field width as well as double precision.
Note that double precision only works for certain cards (e.g. GRID, COORD, DMIG) and not much else.
In [18]:
bdf_xref.write_bdf('fem.bdf', interspersed=False, size=8, is_double=False)
!tail -n 5 "fem.bdf"
bdf_xref.write_bdf('fem.bdf', interspersed=True, size=16, is_double=False)
!tail "fem.bdf"
bdf_xref.write_bdf('fem.bdf', interspersed=True, size=16, is_double=True)
!tail "fem.bdf"
In [19]:
bdf_filename
Out[19]:
In [20]:
print(bdf_filename)
%echo {bdf_filename}
#!pyNastranGUI -f nastran -i {bdf_filename}
solid_bending_bdf = os.path.abspath(os.path.join(pkg_path, '..', 'models', 'solid_bending', 'solid_bending.bdf'))
solid_bending_op2 = os.path.abspath(os.path.join(pkg_path, '..', 'models', 'solid_bending', 'solid_bending.op2'))
!pyNastranGUI -f nastran -i {solid_bending_bdf} -o {solid_bending_op2} > junk.out
print("done")
In [21]:
with open('script.py', 'w') as f:
f.write('self.on_wireframe()\n')
picture_filename = os.path.join(os.getcwd(), 'wireframe_solid_bending.png')
f.write("self.on_take_screenshot(%r)\n" % picture_filename)
f.write('sys.exit()')
!pwd
!pyNastranGUI -f nastran -i {solid_bending_bdf} -o {solid_bending_op2} --postscript script.py > junk.out
# display in a popup
!wireframe_solid_bending.png
from IPython.display import Image
from IPython.display import display
assert os.path.exists('wireframe_solid_bending.png')
# display in iPython
i = Image(filename='wireframe_solid_bending.png')
display(i)
print("the picture is visible")
In [ ]:
In [ ]: