예제 #1
0
    def test_coord_xform_b(self):
        origin = array([0., 0., 0.])
        zaxis = array([0., 0., 1.])
        xzplane = array([1., 0., 0.])
        cid0 = CORD2R(cid=0, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane)

        Lx = 2.
        Ly = 3.
        Lz = 5.
        Fy = 1.5
        origin = array([-Lx, -Ly, -Lz])
        z_axis = origin + array([0., 0., 1.])
        xz_plane = origin + array([1., 0., 1.])
        rid = 0
        data = [1, rid] + list(origin) + list(z_axis) + list(xz_plane)

        fxyz = [0., -Fy, 0.]
        mxyz = [0., 0., 0.]
        cid_new = CORD2R.add_op2_data(data=data)
        model = None

        fxyz_local, mxyz_local = TransformLoadWRT(fxyz, mxyz, cid0, cid_new,
                                                  model)
        r = array([Lx, Ly, Lz])
        F = array([0., -Fy, 0.])
        M = cross(r, F)
        self.assertTrue(array_equal(fxyz_local, F), 'expected=%s actual=%s' % (F, fxyz_local))
        self.assertTrue(array_equal(mxyz_local, M), 'expected=%s actual=%s' % (M, mxyz_local))
예제 #2
0
    def __init__(self, model):
        """
        Defines the ShellProperties object.

        Parameters
        ----------
        model : BDF
           the BDF object
        """
        VectorizedCard.__init__(self, model)
        float_fmt = self.model.float_fmt

        self.n = 1
        ncards = 1
        origin = [0., 0., 0.]
        zaxis = [0., 0., 1.]
        xzplane = [1., 0., 0.]
        self.coords = {
            0: CORD2R(0, origin, zaxis, xzplane),
        }
        self.coord_id = zeros(ncards, dtype='int32')
        self.Type = full(ncards, 'R',
                         dtype='|U1')  # R-CORD2R, S-CORD2S, C-CORD2C

        self.T = full((ncards, 3, 3), nan, dtype=float_fmt)
        self.T[0, :, :] = eye(3)
        self.origin = zeros((ncards, 3), dtype=float_fmt)
        self.is_resolved = full(ncards, True, dtype='bool')
예제 #3
0
    def test_coord_adding(self):
        origin = [0., 0., 0.]
        zaxis = [0., 0., 1.]
        xzplane = [1., 0., 0.]
        unused_cid1 = CORD2R(cid=1, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane,
                             comment='cord2r')

        xaxis = [1., 0., 0.]
        yaxis = [0., 1., 0.]
        zaxis = [0., 0., 1.]
        xz_plane = [1., 0., 1.]
        yz_plane = [0., 1., 1.]
        xy_plane = [1., 1., 0.]
        # x-axis
        unused_cid2 = CORD2R.add_axes(cid=2, rid=0, origin=origin,
                                      xaxis=xaxis, yaxis=None, zaxis=None,
                                      xyplane=None, yzplane=None, xzplane=xz_plane)

        unused_cid3 = CORD2R.add_axes(cid=2, rid=0, origin=origin,
                                      xaxis=xaxis, yaxis=None, zaxis=None,
                                      xyplane=xy_plane, yzplane=None, xzplane=None)

        # y-axis
        unused_cid4 = CORD2R.add_axes(cid=4, rid=0, origin=origin,
                                      xaxis=None, yaxis=yaxis, zaxis=None,
                                      xyplane=xy_plane, yzplane=None, xzplane=None)

        unused_cid5 = CORD2R.add_axes(cid=5, rid=0, origin=origin,
                                      xaxis=None, yaxis=yaxis, zaxis=None,
                                      xyplane=None, yzplane=yz_plane, xzplane=None)

        # z-axis
        unused_cid4 = CORD2R.add_axes(cid=4, rid=0, origin=origin,
                                      xaxis=None, yaxis=None, zaxis=zaxis,
                                      xyplane=None, yzplane=None, xzplane=xz_plane)

        unused_cid5 = CORD2R.add_axes(cid=5, rid=0, origin=origin,
                                      xaxis=None, yaxis=None, zaxis=zaxis,
                                      xyplane=None, yzplane=yz_plane, xzplane=None)

        # ijk
        unused_cid6 = CORD2R.add_ijk(cid=6, rid=0, origin=origin, i=xaxis, j=yaxis, k=None)
        unused_cid7 = CORD2R.add_ijk(cid=7, rid=0, origin=origin, i=xaxis, j=None, k=zaxis)
        unused_cid8 = CORD2R.add_ijk(cid=8, rid=0, origin=origin, i=None, j=yaxis, k=zaxis)
예제 #4
0
def _cut_model(nids, xyz_cp, edges, view_up, p1, p2, tol,
               nodal_result, plane_atol=1e-5, plane_bdf_filename=None):
    """
    Helper method for cut_edge_model_by_axes

    Parameters
    ----------
    edges : (nedges, 2) int ndarray
        the edges
    view_up : (3,) float ndarray
        the up/z vector
    p1 / p2 : (3,) float ndarray
        the start/end points
    tol : float
        the tolerance to filter edges (using some large value) to prevent
        excessive computations
    plane_atol : float; default=1e-5
        the tolerance for a line that's located on the y=0 local plane
    plane_bdf_filename : str; default=None
        optionally write a BDF of the cut

   Returns
    -------
    local_points_array : (N, 3) float ndarray
        the xyz points in the cutting plane coordinate system
    global_points_array : (N, 3) float ndarray
        the xyz points in the global xyz coordinate system
    result_array : (N, 7) float ndarray
        inid, x, y, z, xg, yg, zg, result

    """
    #view_up = camera.GetViewUp()

    #print('p1 =', p1)
    #print('p2 =', p2)
    z = view_up
    x = p2 - p1
    origin = p1
    #i = x / np.linalg.norm(x)
    #k = z / np.linalg.norm(z)

    # j axis (y direction) is normal to the plane
    #j = np.cross(k, i)
    #print("i = ", i)
    #print("j = ", j)
    #print("k = ", k)

    cid = 1
    zaxis = origin + z
    xzplane = origin + x
    coord = CORD2R(cid, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane,
                   comment='')
    local_points_array, global_points_array, result_array = _cut_edge_model_by_coord(
        nids, xyz_cp, edges, coord, tol, nodal_result,
        plane_atol=plane_atol, plane_bdf_filename=plane_bdf_filename)
    return local_points_array, global_points_array, result_array
예제 #5
0
def _cut_model(nids,
               xyz_cp,
               edges,
               view_up,
               p1,
               p2,
               tol,
               nodal_result,
               plane_atol=1e-5):
    """
    Helper method for cut_edge_model_by_axes

    Parameters
    ----------
    edges : (nedges, 2) int ndarray
        the edges
    view_up : (3,) float ndarray
        the up/z vector
    p1 / p2 : (3,) float ndarray
        the start/end points
    tol : float
        the plane tolerance
    """
    #view_up = camera.GetViewUp()

    #print('p1 =', p1)
    #print('p2 =', p2)
    z = view_up
    x = p2 - p1
    origin = p1
    #i = x / np.linalg.norm(x)
    #k = z / np.linalg.norm(z)

    # j axis (y direction) is normal to the plane
    #j = np.cross(k, i)
    #print("i = ", i)
    #print("j = ", j)
    #print("k = ", k)

    cid = 1
    zaxis = origin + z
    xzplane = origin + x
    coord = CORD2R(cid,
                   rid=0,
                   origin=origin,
                   zaxis=zaxis,
                   xzplane=xzplane,
                   comment='')
    local_points_array, global_points_array, result_array = _cut_edge_model_by_coord(
        nids, xyz_cp, edges, coord, tol, nodal_result, plane_atol=plane_atol)
    return local_points_array, global_points_array, result_array
예제 #6
0
파일: geom1.py 프로젝트: watkinrt/pyNastran
 def _read_cord2r(self, data, n):
     """
     (2101,21,8) - the marker for Record 5
     """
     nentries = (len(data) - n) // 52
     for i in range(nentries):
         edata = data[n:n + 52]  # 13*4
         (cid, one, two, rid, a1, a2, a3, b1, b2, b3, c1,
          c2, c3) = unpack(b(self._endian + '4i9f'), edata)
         assert one == 1, one
         assert two == 2, two
         data_in = [cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3]
         #print("cid=%s rid=%s a1=%s a2=%s a3=%s b1=%s b2=%s b3=%s c1=%s c2=%s c3=%s" %(cid,rid,a1,a2,a3,b1,b2,b3,c1,c2,c3))
         if self.is_debug_file:
             self.binary_debug.write('  CORD2R=%s\n' % data_in)
         coord = CORD2R.add_op2_data(data_in)
         self.add_coord(coord, allow_overwrites=True)
         n += 52
     self._increase_card_count('CORD2R', nentries)
     return n
예제 #7
0
 def _read_cord2r(self, data, n):
     """
     (2101,21,8) - the marker for Record 5
     """
     nentries = (len(data) - n) // 52
     for i in range(nentries):
         edata = data[n:n + 52]  # 13*4
         (cid, one, two, rid, a1, a2, a3, b1, b2, b3, c1, c2,
          c3) = unpack(b(self._endian + '4i9f'), edata)
         assert one == 1, one
         assert two == 2, two
         data_in = [cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3]
         #print("cid=%s rid=%s a1=%s a2=%s a3=%s b1=%s b2=%s b3=%s c1=%s c2=%s c3=%s" %
         #(cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3))
         if self.is_debug_file:
             self.binary_debug.write('  CORD2R=%s\n' % data_in)
         coord = CORD2R.add_op2_data(data_in)
         self._add_coord_object(coord, allow_overwrites=True)
         n += 52
     self._increase_card_count('CORD2R', nentries)
     return n
예제 #8
0
    def test_cord2c_01(self):
        """simple CORD2R/CORD2C input/output test"""
        lines = [
            'CORD2C*                3               0              0.              0.',
            '*                     0.              0.              0.              1.*',
            '*                     1.              0.              1.'
        ]
        model = BDF(debug=False)
        card = model._process_card(lines)
        cardi = BDFCard(card)
        cord2c = CORD2C.add_card(cardi)
        model._add_coord_object(cord2c)

        lines = [
            'CORD2R         4       3     10.      0.      5.     10.     90.      5.',
            '             10.      0.      6.'
        ]
        card = model._process_card(lines)
        cardi = BDFCard(card)
        cord2r = CORD2R.add_card(cardi)
        model._add_coord_object(cord2r)
        model.cross_reference()

        cord2r_b = model.Coord(3)
        self.assertEqual(cord2r_b.Cid(), 3)
        self.assertEqual(cord2r_b.Rid(), 0)

        cord2r_c = model.Coord(4)
        self.assertEqual(cord2r_c.Cid(), 4)
        self.assertEqual(cord2r_c.Rid(), 3)

        self.assertTrue(allclose(cord2r_c.i, array([0., 0., 1.])))
        delta = cord2r_c.j - array([1., 1., 0.]) / 2**0.5
        self.assertTrue(allclose(cord2r_c.j,
                                 array([1., 1., 0.]) / 2**0.5), str(delta))
        delta = cord2r_c.k - array([-1., 1., 0.]) / 2**0.5
        self.assertTrue(allclose(cord2r_c.k,
                                 array([-1., 1., 0.]) / 2**0.5), str(delta))
예제 #9
0
 def _read_cord2r(self, data, n):
     """
     (2101,21,8) - the marker for Record 5
     """
     ntotal = 52 * self.factor # 13*4
     s = Struct(mapfmt(self._endian + b'4i9f', self.size))
     nentries = (len(data) - n) // ntotal
     for unused_i in range(nentries):
         edata = data[n:n + ntotal]
         (cid, one, two, rid, a1, a2, a3, b1, b2, b3, c1,
          c2, c3) = s.unpack(edata)
         assert one == 1, one
         assert two == 2, two
         data_in = [cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3]
         #print("cid=%s rid=%s a1=%s a2=%s a3=%s b1=%s b2=%s b3=%s c1=%s c2=%s c3=%s" %
               #(cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3))
         if self.is_debug_file:
             self.binary_debug.write('  CORD2R=%s\n' % data_in)
         coord = CORD2R.add_op2_data(data_in)
         self._add_coord_object(coord, allow_overwrites=False)
         n += ntotal
     self.increase_card_count('CORD2R', nentries)
     return n
예제 #10
0
    def __init_attributes(self):
        # type: () -> None
        """
        Creates storage objects for the BDF object.
        This would be in the init but doing it this way allows for better
        inheritance

        References:
          1.  http://www.mscsoftware.com/support/library/conf/wuc87/p02387.pdf
        """
        self.bdf_filename = None
        self.punch = None
        self._encoding = None

        #: ignore any ECHOON flags
        self.force_echo_off = True

        #: list of Nastran SYSTEM commands
        self.system_command_lines = []  # type: List[str]

        #: list of execive control deck lines
        self.executive_control_lines = []  # type: List[str]

        #: list of case control deck lines
        self.case_control_lines = []  # type: List[str]

        self._auto_reject = False
        self._solmap_to_value = {
            'NONLIN': 101,  # 66 -> 101 per Reference 1
            'SESTATIC': 101,
            'SESTATICS': 101,
            'SEMODES': 103,
            'BUCKLING': 105,
            'SEBUCKL': 105,
            'NLSTATIC': 106,
            'SEDCEIG': 107,
            'SEDFREQ': 108,
            'SEDTRAN': 109,
            'SEMCEIG': 110,
            'SEMFREQ': 111,
            'SEMTRAN': 112,
            'CYCSTATX': 114,
            'CYCMODE': 115,
            'CYCBUCKL': 116,
            'CYCFREQ': 118,
            'NLTRAN': 129,
            'AESTAT': 144,
            'FLUTTR': 145,
            'SEAERO': 146,
            'NLSCSH': 153,
            'NLTCSH': 159,
            'DBTRANS': 190,
            'DESOPT': 200,

            # guessing
            #'CTRAN' : 115,
            'CFREQ' : 118,

            # solution 200 names
            'STATICS': 101,
            'MODES': 103,
            'BUCK': 105,
            'DFREQ': 108,
            'MFREQ': 111,
            'MTRAN': 112,
            'DCEIG': 107,
            'MCEIG': 110,
            #'HEAT'     : None,
            #'STRUCTURE': None,
            #'DIVERGE'  : None,
            'FLUTTER': 145,
            'SAERO': 146,
        }

        self.rsolmap_to_str = {
            66: 'NONLIN',
            101: 'SESTSTATIC',  # linear static
            103: 'SEMODES',  # modal
            105: 'BUCKLING',  # buckling
            106: 'NLSTATIC',  # non-linear static
            107: 'SEDCEIG',  # direct complex frequency response
            108: 'SEDFREQ',  # direct frequency response
            109: 'SEDTRAN',  # direct transient response
            110: 'SEMCEIG',  # modal complex eigenvalue
            111: 'SEMFREQ',  # modal frequency response
            112: 'SEMTRAN',  # modal transient response
            114: 'CYCSTATX',
            115: 'CYCMODE',
            116: 'CYCBUCKL',
            118: 'CYCFREQ',
            129: 'NLTRAN',  # nonlinear transient
            144: 'AESTAT',  # static aeroelastic
            145: 'FLUTTR',  # flutter/aeroservoelastic
            146: 'SEAERO',  # dynamic aeroelastic
            153: 'NLSCSH',  # nonlinear static thermal
            159: 'NLTCSH',  # nonlinear transient thermal
            190: 'DBTRANS',
            200: 'DESOPT',  # optimization
        }

        # ------------------------ bad duplicates ----------------------------
        self._iparse_errors = 0
        self._nparse_errors = 0
        self._stop_on_parsing_error = True
        self._stop_on_duplicate_error = True
        self._stored_parse_errors = []  # type: List[str]

        self._duplicate_nodes = []  # type: List[str]
        self._duplicate_elements = []  # type: List[str]
        self._duplicate_properties = []  # type: List[str]
        self._duplicate_materials = []  # type: List[str]
        self._duplicate_masses = []  # type: List[str]
        self._duplicate_thermal_materials = []  # type: List[str]
        self._duplicate_coords = []  # type: List[str]
        self.values_to_skip = {}  # type: Dict[str, List[int]]

        # ------------------------ structural defaults -----------------------
        #: the analysis type
        self._sol = None
        #: used in solution 600, method
        self.sol_method = None
        #: the line with SOL on it, marks ???
        self.sol_iline = None  # type : Optional[int]
        self.case_control_deck = None  # type: Optional[Any]

        #: store the PARAM cards
        self.params = {}  # type: Dict[str, Any]
        # ------------------------------- nodes -------------------------------
        # main structural block
        #: stores POINT cards
        self.points = {}  # type: Dict[int, Any]
        self.ringaxs = {}  # type: Dict[int, Any]
        #self.grids = {}

        self.spoints = {}  # type: Dict[int, Any]
        self.epoints = {}  # type: Dict[int, Any]

        #: stores GRIDSET card
        self.grdset = None  # type: Optional[Any]

        #: stores SEQGP cards
        self.seqgp = None  # type: Optional[Any]


        #: stores elements (CQUAD4, CTRIA3, CHEXA8, CTETRA4, CROD, CONROD,
        #: etc.)
        self.elements = {}  # type: Dict[int, Any]

        #: stores CBARAO, CBEAMAO
        self.ao_element_flags = {}  # type: Dict[int, Any]

        #: stores rigid elements (RBE2, RBE3, RJOINT, etc.)
        self.rigid_elements = {}  # type: Dict[int, Any]
        #: stores PLOTELs
        self.plotels = {}  # type: Optional[Any]

        #: stores CONM1, CONM2, CMASS1,CMASS2, CMASS3, CMASS4, CMASS5
        self.masses = {}  # type: Dict[int, Any]
        #: stores PMASS
        self.properties_mass = {}  # type: Dict[int, Any]
        #: stores NSM, NSM1
        self.nsms = {}  # type: Dict[int, List[Any]]

        #: stores LOTS of propeties (PBAR, PBEAM, PSHELL, PCOMP, etc.)
        self.properties = {}  # type: Dict[int, Any]

        #: stores MAT1, MAT2, MAT3, MAT8, MAT10, MAT11
        self.materials = {}  # type: Dict[int, Any]

        #: defines the MAT4, MAT5
        self.thermal_materials = {}  # type: Dict[int, Any]

        #: defines the MATHE, MATHP
        self.hyperelastic_materials = {}  # type: Dict[int, Any]

        #: stores MATSx
        self.MATS1 = {}  # type: Dict[int, Any]
        self.MATS3 = {}  # type: Dict[int, Any]
        self.MATS8 = {}  # type: Dict[int, Any]

        #: stores MATTx
        self.MATT1 = {}  # type: Dict[int, Any]
        self.MATT2 = {}  # type: Dict[int, Any]
        self.MATT3 = {}  # type: Dict[int, Any]
        self.MATT4 = {}  # type: Dict[int, Any]
        self.MATT5 = {}  # type: Dict[int, Any]
        self.MATT8 = {}  # type: Dict[int, Any]
        self.MATT9 = {}  # type: Dict[int, Any]

        #: stores the CREEP card
        self.creep_materials = {}  # type: Dict[int, Any]

        self.tics = {}  # type: Optional[Any]

        # stores DLOAD entries.
        self.dloads = {}    # type: Dict[int, Any]
        # stores ACSRCE, RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE,
        #        and QVECT entries.
        self.dload_entries = {}    # type: Dict[int, Any]

        #self.gusts = {}  # Case Control GUST = 100
        #self.random = {} # Case Control RANDOM = 100

        #: stores coordinate systems
        origin = array([0., 0., 0.])
        zaxis = array([0., 0., 1.])
        xzplane = array([1., 0., 0.])
        coord = CORD2R(cid=0, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane)
        self.coords = {0 : coord}    # type: Dict[int, Any]

        # --------------------------- constraints ----------------------------
        #: stores SUPORT1s
        #self.constraints = {} # suport1, anything else???
        self.suport = []  # type: List[Any]
        self.suport1 = {}  # type: Dict[int, Any]
        self.se_suport = []  # type: List[Any]

        #: stores SPCADD, SPC, SPC1, SPCAX, GMSPC
        self.spcs = {}  # type: Dict[int, List[Any]]
        self.spcadds = {}  # type: Dict[int, List[Any]]

        self.spcoffs = {}  # type: Dict[int, List[Any]]
        self.mpcs = {}  # type: Dict[int, List[Any]]
        self.mpcadds = {}  # type: Dict[int, List[Any]]

        # --------------------------- dynamic ----------------------------
        #: stores DAREA
        self.dareas = {}   # type: Dict[int, Any]
        self.dphases = {}  # type: Dict[int, Any]

        self.pbusht = {}  # type: Dict[int, Any]
        self.pdampt = {}  # type: Dict[int, Any]
        self.pelast = {}  # type: Dict[int, Any]

        #: frequencies
        self.frequencies = {}  # type: Dict[int, List[Any]]

        # ----------------------------------------------------------------
        #: direct matrix input - DMIG
        self.dmis = {}  # type: Dict[str, Any]
        self.dmigs = {}  # type: Dict[str, Any]
        self.dmijs = {}  # type: Dict[str, Any]
        self.dmijis = {}  # type: Dict[str, Any]
        self.dmiks = {}  # type: Dict[str, Any]
        self.dti = {}  # type: Dict[str, Any]
        self._dmig_temp = defaultdict(list)  # type: Dict[str, List[str]]

        # ----------------------------------------------------------------
        #: SETy
        self.sets = {}  # type: Dict[int, Any]
        self.asets = []  # type: List[Any]
        self.bsets = []  # type: List[Any]
        self.csets = []  # type: List[Any]
        self.qsets = []  # type: List[Any]
        self.usets = {}  # type: Dict[str, Any]

        #: SExSETy
        self.se_bsets = []  # type: List[Any]
        self.se_csets = []  # type: List[Any]
        self.se_qsets = []  # type: List[Any]
        self.se_usets = {}  # type: Dict[str, Any]
        self.se_sets = {}  # type: Dict[str, Any]

        # ----------------------------------------------------------------
        #: tables
        # TABLES1, ...
        self.tables = {}  # type: Dict[int, Any]

        # TABLEDx
        self.tables_d = {}  # type: Dict[int, Any]

        # TABLEMx
        self.tables_m = {}  # type: Dict[int, Any]

        #: random_tables
        self.random_tables = {}  # type: Dict[int, Any]
        #: TABDMP1
        self.tables_sdamping = {}  # type: Dict[int, Any]

        # ----------------------------------------------------------------
        #: EIGB, EIGR, EIGRL methods
        self.methods = {}  # type: Dict[int, Any]
        # EIGC, EIGP methods
        self.cMethods = {}  # type: Dict[int, Any]

        # ---------------------------- optimization --------------------------
        # optimization
        self.dconadds = {}  # type: Dict[int, Any]
        self.dconstrs = {}  # type: Dict[int, Any]
        self.desvars = {}  # type: Dict[int, Any]
        self.ddvals = {}  # type: Dict[int, Any]
        self.dlinks = {}  # type: Dict[int, Any]
        self.dresps = {}  # type: Dict[int, Any]

        self.dtable = None  # type: Optional[Any]
        self.dequations = {}  # type: Dict[int, Any]

        #: stores DVPREL1, DVPREL2...might change to DVxRel
        self.dvprels = {}  # type: Dict[int, Any]
        self.dvmrels = {}  # type: Dict[int, Any]
        self.dvcrels = {}  # type: Dict[int, Any]
        self.dvgrids = {}  # type: Dict[int, Any]
        self.doptprm = None  # type: Optional[Any]
        self.dscreen = {}  # type: Dict[int, Any]

        # ------------------------- nonlinear defaults -----------------------
        #: stores NLPCI
        self.nlpcis = {}  # type: Dict[int, Any]
        #: stores NLPARM
        self.nlparms = {}  # type: Dict[int, Any]
        #: stores TSTEPs, TSTEP1s
        self.tsteps = {}  # type: Dict[int, Any]
        #: stores TSTEPNL
        self.tstepnls = {}  # type: Dict[int, Any]
        #: stores TF
        self.transfer_functions = {}  # type: Dict[int, Any]
        #: stores DELAY
        self.delays = {}  # type: Dict[int, Any]

        #: stores ROTORG
        self.rotors = {}  # type: Dict[int, Any]

        # --------------------------- aero defaults --------------------------
        # aero cards
        #: stores CAEROx
        self.caeros = {}  # type: Dict[int, Any]
        #: stores PAEROx
        self.paeros = {}  # type: Dict[int, Any]
        # stores MONPNT1
        self.monitor_points = []  # type: List[Any]

        #: stores AECOMP
        self.aecomps = {}  # type: Dict[int, Any]
        #: stores AEFACT
        self.aefacts = {}  # type: Dict[int, Any]
        #: stores AELINK
        self.aelinks = {}  # type: Dict[int, List[Any]]
        #: stores AELIST
        self.aelists = {}  # type: Dict[int, Any]
        #: stores AEPARAM
        self.aeparams = {}  # type: Dict[int, Any]
        #: stores AESURF
        self.aesurf = {}  # type: Dict[int, Any]
        #: stores AESURFS
        self.aesurfs = {}  # type: Dict[int, Any]
        #: stores AESTAT
        self.aestats = {}  # type: Dict[int, Any]
        #: stores CSSCHD
        self.csschds = {}  # type: Dict[int, Any]

        #: store SPLINE1,SPLINE2,SPLINE4,SPLINE5
        self.splines = {}  # type: Dict[int, Any]

        # axisymmetric
        self.axic = None  # type: Optional[Any]

        # ------ SOL 144 ------
        #: stores AEROS
        self.aeros = None  # type: Optional[Any]

        #: stores TRIM
        self.trims = {}  # type: Dict[int, Any]

        #: stores DIVERG
        self.divergs = {}  # type: Dict[int, Any]

        # ------ SOL 145 ------
        #: stores AERO
        self.aero = None  # type: Optional[Any]

        #: stores FLFACT
        #: .. todo:: can this be simplified ???
        self.flfacts = {}  # type: Dict[int, Any]

        #: stores FLUTTER
        self.flutters = {} # type: Dict[int, Any]

        #: mkaeros
        self.mkaeros = []  # type: List[Any]

        # ------ SOL 146 ------
        #: stores GUST cards
        self.gusts = {}  # type: Dict[int, Any]

        # ------------------------- thermal defaults -------------------------
        # BCs
        #: stores thermal boundary conditions - CONV,RADBC
        self.bcs = {}  # type: Dict[int, Any]

        #: stores PHBDY
        self.phbdys = {}  # type: Dict[int, Any]
        #: stores convection properties - PCONV, PCONVM ???
        self.convection_properties = {}  # type: Dict[int, Any]
        #: stores TEMPD
        self.tempds = {}  # type: Dict[int, Any]

        # -------------------------contact cards-------------------------------
        self.bcrparas = {}  # type: Dict[int, Any]
        self.bctadds = {}  # type: Dict[int, Any]
        self.bctparas = {}  # type: Dict[int, Any]
        self.bctsets = {}  # type: Dict[int, Any]
        self.bsurf = {}  # type: Dict[int, Any]
        self.bsurfs = {}  # type: Dict[int, Any]

        # ---------------------------------------------------------------------
        self._type_to_id_map = defaultdict(list)  # type: Dict[int, List[Any]]
        self._slot_to_type_map = {
            'params' : ['PARAM'],
            'nodes' : ['GRID', 'SPOINT', 'EPOINT'], # 'RINGAX',
            'points' : ['POINT'],
            'ringaxs' : ['RINGAX', 'POINTAX'],
            'axic' : ['AXIC'],
            'grdset' : ['GRDSET'],
            'seqgp' : ['SEQGP'],
            'ao_element_flags' : ['CBARAO'],
            #'POINTAX', 'RINGAX',

            # CMASS4 lies in the QRG
            'masses' : ['CONM1', 'CONM2', 'CMASS1', 'CMASS2', 'CMASS3', 'CMASS4'],

            'elements' : [
                'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4',
                # 'CELAS5',
                'CBUSH', 'CBUSH1D', 'CBUSH2D',

                'CDAMP1', 'CDAMP2', 'CDAMP3', 'CDAMP4', 'CDAMP5',
                'CFAST',

                'CBAR', 'CROD', 'CTUBE', 'CBEAM', 'CBEAM3', 'CONROD', 'CBEND',
                'CTRIA3', 'CTRIA6', 'CTRIAR',
                'CQUAD4', 'CQUAD8', 'CQUADR', 'CQUAD',
                'CPLSTN3', 'CPLSTN6', 'CPLSTN4', 'CPLSTN8',
                'CPLSTS3', 'CPLSTS6', 'CPLSTS4', 'CPLSTS8',
                'CTRAX3', 'CTRAX6', 'CTRIAX', 'CTRIAX6',
                'CQUADX', 'CQUADX4', 'CQUADX8',

                'CTETRA', 'CPYRAM', 'CPENTA', 'CHEXA', 'CIHEX1', 'CIHEX2',
                'CSHEAR', 'CVISC', 'CRAC2D', 'CRAC3D',
                'CGAP',

                # thermal
                'CHBDYE', 'CHBDYG', 'CHBDYP',
            ],
            'nsms' : ['NSM', 'NSM1', 'NSML', 'NSML1', 'NSMADD'],
            'rigid_elements' : ['RBAR', 'RBAR1', 'RBE1', 'RBE2', 'RBE3', 'RROD', 'RSPLINE'],
            'plotels' : ['PLOTEL',],

            'properties_mass' : ['PMASS'],
            'properties' : [
                'PELAS', 'PGAP', 'PFAST', 'PLPLANE', 'PPLANE',
                'PBUSH', 'PBUSH1D',
                'PDAMP', 'PDAMP5',
                'PROD', 'PBAR', 'PBARL', 'PBEAM', 'PTUBE', 'PBEND', 'PBCOMP', 'PBRSECT', 'PBMSECT',
                'PBEAML',  # not fully supported
                # 'PBEAM3',

                'PSHELL', 'PCOMP', 'PCOMPG', 'PSHEAR',
                'PSOLID', 'PLSOLID', 'PVISC', 'PRAC2D', 'PRAC3D',
                'PIHEX', 'PCOMPS',
                'PCONEAX',
            ],
            'pdampt' : ['PDAMPT',],
            'pelast' : ['PELAST',],
            'pbusht' : ['PBUSHT',],

            # materials
            'materials' : ['MAT1', 'MAT2', 'MAT3', 'MAT8', 'MAT9', 'MAT10', 'MAT11',
                           'MAT3D', 'MATG'],
            'hyperelastic_materials' : ['MATHE', 'MATHP',],
            'creep_materials' : ['CREEP'],
            'MATT1' : ['MATT1'],
            'MATT2' : ['MATT2'],
            'MATT3' : ['MATT3'],
            'MATT4' : ['MATT4'], # thermal
            'MATT5' : ['MATT5'], # thermal
            'MATT8' : ['MATT8'],
            'MATT9' : ['MATT9'],
            'MATS1' : ['MATS1'],
            'MATS3' : ['MATS3'],
            'MATS8' : ['MATS8'],

            # 'MATHE'
            #'EQUIV', # testing only, should never be activated...

            # thermal materials
            'thermal_materials' : ['MAT4', 'MAT5',],

            # spc/mpc constraints - TODO: is this correct?
            'spcadds' : ['SPCADD'],
            'spcs' : ['SPC', 'SPC1', 'SPCAX', 'GMSPC'],
            'spcoffs' : ['SPCOFF', 'SPCOFF1'],
            'mpcadds' : ['MPCADD'],
            'mpcs' : ['MPC'],
            'suport' : ['SUPORT'],
            'suport1' : ['SUPORT1'],
            'se_suport' : ['SESUP'],

            # loads
            'load_combinations' : ['LOAD', 'LSEQ'],
            'loads' : [
                'FORCE', 'FORCE1', 'FORCE2',
                'MOMENT', 'MOMENT1', 'MOMENT2',
                'GRAV', 'ACCEL', 'ACCEL1',
                'PLOAD', 'PLOAD1', 'PLOAD2', 'PLOAD4',
                'PLOADX1', 'RFORCE', 'RFORCE1', 'SLOAD',
                'GMLOAD', 'SPCD', 'LOADCYN',

                # thermal
                'TEMP', 'QBDY1', 'QBDY2', 'QBDY3', 'QHBDY',
                'QVOL',
                ],
            'dloads' : ['DLOAD', ],
            # stores RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE entries.
            'dload_entries' : ['ACSRCE', 'TLOAD1', 'TLOAD2', 'RLOAD1', 'RLOAD2',
                               'QVECT', 'RANDPS'],

            # aero cards
            'aero' : ['AERO'],
            'aeros' : ['AEROS'],
            'gusts' : ['GUST'],
            'flutters' : ['FLUTTER'],
            'flfacts' : ['FLFACT'],
            'mkaeros' : ['MKAERO1', 'MKAERO2'],
            'aecomps' : ['AECOMP'],
            'aefacts' : ['AEFACT'],
            'aelinks' : ['AELINK'],
            'aelists' : ['AELIST'],
            'aeparams' : ['AEPARM'],
            'aesurf' : ['AESURF'],
            'aesurfs' : ['AESURFS'],
            'aestats' : ['AESTAT'],
            'caeros' : ['CAERO1', 'CAERO2', 'CAERO3', 'CAERO4', 'CAERO5'],
            'paeros' : ['PAERO1', 'PAERO2', 'PAERO3', 'PAERO4', 'PAERO5'],
            'monitor_points' : ['MONPNT1', 'MONPNT2', 'MONPNT3'],
            'splines' : ['SPLINE1', 'SPLINE2', 'SPLINE4', 'SPLINE5',],
            'csschds' : ['CSSCHD',],
            #'SPLINE3', 'SPLINE6', 'SPLINE7',
            'trims' : ['TRIM',],
            'divergs' : ['DIVERG'],

            # coords
            'coords' : ['CORD1R', 'CORD1C', 'CORD1S',
                        'CORD2R', 'CORD2C', 'CORD2S',
                        'GMCORD'],

            # temperature cards
            'tempds' : ['TEMPD'],

            'phbdys' : ['PHBDY'],
            'convection_properties' : ['PCONV', 'PCONVM'],

            # stores thermal boundary conditions
            'bcs' : ['CONV', 'RADBC', 'RADM'],


            # dynamic cards
            'dareas' : ['DAREA'],
            'tics' : ['TIC'],
            'dphases' : ['DPHASE'],
            'nlparms' : ['NLPARM'],
            'nlpcis' : ['NLPCI'],
            'tsteps' : ['TSTEP'],
            'tstepnls' : ['TSTEPNL', 'TSTEP1'],
            'transfer_functions' : ['TF'],
            'delays' : ['DELAY'],
            'rotors' : ['ROTORG', 'ROTORD'],

            'frequencies' : ['FREQ', 'FREQ1', 'FREQ2', 'FREQ3', 'FREQ4', 'FREQ5'],

            # direct matrix input cards
            'dmigs' : ['DMIG'],
            'dmijs' : ['DMIJ'],
            'dmijis' : ['DMIJI'],
            'dmiks' : ['DMIK'],
            'dmis' : ['DMI'],
            'dti' : ['DTI'],

            # optimzation
            'dequations' : ['DEQATN'],
            'dtable' : ['DTABLE'],
            'dconstrs' : ['DCONSTR', 'DCONADD'],
            'desvars' : ['DESVAR'],
            'ddvals' : ['DDVAL'],
            'dlinks' : ['DLINK'],
            'dresps' : ['DRESP1', 'DRESP2', 'DRESP3',],
            'dvprels' : ['DVPREL1', 'DVPREL2'],
            'dvmrels' : ['DVMREL1', 'DVMREL2'],
            'dvcrels' : ['DVCREL1', 'DVCREL2'],
            'dvgrids' : ['DVGRID'],
            'doptprm' : ['DOPTPRM'],
            'dscreen' : ['DSCREEN'],


            # sets
            'asets' : ['ASET', 'ASET1'],
            'bsets' : ['BSET', 'BSET1',],
            'qsets' : ['QSET', 'QSET1'],
            'csets' : ['CSET', 'CSET1',],
            'usets' : ['USET', 'USET1',],
            'sets' : ['SET1', 'SET3',],

            # super-element sets
            'se_bsets' : ['SEBSET', 'SEBSET1'],
            'se_csets' : ['SECSET', 'SECSET1',],
            'se_qsets' : ['SEQSET', 'SEQSET1'],
            'se_usets' : ['SEUSET', 'SEQSET1'],
            'se_sets' : ['SESET'],
            # SEBSEP

            'tables' : [
                'TABLEHT', 'TABRNDG',
                'TABLES1', 'TABLEST',
                ],
            'tables_d' : ['TABLED1', 'TABLED2', 'TABLED3', 'TABLED4', 'TABLED5'],
            'tables_m' : ['TABLEM1', 'TABLEM2', 'TABLEM3', 'TABLEM4'],
            'tables_sdamping' : ['TABDMP1'],
            'random_tables' : ['TABRND1', 'TABRNDG',],

            # initial conditions - sid (set ID)
            ##'TIC',  (in bdf_tables.py)

            # methods
            'methods' : ['EIGB', 'EIGR', 'EIGRL',],

            # cMethods
            'cMethods' : ['EIGC', 'EIGP',],

            # contact
            'bctparas' : ['BCTPARA'],
            'bcrparas' : ['BCRPARA'],
            'bctadds' : ['BCTADD'],
            'bctsets' : ['BCTSET'],
            'bsurf' : ['BSURF'],
            'bsurfs' : ['BSURFS'],

            ## other
            #'INCLUDE',  # '='
            #'ENDDATA',
        }  # type: Dict[str, List[str]]
        self._type_to_slot_map = self.get_rslot_map()
예제 #11
0
파일: coord.py 프로젝트: hurlei/pyNastran
 def add_cord2r(self, card, comment=''):
     """adds a CORD2R card"""
     coord = CORD2R.add_card(card, comment=comment)
     self.coords[coord.cid] = coord
     self.n += 1
예제 #12
0
    def __init_attributes(self) -> None:
        """
        Creates storage objects for the BDF object.
        This would be in the init but doing it this way allows for better
        inheritance

        References:
          1.  http://www.mscsoftware.com/support/library/conf/wuc87/p02387.pdf
        """
        self.reset_errors()
        self.bdf_filename = None
        self.punch = None
        self._encoding = None
        self._is_long_ids = False # ids > 8 characters

        #: ignore any ECHOON flags
        self.force_echo_off = True

        #: list of Nastran SYSTEM commands
        self.system_command_lines = []  # type: List[str]

        #: list of execive control deck lines
        self.executive_control_lines = []  # type: List[str]

        #: list of case control deck lines
        self.case_control_lines = []  # type: List[str]

        # dictionary of BDFs
        self.superelement_models = {}
        self.initial_superelement_models = []  # the keys before superelement mirroring

        self._auto_reject = False
        self._solmap_to_value = {
            'NONLIN': 101,  # 66 -> 101 per Reference 1
            'SESTATIC': 101,
            'SESTATICS': 101,
            'SEMODES': 103,
            'BUCKLING': 105,
            'SEBUCKL': 105,
            'NLSTATIC': 106,
            'SEDCEIG': 107,
            'SEDFREQ': 108,
            'SEDTRAN': 109,
            'SEMCEIG': 110,
            'SEMFREQ': 111,
            'SEMTRAN': 112,
            'CYCSTATX': 114,
            'CYCMODE': 115,
            'CYCBUCKL': 116,
            'CYCFREQ': 118,
            'NLTRAN': 129,
            'AESTAT': 144,
            'FLUTTR': 145,
            'SEAERO': 146,
            'NLSCSH': 153,
            'NLTCSH': 159,
            'DBTRANS': 190,
            'DESOPT': 200,

            # guessing
            #'CTRAN' : 115,
            'CFREQ' : 118,

            # solution 200 names
            'STATICS': 101,
            'MODES': 103,
            'BUCK': 105,
            'DFREQ': 108,
            'MFREQ': 111,
            'MTRAN': 112,
            'DCEIG': 107,
            'MCEIG': 110,
            #'HEAT'     : None,
            #'STRUCTURE': None,
            #'DIVERGE'  : None,
            'FLUTTER': 145,
            'SAERO': 146,
        }

        self.rsolmap_to_str = {
            66: 'NONLIN',
            101: 'SESTSTATIC',  # linear static
            103: 'SEMODES',   # modal
            105: 'BUCKLING',  # buckling
            106: 'NLSTATIC',  # non-linear static
            107: 'SEDCEIG',  # direct complex frequency response
            108: 'SEDFREQ',  # direct frequency response
            109: 'SEDTRAN',  # direct transient response
            110: 'SEMCEIG',  # modal complex eigenvalue
            111: 'SEMFREQ',  # modal frequency response
            112: 'SEMTRAN',  # modal transient response
            114: 'CYCSTATX',
            115: 'CYCMODE',
            116: 'CYCBUCKL',
            118: 'CYCFREQ',
            129: 'NLTRAN',  # nonlinear transient
            144: 'AESTAT',  # static aeroelastic
            145: 'FLUTTR',  # flutter/aeroservoelastic
            146: 'SEAERO',  # dynamic aeroelastic
            153: 'NLSCSH',  # nonlinear static thermal
            159: 'NLTCSH',  # nonlinear transient thermal
            #187 - Dynamic Design Analysis Method
            190: 'DBTRANS',
            200: 'DESOPT',  # optimization
        }

        # ------------------------ bad duplicates ----------------------------
        self._iparse_errors = 0
        self._nparse_errors = 0
        self._stop_on_parsing_error = True
        self._stop_on_duplicate_error = True
        self._stored_parse_errors = []  # type: List[str]

        self._duplicate_nodes = []  # type: List[str]
        self._duplicate_elements = []  # type: List[str]
        self._duplicate_properties = []  # type: List[str]
        self._duplicate_materials = []  # type: List[str]
        self._duplicate_masses = []  # type: List[str]
        self._duplicate_thermal_materials = []  # type: List[str]
        self._duplicate_coords = []  # type: List[str]
        self.values_to_skip = {}  # type: Dict[str, List[int]]

        # ------------------------ structural defaults -----------------------
        #: the analysis type
        self._sol = None
        #: used in solution 600, method
        self.sol_method = None
        #: the line with SOL on it, marks ???
        self.sol_iline = None  # type : Optional[int]
        self.case_control_deck = None  # type: Optional[Any]

        #: store the PARAM cards
        self.params = {}  # type: Dict[str, Any]
        # ------------------------------- nodes -------------------------------
        # main structural block
        #: stores POINT cards
        self.points = {}  # type: Dict[int, Any]
        #self.grids = {}

        self.spoints = {}  # type: Dict[int, Any]
        self.epoints = {}  # type: Dict[int, Any]

        #: stores GRIDSET card
        self.grdset = None  # type: Optional[Any]

        #: stores SEQGP cards
        self.seqgp = None  # type: Optional[Any]

        ## stores RINGAX
        self.ringaxs = {}  # type: Dict[int, Any]

        ## stores GRIDB
        self.gridb = {}  # type: Dict[int, Any]

        #: stores elements (CQUAD4, CTRIA3, CHEXA8, CTETRA4, CROD, CONROD,
        #: etc.)
        self.elements = {}  # type: Dict[int, Any]

        #: stores CBARAO, CBEAMAO
        self.ao_element_flags = {}  # type: Dict[int, Any]
        #: stores BAROR
        self.baror = None  # type: Optional[Any]
        #: stores BEAMOR
        self.beamor = None  # type: Optional[Any]
        #: stores SNORM
        self.normals = {}  # type: Dict[int, Any]

        #: stores rigid elements (RBE2, RBE3, RJOINT, etc.)
        self.rigid_elements = {}  # type: Dict[int, Any]
        #: stores PLOTELs
        self.plotels = {}  # type: Optional[Any]

        #: stores CONM1, CONM2, CMASS1,CMASS2, CMASS3, CMASS4, CMASS5
        self.masses = {}  # type: Dict[int, Any]
        #: stores PMASS
        self.properties_mass = {}  # type: Dict[int, Any]

        #: stores NSM, NSM1, NSML, NSML1
        self.nsms = {}  # type: Dict[int, List[Any]]
        #: stores NSMADD
        self.nsmadds = {}  # type: Dict[int, List[Any]]

        #: stores LOTS of propeties (PBAR, PBEAM, PSHELL, PCOMP, etc.)
        self.properties = {}  # type: Dict[int, Any]

        #: stores MAT1, MAT2, MAT3, MAT8, MAT10, MAT11
        self.materials = {}  # type: Dict[int, Any]

        #: defines the MAT4, MAT5
        self.thermal_materials = {}  # type: Dict[int, Any]

        #: defines the MATHE, MATHP
        self.hyperelastic_materials = {}  # type: Dict[int, Any]

        #: stores MATSx
        self.MATS1 = {}  # type: Dict[int, Any]
        self.MATS3 = {}  # type: Dict[int, Any]
        self.MATS8 = {}  # type: Dict[int, Any]

        #: stores MATTx
        self.MATT1 = {}  # type: Dict[int, Any]
        self.MATT2 = {}  # type: Dict[int, Any]
        self.MATT3 = {}  # type: Dict[int, Any]
        self.MATT4 = {}  # type: Dict[int, Any]
        self.MATT5 = {}  # type: Dict[int, Any]
        self.MATT8 = {}  # type: Dict[int, Any]
        self.MATT9 = {}  # type: Dict[int, Any]
        self.nxstrats = {}  # type: Dict[int, Any]

        #: stores the CREEP card
        self.creep_materials = {}  # type: Dict[int, Any]

        self.tics = {}  # type: Optional[Any]

        # stores DLOAD entries.
        self.dloads = {}    # type: Dict[int, Any]
        # stores ACSRCE, RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE,
        #        and QVECT entries.
        self.dload_entries = {}    # type: Dict[int, Any]

        #self.gusts = {}  # Case Control GUST = 100
        #self.random = {} # Case Control RANDOM = 100

        #: stores coordinate systems
        origin = array([0., 0., 0.])
        zaxis = array([0., 0., 1.])
        xzplane = array([1., 0., 0.])
        coord = CORD2R(cid=0, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane)
        self.coords = {0 : coord}   # type: Dict[int, Any]

        # --------------------------- constraints ----------------------------
        #: stores SUPORT1s
        #self.constraints = {} # suport1, anything else???
        self.suport = []  # type: List[Any]
        self.suport1 = {}  # type: Dict[int, Any]
        self.se_suport = []  # type: List[Any]

        #: stores SPC, SPC1, SPCAX, GMSPC
        self.spcs = {}  # type: Dict[int, List[Any]]
        #: stores SPCADD
        self.spcadds = {}  # type: Dict[int, List[Any]]
        self.spcoffs = {}  # type: Dict[int, List[Any]]

        self.mpcs = {}  # type: Dict[int, List[Any]]
        self.mpcadds = {}  # type: Dict[int, List[Any]]

        # --------------------------- dynamic ----------------------------
        #: stores DAREA
        self.dareas = {}   # type: Dict[int, Any]
        self.dphases = {}  # type: Dict[int, Any]

        self.pbusht = {}  # type: Dict[int, Any]
        self.pdampt = {}  # type: Dict[int, Any]
        self.pelast = {}  # type: Dict[int, Any]

        #: frequencies
        self.frequencies = {}  # type: Dict[int, List[Any]]

        # ----------------------------------------------------------------
        #: direct matrix input - DMIG
        self.dmi = {}  # type: Dict[str, Any]
        self.dmig = {}  # type: Dict[str, Any]
        self.dmij = {}  # type: Dict[str, Any]
        self.dmiji = {}  # type: Dict[str, Any]
        self.dmik = {}  # type: Dict[str, Any]
        self.dmiax = {}  # type: Dict[str, Any]
        self.dti = {}  # type: Dict[str, Any]
        self._dmig_temp = defaultdict(list)  # type: Dict[str, List[str]]

        # ----------------------------------------------------------------
        #: SETy
        self.sets = {}  # type: Dict[int, Any]
        self.asets = []  # type: List[Any]
        self.omits = []  # type: List[Any]
        self.bsets = []  # type: List[Any]
        self.csets = []  # type: List[Any]
        self.qsets = []  # type: List[Any]
        self.usets = {}  # type: Dict[str, Any]

        #: SExSETy
        self.se_bsets = []  # type: List[Any]
        self.se_csets = []  # type: List[Any]
        self.se_qsets = []  # type: List[Any]
        self.se_usets = {}  # type: Dict[str, Any]
        self.se_sets = {}  # type: Dict[str, Any]

        # ----------------------------------------------------------------
        #: parametric
        self.pset = {}
        self.pval = {}
        self.gmcurv = {}
        self.gmsurf = {}
        self.feedge = {}
        self.feface = {}

        # ----------------------------------------------------------------
        #: tables
        # TABLES1, ...
        self.tables = {}  # type: Dict[int, TABLES1]

        # TABLEDx
        self.tables_d = {}  # type: Dict[int, Union[TABLED1, TABLED2, TABLED3, TABLED4]]

        # TABLEMx
        self.tables_m = {}  # type: Dict[int, Union[TABLEM1, TABLEM2, TABLEM3, TABLEM4]]

        #: random_tables
        self.random_tables = {}  # type: Dict[int, Any]
        #: TABDMP1
        self.tables_sdamping = {}  # type: Dict[int, TABDMP1]

        # ----------------------------------------------------------------
        #: EIGB, EIGR, EIGRL methods
        self.methods = {}  # type: Dict[int, Union[EIGR, EIGRL, EIGB]]
        # EIGC, EIGP methods
        self.cMethods = {}  # type: Dict[int, Union[EIGC, EIGP]]

        # ---------------------------- optimization --------------------------
        # optimization
        self.dconadds = {}  # type: Dict[int, DCONADD]
        self.dconstrs = {}  # type: Dict[int, DCONSTR]
        self.desvars = {}  # type: Dict[int, DESVAR]
        self.topvar = {}  # type: Dict[int, TOPVAR]
        self.ddvals = {}  # type: Dict[int, DDVAL]
        self.dlinks = {}  # type: Dict[int, DLINK]
        self.dresps = {}  # type: Dict[int, Union[DRESP1, DRESP2, DRESP3]]

        self.dtable = None  # type: Optional[DTABLE]
        self.dequations = {}  # type: Dict[int, DEQATN]

        #: stores DVPREL1, DVPREL2...might change to DVxRel
        self.dvprels = {}  # type: Dict[int, Union[DVPREL1, DVPREL2]]
        self.dvmrels = {}  # type: Dict[int, Union[DVMREL1, DVMREL2]]
        self.dvcrels = {}  # type: Dict[int, Union[DVCREL1, DVCREL2]]
        self.dvgrids = {}  # type: Dict[int, DVGRID]
        self.doptprm = None  # type: Optional[DOPTPRM]
        self.dscreen = {}  # type: Dict[int, DSCREEN]

        # ------------------------- nonlinear defaults -----------------------
        #: stores NLPCI
        self.nlpcis = {}  # type: Dict[int, NLPCI]
        #: stores NLPARM
        self.nlparms = {}  # type: Dict[int, NLPARM]
        #: stores TSTEPs, TSTEP1s
        self.tsteps = {}  # type: Dict[int, Union[TSTEP, TSTEP1]]
        #: stores TSTEPNL
        self.tstepnls = {}  # type: Dict[int, TSTEPNL]
        #: stores TF
        self.transfer_functions = {}  # type: Dict[int, TF]
        #: stores DELAY
        self.delays = {}  # type: Dict[int, DELAY]

        #: stores ROTORD, ROTORG
        self.rotors = {}  # type: Dict[int, Union[ROTORD, ROTORG]]

        # --------------------------- aero defaults --------------------------
        # aero cards
        #: stores CAEROx
        self.caeros = {}  # type: Dict[int, Union[CAERO1, CAERO2, CAERO3, CAERO4, CAERO5]]
        #: stores PAEROx
        self.paeros = {}  # type: Dict[int, Union[PAERO1, PAERO2, PAERO3, PAERO4, PAERO5]]
        # stores MONPNT1
        self.monitor_points = []  # type: List[Union[MONPNT1, MONPNT2, MONPNT3]]

        #: stores AECOMP
        self.aecomps = {}  # type: Dict[int, AECOMP]
        #: stores AEFACT
        self.aefacts = {}  # type: Dict[int, AEFACT]
        #: stores AELINK
        self.aelinks = {}  # type: Dict[int, List[AELINK]]
        #: stores AELIST
        self.aelists = {}  # type: Dict[int, AELIST]
        #: stores AEPARAM
        self.aeparams = {}  # type: Dict[int, AEPARAM]
        #: stores AESURF
        self.aesurf = {}  # type: Dict[int, AESURF]
        #: stores AESURFS
        self.aesurfs = {}  # type: Dict[int, AESURFS]
        #: stores AESTAT
        self.aestats = {}  # type: Dict[int, AESTAT]
        #: stores CSSCHD
        self.csschds = {}  # type: Dict[int, CSSCHD]

        #: store SPLINE1,SPLINE2,SPLINE4,SPLINE5
        self.splines = {}  # type: Dict[int, Union[SPLINE1, SPLINE2, SPLINE3, SPLINE4, SPLINE5]]
        self.zona = ZONA(self)

        # axisymmetric
        self.axic = None  # type: Optional[AXIC]
        self.axif = None  # type: Optional[AXIF]
        self.ringfl = {}  # type: Dict[int, RINGFL]
        self._is_axis_symmetric = False

        # cyclic
        self.cyax = None  # type: Optional[CYAX]
        self.cyjoin = {}  # type: Dict[int, CYJOIN]

        self.modtrak = None  # type: Optional[MODTRAK]

        # acoustic
        self.acmodl = None

        # ------ SOL 144 ------
        #: stores AEROS
        self.aeros = None  # type: Optional[AEROS]

        #: stores TRIM, TRIM2
        self.trims = {}  # type: Dict[int, Union[TRIM, TRIM2]]

        #: stores DIVERG
        self.divergs = {}  # type: Dict[int, DIVERG]

        # ------ SOL 145 ------
        #: stores AERO
        self.aero = None  # type: Optional[AERO]

        #: stores FLFACT
        self.flfacts = {}  # type: Dict[int, FLFACT]

        #: stores FLUTTER
        self.flutters = {} # type: Dict[int, FLUTTER]

        #: mkaeros
        self.mkaeros = []  # type: List[Union[MKAERO1,MKAERO2]]

        # ------ SOL 146 ------
        #: stores GUST cards
        self.gusts = {}  # type: Dict[int, GUST]

        # ------------------------- thermal defaults -------------------------
        # BCs
        #: stores thermal boundary conditions - CONV,RADBC
        self.bcs = {}  # type: Dict[int, Union[CONV, RADBC]]

        #: stores PHBDY
        self.phbdys = {}  # type: Dict[int, PHBDY]
        #: stores convection properties - PCONV, PCONVM ???
        self.convection_properties = {}  # type: Dict[int, Union[PCONV, PCONVM]]
        #: stores TEMPD
        self.tempds = {}  # type: Dict[int, TEMPD]

        #: stores VIEW
        self.views = {}  # type: Dict[int, VIEW]
        #: stores VIEW3D
        self.view3ds = {}  # type: Dict[int, VIEW3D]
        self.radset = None
        self.radcavs = {}  # type: Dict[int, RADCAV]
        self.radmtx = {}  # type: Dict[int, RADMTX]

        # -------------------------contact cards-------------------------------
        self.bcrparas = {}  # type: Dict[int, BCRPARA]
        self.bctadds = {}  # type: Dict[int, BCTADD]
        self.bctparas = {}  # type: Dict[int, BCTPARA]
        self.bctsets = {}  # type: Dict[int, BCTSET]
        self.bsurf = {}  # type: Dict[int, BSURF]
        self.bsurfs = {}  # type: Dict[int, BSURFS]
        self.bconp = {}  # type: Dict[int, BCONP]
        self.blseg = {}  # type: Dict[int, BLSEG]
        self.bfric = {}  # type: Dict[int, BFRIC]


        #--------------------------superelements------------------------------
        self.setree = {}  # type: Dict[int, SETREE]
        self.senqset = {}  # type: Dict[int, Union[SENQSET, SENQSET1]]
        self.sebulk = {}  # type: Dict[int, SEBULK]
        self.sebndry = {}  # type: Dict[int, SEBNDRY]
        self.release = {}  # type: Dict[int, RELEASE]
        self.seloc = {}  # type: Dict[int, SELOC]
        self.sempln = {}  # type: Dict[int, SEMPLN]
        self.seconct = {}  # type: Dict[int, SECONCT]
        self.selabel = {}  # type: Dict[int, SELABEL]
        self.seexcld = {}  # type: Dict[int, SEEXCLD]
        self.seelt = {}  # type: Dict[int, SEELT]
        self.seload = {}  # type: Dict[int, SELOAD]
        self.csuper = {}  # type: Dict[int, CSUPER]
        self.csupext = {}  # type: Dict[int, CSUPEXT]

        # ---------------------------------------------------------------------
        self._type_to_id_map = defaultdict(list)  # type: Dict[int, List[Any]]
        self._slot_to_type_map = {
            'params' : ['PARAM'],
            'nodes' : ['GRID', 'SPOINT', 'EPOINT'], # 'RINGAX',
            'points' : ['POINT'],
            'ringaxs' : ['RINGAX', 'POINTAX'],
            'ringfl' : ['RINGFL'],
            'axic' : ['AXIC'],
            'axif' : ['AXIF'],
            'acmodl' : ['ACMODL'],
            'grdset' : ['GRDSET'],
            'gridb' : ['GRIDB'],
            'seqgp' : ['SEQGP'],
            'ao_element_flags' : ['CBARAO'],
            #'POINTAX', 'RINGAX',

            # CMASS4 lies in the QRG
            'masses' : ['CONM1', 'CONM2', 'CMASS1', 'CMASS2', 'CMASS3', 'CMASS4'],

            'elements' : [
                'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4',
                # 'CELAS5',
                'CBUSH', 'CBUSH1D', 'CBUSH2D',

                'CDAMP1', 'CDAMP2', 'CDAMP3', 'CDAMP4', 'CDAMP5',
                'CFAST', 'GENEL',

                'CBAR', 'CROD', 'CTUBE', 'CBEAM', 'CBEAM3', 'CONROD', 'CBEND',
                'CTRIA3', 'CTRIA6', 'CTRIAR',
                'CQUAD4', 'CQUAD8', 'CQUADR', 'CQUAD',
                'CPLSTN3', 'CPLSTN6', 'CPLSTN4', 'CPLSTN8',
                'CPLSTS3', 'CPLSTS6', 'CPLSTS4', 'CPLSTS8',
                'CTRAX3', 'CTRAX6', 'CTRIAX', 'CTRIAX6',
                'CQUADX', 'CQUADX4', 'CQUADX8',
                'CCONEAX',

                'CTETRA', 'CPYRAM', 'CPENTA', 'CHEXA', 'CIHEX1', 'CIHEX2',
                'CSHEAR', 'CVISC', 'CRAC2D', 'CRAC3D',
                'CGAP',

                # thermal
                'CHBDYE', 'CHBDYG', 'CHBDYP',

                # acoustic
                'CHACAB', 'CAABSF', 'CHACBR',
            ],
            'normals' : ['SNORM'],
            'nsms' : ['NSM', 'NSM1', 'NSML', 'NSML1'],
            'nsmadds' : ['NSMADD'],
            'rigid_elements' : ['RBAR', 'RBAR1', 'RBE1', 'RBE2', 'RBE3', 'RROD', 'RSPLINE', 'RSSCON'],
            'plotels' : ['PLOTEL'],

            'properties_mass' : ['PMASS'],
            #'properties_acoustic' : ['PACABS'],
            'properties' : [
                #  acoustic
                'PACABS', 'PAABSF', 'PACBAR',

                # 0d
                'PELAS', 'PGAP', 'PFAST',
                'PBUSH', 'PBUSH1D',
                'PDAMP', 'PDAMP5',

                # 1d
                'PROD', 'PBAR', 'PBARL', 'PBEAM', 'PTUBE', 'PBEND', 'PBCOMP', 'PBRSECT', 'PBMSECT',
                'PBEAML',  # not fully supported
                'PBEAM3',

                # 2d
                'PLPLANE', 'PPLANE',
                'PSHELL', 'PCOMP', 'PCOMPG', 'PSHEAR',
                'PSOLID', 'PLSOLID', 'PVISC', 'PRAC2D', 'PRAC3D',
                'PIHEX', 'PCOMPS',
                'PCONEAX',
            ],
            'pdampt' : ['PDAMPT'],
            'pelast' : ['PELAST'],
            'pbusht' : ['PBUSHT'],

            # materials
            'materials' : ['MAT1', 'MAT2', 'MAT3', 'MAT8', 'MAT9', 'MAT10', 'MAT11',
                           'MAT3D', 'MATG'],
            'hyperelastic_materials' : ['MATHE', 'MATHP'],
            'creep_materials' : ['CREEP'],
            'MATT1' : ['MATT1'],
            'MATT2' : ['MATT2'],
            'MATT3' : ['MATT3'],
            'MATT4' : ['MATT4'], # thermal
            'MATT5' : ['MATT5'], # thermal
            'MATT8' : ['MATT8'],
            'MATT9' : ['MATT9'],
            'MATS1' : ['MATS1'],
            'MATS3' : ['MATS3'],
            'MATS8' : ['MATS8'],
            'nxstrats' : ['NXSTRAT'],

            # 'MATHE'
            #'EQUIV', # testing only, should never be activated...

            # thermal materials
            'thermal_materials' : ['MAT4', 'MAT5'],

            # spc/mpc constraints - TODO: is this correct?
            'spcadds' : ['SPCADD'],
            'spcs' : ['SPC', 'SPC1', 'SPCAX', 'GMSPC'],
            'spcoffs' : ['SPCOFF', 'SPCOFF1'],
            'mpcadds' : ['MPCADD'],
            'mpcs' : ['MPC'],
            'suport' : ['SUPORT'],
            'suport1' : ['SUPORT1'],
            'se_suport' : ['SESUP'],

            'setree' : ['SETREE'],
            'senqset' : ['SENQSET'],
            'sebulk' : ['SEBULK'],
            'sebndry' : ['SEBNDRY'],
            'release' : ['RELEASE'],
            'seloc' : ['SELOC'],
            'sempln' : ['SEMPLN'],
            'seconct' : ['SECONCT'],
            'selabel' : ['SELABEL'],
            'seexcld' : ['SEEXCLD'],
            'seelt' : ['SEELT'],
            'seload' : ['SELOAD'],
            'csuper' : ['CSUPER'],
            'csupext' : ['CSUPEXT'],

            # loads
            'load_combinations' : ['LOAD', 'LSEQ', 'CLOAD'],
            'loads' : [
                'FORCE', 'FORCE1', 'FORCE2',
                'MOMENT', 'MOMENT1', 'MOMENT2',
                'GRAV', 'ACCEL', 'ACCEL1',
                'PLOAD', 'PLOAD1', 'PLOAD2', 'PLOAD4',
                'RFORCE', 'RFORCE1', 'SLOAD',
                'GMLOAD', 'SPCD', 'LOADCYN', 'LOADCYH', 'DEFORM',

                # thermal
                'TEMP', 'TEMPB3', 'TEMPRB',
                'QBDY1', 'QBDY2', 'QBDY3', 'QHBDY', 'QVOL',

                # axisymmetric
                'PLOADX1', 'FORCEAX', 'PRESAX', 'TEMPAX',
                ],
            'cyjoin' : ['CYJOIN'],
            'cyax' : ['CYAX'],
            'modtrak' : ['MODTRAK'],
            'dloads' : ['DLOAD'],
            # stores RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE entries.
            'dload_entries' : ['ACSRCE', 'TLOAD1', 'TLOAD2', 'RLOAD1', 'RLOAD2',
                               'QVECT', 'RANDPS', 'RANDT1'],

            # aero cards
            'aero' : ['AERO'],
            'aeros' : ['AEROS'],
            'gusts' : ['GUST', 'GUST2'],
            'flutters' : ['FLUTTER'],
            'flfacts' : ['FLFACT'],
            'mkaeros' : ['MKAERO1', 'MKAERO2'],
            'aecomps' : ['AECOMP', 'AECOMPL'],
            'aefacts' : ['AEFACT'],
            'aelinks' : ['AELINK'],
            'aelists' : ['AELIST'],
            'aeparams' : ['AEPARM'],
            'aesurf' : ['AESURF'],
            'aesurfs' : ['AESURFS'],
            'aestats' : ['AESTAT'],
            'caeros' : ['CAERO1', 'CAERO2', 'CAERO3', 'CAERO4', 'CAERO5', 'CAERO7', 'BODY7'],
            'paeros' : ['PAERO1', 'PAERO2', 'PAERO3', 'PAERO4', 'PAERO5', 'SEGMESH'],
            'monitor_points' : ['MONPNT1', 'MONPNT2', 'MONPNT3', 'MONDSP1'],
            'splines' : ['SPLINE1', 'SPLINE2', 'SPLINE3', 'SPLINE4', 'SPLINE5', 'SPLINE6', 'SPLINE7'],
            'panlsts' : ['PANLST1', 'PANLST2', 'PANLST3'],
            'csschds' : ['CSSCHD',],
            #'SPLINE3', 'SPLINE6', 'SPLINE7',
            'trims' : ['TRIM', 'TRIM2'],
            'divergs' : ['DIVERG'],

            # coords
            'coords' : ['CORD1R', 'CORD1C', 'CORD1S',
                        'CORD2R', 'CORD2C', 'CORD2S',
                        'GMCORD', 'ACOORD', 'CORD3G'],

            # temperature cards
            'tempds' : ['TEMPD'],

            'phbdys' : ['PHBDY'],
            'convection_properties' : ['PCONV', 'PCONVM'],

            # stores thermal boundary conditions
            'bcs' : ['CONV', 'CONVM', 'RADBC', 'RADM', 'TEMPBC'],


            # dynamic cards
            'dareas' : ['DAREA'],
            'tics' : ['TIC'],
            'dphases' : ['DPHASE'],
            'nlparms' : ['NLPARM'],
            'nlpcis' : ['NLPCI'],
            'tsteps' : ['TSTEP'],
            'tstepnls' : ['TSTEPNL', 'TSTEP1'],
            'transfer_functions' : ['TF'],
            'delays' : ['DELAY'],
            'rotors' : ['ROTORG', 'ROTORD'],

            'frequencies' : ['FREQ', 'FREQ1', 'FREQ2', 'FREQ3', 'FREQ4', 'FREQ5'],

            # direct matrix input cards
            'dmig' : ['DMIG'],
            'dmiax' : ['DMIAX'],
            'dmij' : ['DMIJ'],
            'dmiji' : ['DMIJI'],
            'dmik' : ['DMIK'],
            'dmi' : ['DMI'],
            'dti' : ['DTI'],

            # optimzation
            'dequations' : ['DEQATN'],
            'dtable' : ['DTABLE'],
            'dconstrs' : ['DCONSTR', 'DCONADD'],
            'desvars' : ['DESVAR'],
            'topvar' : ['TOPVAR'],
            'ddvals' : ['DDVAL'],
            'dlinks' : ['DLINK'],
            'dresps' : ['DRESP1', 'DRESP2', 'DRESP3'],
            'dvprels' : ['DVPREL1', 'DVPREL2'],
            'dvmrels' : ['DVMREL1', 'DVMREL2'],
            'dvcrels' : ['DVCREL1', 'DVCREL2'],
            'dvgrids' : ['DVGRID'],
            'doptprm' : ['DOPTPRM'],
            'dscreen' : ['DSCREEN'],


            # sets
            'asets' : ['ASET', 'ASET1'],
            'omits' : ['OMIT', 'OMIT1'],
            'bsets' : ['BSET', 'BSET1'],
            'qsets' : ['QSET', 'QSET1'],
            'csets' : ['CSET', 'CSET1'],
            'usets' : ['USET', 'USET1'],
            'sets' : ['SET1', 'SET3'],

            # super-element sets
            'se_bsets' : ['SEBSET', 'SEBSET1'],
            'se_csets' : ['SECSET', 'SECSET1'],
            'se_qsets' : ['SEQSET', 'SEQSET1'],
            'se_usets' : ['SEUSET', 'SEQSET1'],
            'se_sets' : ['SESET'],
            'radset' : ['RADSET'],
            'radcavs' : ['RADCAV', 'RADLST'],
            'radmtx' : ['RADMTX'],
            # SEBSEP

            # parametric
            'pset' : ['PSET'],
            'pval' : ['PVAL'],
            'gmcurv' : ['GMCURV'],
            'gmsurf' : ['GMSURF'],
            'feedge' : ['FEEDGE'],
            'feface' : ['FEFACE'],

            # tables
            'tables' : [
                'TABLEH1', 'TABLEHT',
                'TABLES1', 'TABLEST',
                ],
            'tables_d' : ['TABLED1', 'TABLED2', 'TABLED3', 'TABLED4', 'TABLED5'],
            'tables_m' : ['TABLEM1', 'TABLEM2', 'TABLEM3', 'TABLEM4'],
            'tables_sdamping' : ['TABDMP1'],
            'random_tables' : ['TABRND1', 'TABRNDG'],

            # initial conditions - sid (set ID)
            ##'TIC',  (in bdf_tables.py)

            # methods
            'methods' : ['EIGB', 'EIGR', 'EIGRL'],

            # cMethods
            'cMethods' : ['EIGC', 'EIGP'],

            # contact
            'bctparas' : ['BCTPARA'],
            'bcrparas' : ['BCRPARA'],
            'bctadds' : ['BCTADD'],
            'bctsets' : ['BCTSET'],
            'bsurf' : ['BSURF'],
            'bsurfs' : ['BSURFS'],
            'bconp' : ['BCONP'],
            'blseg' : ['BLSEG'],
            'bfric' : ['BFRIC'],
            'views' : ['VIEW'],
            'view3ds' : ['VIEW3D'],

            ## other
            #'INCLUDE',  # '='
            #'ENDDATA',
        }  # type: Dict[str, List[str]]
        self._type_to_slot_map = self.get_rslot_map()
    def plot_shear_moment_torque(self,
                                 model_name,
                                 gpforce,
                                 p1,
                                 p2,
                                 p3,
                                 zaxis,
                                 method='Z-Axis Projection',
                                 cid_p1=0,
                                 cid_p2=0,
                                 cid_p3=0,
                                 cid_zaxis=0,
                                 nplanes=20,
                                 plane_color=None,
                                 plane_opacity=0.5,
                                 csv_filename=None,
                                 show=True):
        """Creates a shear moment torque plot for the active plot result"""
        log = self.gui.log
        if plane_color is None:
            plane_color = PURPLE_FLOAT
        assert len(plane_color) == 3, plane_color

        model = self.gui.models[model_name]
        out = model.get_displacement_index_xyz_cp_cd()
        icd_transform, icp_transform, xyz_cp, nid_cp_cd = out
        nids = nid_cp_cd[:, 0]
        nid_cd = nid_cp_cd[:, [0, 2]]
        xyz_cid0 = model.transform_xyzcp_to_xyz_cid(xyz_cp,
                                                    nids,
                                                    icp_transform,
                                                    cid=0)

        #xyz_min, xyz_max = model.xyz_limits
        xyz_min = xyz_cid0.min(axis=0)
        xyz_max = xyz_cid0.max(axis=0)
        assert len(xyz_min) == 3, xyz_min

        dxyz = np.abs(xyz_max - xyz_min)
        dim_max = dxyz.max()
        izero = np.where(dxyz == 0)
        dxyz[izero] = dim_max

        xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r(
            model,
            p1,
            p2,
            zaxis,
            cid_p1=cid_p1,
            cid_p2=cid_p2,
            cid_zaxis=cid_zaxis,
            method=method)
        xyz3 = model.coords[cid_p3].transform_node_to_global(p3)
        dx = xyz3[0] - xyz1[0]
        stations = np.linspace(0., dx, num=nplanes, endpoint=True)
        x = stations

        try:
            # i/j/k vector is nan
            coord = CORD2R(1,
                           rid=0,
                           origin=origin,
                           zaxis=zaxis,
                           xzplane=xzplane,
                           comment='')
        except:
            log.error(
                'The coordinate system is invalid; check your cutting plane.')
            return None, None
        origin = coord.origin
        beta = coord.beta().T

        cid = ''
        self.gui.create_coordinate_system(cid,
                                          dim_max,
                                          label='%s' % cid,
                                          origin=origin,
                                          matrix_3x3=beta,
                                          coord_type='xyz')

        plane_actor = self.gui._create_plane_actor_from_points(
            xyz1, xyz2, i, k, dim_max, actor_name='smt_plane')
        props = self.gui.geometry_properties['smt_plane']
        props.set_color(plane_color)
        props.opacity = plane_opacity
        prop = plane_actor.GetProperty()
        prop.SetColor(*plane_color)
        prop.SetOpacity(plane_opacity)  # 0=transparent, 1=solid
        plane_actor.VisibilityOn()

        if 0:
            point_actor = self.gui.create_point_actor_from_points(
                [xyz1, xyz3], point_size=8, actor_name='smt_points')
            prop = point_actor.GetProperty()
            prop.SetColor(*plane_color)
            prop.SetOpacity(plane_opacity)  # 0=transparent, 1=solid
            point_actor.VisibilityOn()
        self.gui.rend.Render()
        self.gui.Render()

        eids, element_centroids_cid0 = get_element_centriods(model)
        force_sum, moment_sum = gpforce.shear_moment_diagram(
            xyz_cid0,
            eids,
            nids,
            icd_transform,
            element_centroids_cid0,
            model.coords,
            nid_cd,
            stations,
            coord,
            idir=0,
            itime=0,
            debug=False,
            logger=log)
        plot_smt(x, force_sum, moment_sum, show=show)
        return force_sum, moment_sum
예제 #14
0
def get_stations(model: BDF,
                 p1,
                 p2,
                 p3,
                 zaxis,
                 method: str = 'Z-Axis Projection',
                 cid_p1: int = 0,
                 cid_p2: int = 0,
                 cid_p3: int = 0,
                 cid_zaxis: int = 0,
                 idir: int = 0,
                 nplanes: int = 20) -> Tuple[NDArray3float, NDArray3float, ]:
    """
    Gets the axial stations

    Parameters
    ----------
    p1: (3,) float ndarray
        defines the starting point for the shear, moment, torque plot
    p3: (3,) float ndarray
        defines the end point for the shear, moment, torque plot
    p2: (3,) float ndarray
        defines the XZ plane for the shears/moments
    zaxis: (3,) float ndarray
        the direction of the z-axis
    cid_p1 / cid_p2 / cid_p3 : int
        the coordinate systems for p1, p2, and p3
    method : str
        'Z-Axis Projection'
           p1-p2 defines the x-axis
           k is defined by the z-axis
       'CORD2R' : typical
    idir : int; default=0
        the direction of the step direction

    Returns
    -------
    xyz1 / xyz2 / xyz3 : (3,) float ndarray
        the 1=starting 2=ending, 3=normal coordinates of the
        coordinate frames to create in the cid=0 frame
    i / k : (3,) float ndarray
        the i and k vectors of the coordinate system
    coord_out : Coord
        the generated coordinate system
    stations : (n,) float ndarray
        ???

    """
    # define a local coordinate system
    xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r(
        model,
        p1,
        p2,
        zaxis,
        cid_p1=cid_p1,
        cid_p2=cid_p2,
        cid_zaxis=cid_zaxis,
        method=method)
    xyz3 = model.coords[cid_p3].transform_node_to_global(p3)

    coord_out = CORD2R(None,
                       rid=0,
                       origin=origin,
                       zaxis=zaxis,
                       xzplane=xzplane,
                       comment='')
    #print(coord_out.get_stats())

    xyz1p = coord_out.transform_node_to_local(xyz1)
    xyz3p = coord_out.transform_node_to_local(xyz3)
    dx = xyz3p[idir] - xyz1p[idir]
    if abs(dx) == 0.:
        msg = f'Coincident starting and end points.  dx={dx} xyz1={xyz1} xyz3={xyz3}'
        raise ValueError(msg)
    stations = np.linspace(0., dx, num=nplanes, endpoint=True)

    return xyz1, xyz2, xyz3, i, k, coord_out, stations
예제 #15
0
 def add_cord2r(self, card, comment=''):
     """adds a CORD2R card"""
     coord = CORD2R.add_card(card, comment=comment)
     self.coords[coord.cid] = coord
     self.n += 1
예제 #16
0
def get_stations(model: BDF,
                 p1,
                 p2,
                 p3,
                 zaxis,
                 method: str = 'Z-Axis Projection',
                 cid_p1: int = 0,
                 cid_p2: int = 0,
                 cid_p3: int = 0,
                 cid_zaxis: int = 0,
                 idir: int = 0,
                 nplanes: int = 20) -> Tuple[NDArray3float, NDArray3float, ]:
    """
    Gets the axial stations

    Parameters
    ----------
    p1: (3,) float ndarray
        defines the starting point for the shear, moment, torque plot
    p3: (3,) float ndarray
        defines the end point for the shear, moment, torque plot
    p2: (3,) float ndarray
        defines the XZ plane for the shears/moments
    zaxis: (3,) float ndarray
        the direction of the z-axis
    cid_p1 / cid_p2 / cid_p3 : int
        the coordinate systems for p1, p2, and p3
    method : str
        'Z-Axis Projection'
           p1-p2 defines the x-axis
           k is defined by the z-axis
       'CORD2R' : typical
    idir : int; default=0
        the direction of the step direction (0, 1, 2)

    Returns
    -------
    xyz1 / xyz2 / xyz3 : (3,) float ndarray
        the 1=starting 2=ending, 3=normal coordinates of the
        coordinate frames to create in the cid=0 frame
    i / k : (3,) float ndarray
        the i and k vectors of the coordinate system
    coord_out : Coord
        the generated coordinate system where the x-axis defines
        the direction to be marched
    stations : (n,) float ndarray
        the coordinates in the x-axis that will be marched down

    Example
    -------
    For the BWB example, we to calculate an SMT down the global x-axis

    1--------> y
    |
    |
    |
    2, 3
    |
    v x

    # axial
    p1 = np.array([0., 0., 0.]) # origin
    p2 = np.array([1600., 0., 0.]) # xaxis
    p3 = np.array([1600., 0., 0.]) # end
    zaxis = np.array([0., 0., 1.])
    method = 'Z-Axis Projection'
    idir = 0

    xyz1, xyz2, xyz3, i, k, coord_out, stations = get_stations(
        model, p1, p2, p3, zaxis,
        method=method, cid_p1=0, cid_p2=0, cid_p3=0,
        cid_zaxis=0, idir=idir, nplanes=100)
    print(stations)

    """
    # define a local coordinate system
    xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r(
        model,
        p1,
        p2,
        zaxis,
        cid_p1=cid_p1,
        cid_p2=cid_p2,
        cid_zaxis=cid_zaxis,
        method=method)
    xyz3 = model.coords[cid_p3].transform_node_to_global(p3)

    coord_out = CORD2R(None,
                       rid=0,
                       origin=origin,
                       zaxis=zaxis,
                       xzplane=xzplane,
                       comment='')
    #print(coord_out.get_stats())

    xyz1p = coord_out.transform_node_to_local(xyz1)
    xyz3p = coord_out.transform_node_to_local(xyz3)
    dx = xyz3p[idir] - xyz1p[idir]
    if abs(dx) == 0.:
        msg = f'Coincident starting and end points.  dx={dx} xyz1={xyz1} xyz3={xyz3}\n'
        msg += coord_out.get_stats()
        raise ValueError(msg)
    stations = np.linspace(0., dx, num=nplanes, endpoint=True)

    return xyz1, xyz2, xyz3, i, k, coord_out, stations
예제 #17
0
def get_stations(model: BDF,
                 p1: NDArray3float, p2: NDArray3float, p3: NDArray3float,
                 zaxis: NDArray3float,
                 method: str='Z-Axis Projection',
                 cid_p1: int=0, cid_p2: int=0, cid_p3: int=0, cid_zaxis: int=0,
                 nplanes: int=20) -> Tuple[NDArray3float, NDArray3float, NDArray3float,
                                                        NDArray3float, NDArray3float,
                                                        CORD2R,
                                                        NDArray3float, NDArrayNfloat]:
    """
    Gets the axial stations

    Parameters
    ----------
    p1: (3,) float ndarray
        defines the starting point for the shear, moment, torque plot
    p3: (3,) float ndarray
        defines the end point for the shear, moment, torque plot
    p2: (3,) float ndarray
        defines the XZ plane for the shears/moments
    zaxis: (3,) float ndarray
        the direction of the z-axis
    cid_p1 / cid_p2 / cid_p3 : int
        the coordinate systems for p1, p2, and p3
    method : str
        'Z-Axis Projection'
           p1-p2 defines the x-axis
           k is defined by the z-axis
       'CORD2R' : typical

    Returns
    -------
    xyz1 / xyz2 / xyz3 : (3,) float ndarray
        the 1=starting 2=ending, 3=normal coordinates of the
        coordinate frames to create in the cid=0 frame
    i / k : (3,) float ndarray
        the i and k vectors of the coordinate system
    coord_out : Coord
        the output coordinate system
    iaxis_march : (3,) float ndarray
        the normalized x-axis that defines the direction to march
    stations : (n,) float ndarray
        the coordinates in the x-axis that will be marched down

    Example
    -------
    For the BWB example, we to calculate an SMT down the global x-axis

    1--------> y
    |
    |
    |
    2, 3
    |
    v x

    # axial
    p1 = np.array([0., 0., 0.]) # origin
    p2 = np.array([1600., 0., 0.]) # xaxis
    p3 = np.array([1600., 0., 0.]) # end
    zaxis = np.array([0., 0., 1.])
    method = 'Z-Axis Projection'

    xyz1, xyz2, xyz3, i, k, coord_out, stations = get_stations(
        model, p1, p2, p3, zaxis,
        method=method, cid_p1=0, cid_p2=0, cid_p3=0,
        cid_zaxis=0, nplanes=100)
    print(stations)

    """
    p1 = np.asarray(p1) # start
    p2 = np.asarray(p2) # xz-plane
    p3 = np.asarray(p3) # end point
    zaxis = np.asarray(zaxis)

    # define a local coordinate system
    xyz1, xyz2, unused_z_global, i, k, origin, zaxis2, xzplane = _p1_p2_zaxis_to_cord2r(
        model, p1, p2, zaxis,
        cid_p1=cid_p1, cid_p2=cid_p2, cid_zaxis=cid_zaxis,
        method=method)
    xyz3 = model.coords[cid_p3].transform_node_to_global(p3)

    coord_out = CORD2R(None, origin=origin, zaxis=zaxis2, xzplane=xzplane)
    #coord_march = coord_out
    xaxis_march = xyz3 - xyz1
    xaxis_march_norm = np.linalg.norm(xaxis_march)
    if xaxis_march_norm == 0.:
        msg = f'Coincident starting and end points.  dx={xaxis_march_norm} xyz1={xyz1} xyz3={xyz3}\n'
        #msg += coord_out.get_stats()
        raise ValueError(msg)

    iaxis_march = xaxis_march / xaxis_march_norm
    # k has been rotated into the output coordinte frame, so we'll maintain that
    # k is length=1
    assert np.allclose(np.linalg.norm(k), 1.0)
    jaxis_march = np.cross(k, iaxis_march)
    kaxis_march = np.cross(iaxis_march, jaxis_march)
    coord_march = CORD2R(None, origin=origin, zaxis=origin+kaxis_march, xzplane=origin+iaxis_march)
    #coord_march = CORD2R(None, origin=origin, zaxis=axis_march, xzplane=xzplane)
    #print(coord_out.get_stats())

    xyz1p = coord_march.transform_node_to_local(xyz1)
    xyz3p = coord_march.transform_node_to_local(xyz3)
    xaxis = xyz3p - xyz1p

    # we want to give the dx the right sign in the coord_out frame
    #i_abs = np.abs(coord_march.i)
    #i_abs_max = i_abs.max()
    #idir = np.where(i_abs == i_abs_max)[0][0]
    #isign = np.sign(coord_march.i[idir])
    dx = xaxis[0] # * isign

    if abs(dx) == 0.:
        msg = f'Coincident starting and end points.  dx={dx} xyz1={xyz1} xyz3={xyz3}\n'
        msg += coord_out.get_stats()
        raise ValueError(msg)
    x_stations_march = np.linspace(0., dx, num=nplanes, endpoint=True)
    assert x_stations_march.shape == (nplanes, ), x_stations_march.shape
    #stations.sort()

    return xyz1, xyz2, xyz3, i, k, coord_out, iaxis_march, x_stations_march
예제 #18
0
    def make_cutting_plane(self,
                           model_name,
                           p1,
                           p2,
                           zaxis,
                           method='Z-Axis Projection',
                           cid_p1=0,
                           cid_p2=0,
                           cid_zaxis=0,
                           ytol=1.,
                           plane_atol=1e-5,
                           plane_color=None,
                           plane_opacity=0.5,
                           csv_filename=None,
                           show=True):
        """Creates a cutting plane of the aero_model for the active plot result"""
        if plane_color is None:
            plane_color = PURPLE_FLOAT
        assert len(plane_color) == 3, plane_color
        log = self.gui.log

        model = self.gui.models[model_name]
        class_name = model.__class__.__name__
        if class_name in ['BDF', 'OP2Geom']:
            out = model.get_displacement_index_xyz_cp_cd()
            unused_icd_transform, icp_transform, xyz_cp, nid_cp_cd = out
            nids = nid_cp_cd[:, 0]
            nid_cd = nid_cp_cd[:, [0, 2]]
            xyz_cid0 = model.transform_xyzcp_to_xyz_cid(xyz_cp,
                                                        nids,
                                                        icp_transform,
                                                        cid=0)
        else:
            log.error('%r is not supported' % class_name)
            return

        #xyz_min, xyz_max = model.xyz_limits
        xyz_min = xyz_cid0.min(axis=0)
        xyz_max = xyz_cid0.max(axis=0)
        assert len(xyz_min) == 3, xyz_min

        dxyz = np.abs(xyz_max - xyz_min)
        dim_max = dxyz.max()
        izero = np.where(dxyz == 0)
        dxyz[izero] = dim_max

        xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r(
            model,
            p1,
            p2,
            zaxis,
            cid_p1=cid_p1,
            cid_p2=cid_p2,
            cid_zaxis=cid_zaxis,
            method=method)

        plane_actor = self.gui._create_plane_actor_from_points(
            xyz1, xyz2, i, k, dim_max, actor_name='plane')
        prop = plane_actor.GetProperty()
        prop.SetColor(*plane_color)
        prop.SetOpacity(plane_opacity)  # 0=transparent, 1=solid

        self.gui.rend.Render()

        try:
            # i/j/k vector is nan
            coord = CORD2R(1,
                           rid=0,
                           origin=origin,
                           zaxis=zaxis,
                           xzplane=xzplane,
                           comment='')
        except:
            log.error(
                'The coordinate system is invalid; check your cutting plane.')
            return
        #print(coord)
        origin = coord.origin
        beta = coord.beta().T

        cid = ''
        self.gui.create_coordinate_system(cid,
                                          dim_max,
                                          label='%s' % cid,
                                          origin=origin,
                                          matrix_3x3=beta,
                                          coord_type='xyz')

        nnodes = xyz_cid0.shape[0]
        #nodal_result = np.linspace(0., 1., num=nnodes)

        #case = self.result_cases[self.icase_aero]
        #res_scalars, location = model.aero_raw_plot_result()
        (obj, (i, name)) = self.gui.result_cases[self.gui.icase_fringe]
        res_scalars = obj.get_scalar(i, name)
        location = obj.get_location(i, name)

        if res_scalars is None:
            if plane_actor is not None:
                plane_actor.VisibilityOn()
                #print(self.model_frame.plane_actor)
                #print(dir(self.model_frame.plane_actor))
                #plane_actor.VisibilityOff()
            log.error('No result is selected.')
            return

        if hasattr(obj, 'titles'):
            title = obj.titles[0]
        elif hasattr(obj, 'title'):
            title = obj.title
        else:
            raise NotImplementedError(obj)

        plane_actor.VisibilityOn()
        if location == 'centroid':
            if hasattr(model, 'map_centroidal_result'):
                nodal_result = model.map_centroidal_result(res_scalars)
            else:
                log.error('Centroidal results are not supported.')
                return
            #np.savetxt('Cp_centroid.csv', res_scalars, header='# Cp')
            #np.savetxt('Cp_nodal.csv', nodal_result, header='# Cp')
        else:
            nodal_result = res_scalars
        assert len(nodal_result) == nnodes

        invert_yaxis = False
        if title in ['Cp']:
            invert_yaxis = True

        cut_and_plot_model(title,
                           p1,
                           p2,
                           zaxis,
                           model,
                           coord,
                           nodal_result,
                           log,
                           ytol,
                           plane_atol=plane_atol,
                           csv_filename=csv_filename,
                           invert_yaxis=invert_yaxis,
                           cut_type='edge',
                           show=show)