Esempio n. 1
0
    def safe_cross_reference(self, model: BDF, xref_errors):
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by CGAP eid=%s' % self.eid
        self.ga_ref = model.Node(self.ga, msg=msg)
        self.gb_ref = model.Node(self.gb, msg=msg)
        if self.g0:
            self.g0_ref = model.Node(self.g0, msg=msg)
            self.x = self.g0_ref.get_position()
        self.pid_ref = model.safe_property(self.pid,
                                           self.eid,
                                           xref_errors,
                                           msg=msg)
        if self.cid is not None:
            self.cid_ref = model.safe_coord(self.cid,
                                            self.eid,
                                            xref_errors,
                                            msg=msg)
Esempio n. 2
0
    def getNodes(self, grids, grids_expected, coords, debug=False):
        model = BDF(debug=False)

        for (nid, grid) in enumerate(grids):
            (cid, x, y, z) = grid
            model.add_card(['GRID', nid + 1, cid, x, y, z], 'GRID')
            gridObj = model.Node(nid + 1)
            if debug:
                print(gridObj)

        for (cid, coord) in enumerate(coords):
            #print coord
            (rid, x, y, z) = coord
            model.add_card(['CORD2R', cid + 1, rid] + x + y + z, 'CORD2R')
            coordObj = model.Coord(cid + 1)
            if debug:
                print(coordObj)

        model.cross_reference()

        for (i, grid) in enumerate(grids_expected):
            (cid, x, y, z) = grid
            node = model.Node(i + 1)
            pos = node.Position()
            n = array([x, y, z])

            msg = 'expected=%s actual=%s\n' % (n, pos)
            msg += 'n=%s grid=\n%s' % (i + 1, node)
            coord = node.cp
            msg += 'n=%s coord=\n%s' % (node.nid, coord)
            while coord.rid:
                msg += 'n=%s rcoord=\n%s' % (node.nid, coord.rid)
                coord = coord.rid
            assert allclose(n, pos), msg
Esempio n. 3
0
    def test_cord2_rcs_01(self):
        """
        all points are located at <30,40,50>
        """
        model = BDF(debug=False)
        cards = [
            [#'$ Femap with NX Nastran Coordinate System 10 : rectangular defined in a rectangular',
            'CORD2R*               10               0             10.              5.',
            '*                     3.   10.3420201433   4.53015368961   3.81379768136*       ',
            '*          10.7198463104   5.68767171433   3.09449287122',],
            [#'$ Femap with NX Nastran Coordinate System 11 : cylindrical defined in rectangular',
            'CORD2C*               11               0              7.              3.',
            '*                     9.   7.64278760969   2.73799736977   9.71984631039*       ',
            '*          7.75440650673   3.37968226211   8.46454486422',],
            [#'$ Femap with NX Nastran Coordinate System 12 : spherical defined in rectangular',
            'CORD2S*               12               0             12.              8.',
            '*                     5.   12.6427876097   7.86697777844   5.75440650673*       ',
            '*          12.6634139482   8.58906867688   4.53861076379',],

            ['GRID*                 10              10   42.9066011565   34.2422137135',
            '*          28.6442730262               0',],
            ['GRID*                 11              11   48.8014631871   78.8394787869',
            '*          34.6037164304               0',],
            ['GRID*                 12              12   58.0775343829   44.7276544324',
            '*          75.7955331161               0',],
        ]
        for lines in cards:
            card = model.process_card(lines)
            model.add_card(card, card[0])
        model.cross_reference()
        for nid in model.nodes:
            a = array([30.,40.,50.])
            b = model.Node(nid).Position()
            self.assertTrue(allclose(array([30.,40.,50.]), model.Node(nid).Position()), str(a-b))
Esempio n. 4
0
 def test_cord2_rcs_03(self):
     """
     all points are located at <30,40,50>
     """
     model = BDF(debug=False)
     cards = [
         [
             'CORD2S*                2               0              0.              0.',
             '*                     0.              0.              0.              1.*       ',
             '*                     1.              0.              1.',
         ],
         [
             #'$ Femap with NX Nastran Coordinate System 30 : rectangular in spherical',
             'CORD2R*               30               2             14.             30.',
             '*                    70.    13.431863852   32.1458443949   75.2107442927*       ',
             '*          14.4583462334   33.4569982885   68.2297989286',
         ],
         [
             #'$ Femap with NX Nastran Coordinate System 31 : cylindrical in spherical',
             'CORD2C*               31               2              3.             42.',
             '*                  -173.   2.86526881213   45.5425615252   159.180363517*       ',
             '*          3.65222385965   29.2536614627  -178.631312271',
         ],
         [
             #'$ Femap with NX Nastran Coordinate System 32 : spherical in spherical',
             'CORD2S*               32               2             22.             14.',
             '*                    85.   22.1243073983   11.9537753718   77.9978191005*       ',
             '*          21.0997242967   13.1806120497   88.4824763008',
         ],
         [
             'GRID*                 30              30   40.7437952957  -23.6254877994',
             '*           -33.09784854               0',
         ],
         [
             'GRID*                 31              31   62.9378078196   15.9774797923',
             '*          31.0484428362               0',
         ],
         [
             'GRID*                 32              32   53.8270847449   95.8215692632',
             '*          159.097767463               0',
         ],
     ]
     for lines in cards:
         card = model._process_card(lines)
         model.add_card(card, card[0])
     model.cross_reference()
     for nid in model.nodes:
         a = array([30., 40., 50.])
         b = model.Node(nid).Position()
         self.assertTrue(
             allclose(array([30., 40., 50.]),
                      model.Node(nid).Position()), str(a - b))
Esempio n. 5
0
 def test_cord2_rcs_02(self):
     """
     all points are located at <30,40,50>
     """
     model = BDF(debug=False)
     cards = [
         [
             'CORD2C*                1               0              0.              0.',
             '*                     0.              0.              0.              1.*       ',
             '*                     1.              0.              1.',
         ],
         [
             #'$ Femap with NX Nastran Coordinate System 20 : rectangular defined in cylindrical',
             'CORD2R*               20               1              7.             20.',
             '*                    -6.   7.07106781187   28.1301023542             -6.*       ',
             '*          7.70710678119             20.  -5.29289321881',
         ],
         [
             #'$ Femap with NX Nastran Coordinate System 21 : cylindrical defined in cylindrical',
             'CORD2C*               21               1             15.            -30.',
             '*                    12.   14.6565766735  -30.3177805524   12.9355733712*       ',
             '*          14.6234241583  -26.4257323272   11.9304419665',
         ],
         [
             #'$ Femap with NX Nastran Coordinate System 22 : spherical defined in cylindrical',
             'CORD2S*               22               1              5.            -75.',
             '*                    20.   5.66032384035  -82.9319986389   19.8502545865*       ',
             '*          4.88876051026  -73.8006653677   19.0116094889',
         ],
         [
             'GRID*                 20              20   64.2559135157  -14.9400459772',
             '*          27.3271005317               0',
         ],
         [
             'GRID*                 21              21   52.8328862418  -28.8729017195',
             '*           34.615939507               0',
         ],
         [
             'GRID*                 22              22   61.1042111232   158.773483595',
             '*           -167.4951724               0',
         ],
     ]
     for lines in cards:
         card = model._process_card(lines)
         model.add_card(card, card[0])
     model.cross_reference()
     for nid in model.nodes:
         a = array([30., 40., 50.])
         b = model.Node(nid).Position()
         self.assertTrue(
             allclose(array([30., 40., 50.]),
                      model.Node(nid).Position()), str(a - b))
Esempio n. 6
0
    def test_cord2r_02(self):
        grid = ['GRID       20143       7 -9.31-4  .11841 .028296']
        coord = [
            'CORD2R         7           1.135 .089237  -.0676    .135 .089237  -.0676',
            '           1.135 .089237   .9324'
        ]

        model = BDF(debug=False)
        card = model._process_card(grid)
        model.add_card(card, card[0])

        card = model._process_card(coord)
        model.add_card(card, card[0])
        model.cross_reference()
        coord = model.Coord(7)
        #print(coord.origin)
        #print(coord.i, coord.j, coord.k)

        node = model.Node(20143)
        xyzp1 = Position(node.xyz, node.cp, model)
        xyzp2 = Position(node.xyz, node.cp_ref, model)
        xyz = node.get_position()
        assert np.array_equal(xyz, xyzp1)
        assert np.array_equal(xyz, xyzp2)

        xyz_same = PositionWRT([1., 2., 3.], 100, 100, model)
        assert np.array_equal(xyz_same, [1., 2., 3.])

        xyz_wrt_p1 = PositionWRT(node.xyz, node.cp, 0, model)
        xyz_wrt_p2 = PositionWRT(node.xyz, node.cp_ref, 0, model)
        xyz_wrt = node.get_position_wrt(model, 0)
        assert np.array_equal(xyz, xyz_wrt_p1)
        assert np.array_equal(xyz, xyz_wrt_p2)
        assert np.array_equal(xyz, xyz_wrt)

        # by running it through Patran...
        #GRID     20143          1.1067  .207647 -.068531
        expected = array([1.106704, .207647, -0.068531])
        diff = xyz - expected

        msg = '\nexpected=%s \nactual  =%s \ndiff    =%s' % (expected, xyz, diff)
        assert allclose(diff, 0.), msg
        coord = model.Coord(7)
        coord.beta_n(1)
        coord.beta_n(2)
        coord.beta_n(3)
        coord.beta_n(6)
        with self.assertRaises(AttributeError):
            self.assertTrue(array_equal(coord.T(), coord.beta_n(2)))
        #with self.assertRaises(NotImplementedError):
            #self.assertTrue(array_equal(coord.T(), coord.beta_n(2)))

        model2 = BDF(debug=False)
        cid = 7
        origin = [1.135, .089237, -.0676]
        zaxis = [.135, .089237, -.0676]
        xzplane = [1.135, .089237, .9324]
        coord2 = model2.add_cord2r(cid, origin, zaxis, xzplane, rid=0, comment='cord2r')
        coord2.comment = ''
        assert coord == coord2, 'coord:\n%r\ncoord2:\n%r' % (str(coord), str(coord2))
Esempio n. 7
0
    def _get_nodes(self, grids, grids_expected, coords):
        model = BDF(debug=False)

        for grid in grids:
            (nid, cid, x, y, z) = grid
            model.add_card(['GRID', nid, cid, x, y, z], 'GRID')

        for coord in coords:
            (cid, rid, x, y, z) = coord
            model.add_card(['CORD2R', cid, rid] + x + y + z, 'CORD2R')
            coord_obj = model.Coord(cid)

        model.cross_reference()
        for i, grid in enumerate(grids_expected):
            nid, cid, x, y, z = grid
            node = model.Node(nid)
            pos = node.get_position()
            n = array([x, y, z])

            msg = 'i=%s expected=%s actual=%s\n' % (i, n, pos)
            msg += 'n=%s grid=\n%s' % (nid, node)
            coord = node.cp
            msg += 'n=%s coord=\n%s' % (node.nid, coord)
            while coord.rid:
                msg += 'n=%s rcoord=\n%s' % (node.nid, coord.rid)
                coord = coord.rid
            assert allclose(n, pos), msg
Esempio n. 8
0
    def test_cord2r_1(self):
        grid = ['GRID       20143       7 -9.31-4  .11841 .028296']
        coord = ['CORD2R         7           1.135 .089237  -.0676    .135 .089237  -.0676',
                 '           1.135 .089237   .9324']

        model = BDF(debug=False)
        card = model.process_card(grid)
        model.add_card(card, card[0])

        card = model.process_card(coord)
        model.add_card(card, card[0])
        model.cross_reference()

        g = model.Node(20143)
        #print(g.Position(debug=False))

        # by running it through Patran...
        #GRID     20143          1.1067  .207647 -.068531
        diff = g.Position() - array([1.106704, .207647, -0.068531])

        msg = 'diff=%s' % diff
        assert allclose(diff, 0.), msg
        coord = model.Coord(7)
        coord.T()
        self.assertTrue(array_equal(coord.T(), coord.beta_n(2)))
Esempio n. 9
0
    def test_cord2r_02(self):
        grid = ['GRID       20143       7 -9.31-4  .11841 .028296']
        coord = ['CORD2R         7           1.135 .089237  -.0676    .135 .089237  -.0676',
                 '           1.135 .089237   .9324']

        model = BDF(debug=False)
        card = model.process_card(grid)
        model.add_card(card, card[0])

        card = model.process_card(coord)
        model.add_card(card, card[0])
        model.cross_reference()
        coord = model.Coord(7)
        #print(coord.origin)
        #print(coord.i, coord.j, coord.k)

        g = model.Node(20143)
        #print(g.Position(debug=False))
        xyz = g.Position()

        # by running it through Patran...
        #GRID     20143          1.1067  .207647 -.068531
        expected = array([1.106704, .207647, -0.068531])
        diff = xyz - expected

        msg = '\nexpected=%s \nactual  =%s \ndiff    =%s' % (expected, xyz, diff)
        assert allclose(diff, 0.), msg
        coord = model.Coord(7)
        coord.T()
        self.assertTrue(array_equal(coord.T(), coord.beta_n(2)))
Esempio n. 10
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object
        """
        msg = ', which is required by CBUSH1D eid=%s' % self.eid
        self.ga_ref = model.Node(self.ga, msg=msg)
        if self.gb:
            self.gb_ref = model.Node(self.gb, msg=msg)
        self.pid_ref = model.Property(self.pid, msg=msg)
        if self.cid is not None:
            self.cid_ref = model.Coord(self.cid)
Esempio n. 11
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by CFAST eid=%s' % self.eid
        self.pid_ref = model.Property(self.Pid(), msg=msg)
        if self.gs:
            self.gs_ref = model.Node(self.Gs(), msg=msg)
        if self.ga:
            self.ga_ref = model.Node(self.Ga(), msg=msg)
        if self.gb:
            self.gb_ref = model.Node(self.Gb(), msg=msg)
Esempio n. 12
0
def get_nodes(grids, grids_expected, coords):
    """
    Create each input grid/coord

    Loop over the expected grids, use the provided coordinate system
    and verify that the xyz location is correct.

    Parameters
    ----------
    grids : List[grid]
        the grids
        grid : List[nid, cp, x, y, z]
            the GRID fields
    coords : List[coord]
        coord : List[int cid, rid, origin, zaxis, xaxis]
            the coordinate system to add to the model
    grids_expected : List[grid]
        the expected grids
        grid : List[nid, cp, x, y, z]
            the GRID fields

    """
    model = BDF(debug=False)

    for grid in grids:
        (nid, cid, x, y, z) = grid
        model.add_card(['GRID', nid, cid, x, y, z], 'GRID')

    for coord in coords:
        (cid, rid, x, y, z) = coord
        model.add_card(['CORD2R', cid, rid] + x + y + z, 'CORD2R')
        #coord_obj = model.Coord(cid)

    model.cross_reference()
    save_load_deck(model,
                   run_remove_unused=False,
                   run_convert=False,
                   run_save_load_hdf5=True)

    for (i, grid) in enumerate(grids_expected):
        (nid, cid, x, y, z) = grid
        node = model.Node(nid)
        xyz_actual = node.get_position()
        xyz = array([x, y, z])

        msg = 'i=%s expected=%s actual=%s\n' % (i, xyz, xyz_actual)
        msg += 'n=%s grid=\n%s' % (nid, node)
        coord_ref = node.cp_ref
        msg += 'n=%s coord=\n%s' % (node.nid, coord_ref)

        if not allclose(xyz, xyz_actual):
            # TODO: this used to work, but the changing xref broke it somehow
            #       this block probably needs to be slightly updated
            while coord_ref.rid:
                msg += 'xyz=%s rcoord=\n%s' % (node.nid, coord_ref.rid)
                coord_ref = coord_ref.rid
            assert allclose(xyz, xyz_actual), msg
Esempio n. 13
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by CGAP eid=%s' % self.eid
        self.ga_ref = model.Node(self.ga, msg=msg)
        self.gb_ref = model.Node(self.gb, msg=msg)
        if self.g0:
            self.g0_ref = model.Node(self.g0, msg=msg)
            self.x = self.g0_ref.get_position()
        self.pid_ref = model.Property(self.pid, msg=msg)
        if self.cid:
            self.cid_ref = model.Coord(self.cid, msg=msg)
Esempio n. 14
0
    def safe_cross_reference(self, model: BDF, xref_errors):
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by CONM1 eid=%s' % self.eid
        self.nid_ref = model.Node(self.nid, msg=msg)
        self.cid_ref = model.safe_coord(self.cid, self.eid, xref_errors, msg='')
Esempio n. 15
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by CONM1 eid=%s' % self.eid
        self.nid_ref = model.Node(self.nid, msg=msg)
        self.cid_ref = model.Coord(self.cid, msg=msg)
Esempio n. 16
0
    def get_node_positions_no_xref(self, model: BDF, nodes: List[Any]=None) -> np.ndarray:
        """returns the positions of multiple node objects"""
        if not nodes:
            nodes = self.nodes

        nnodes = len(nodes)
        positions = np.empty((nnodes, 3), dtype='float64')
        positions.fill(np.nan)
        for i, nid in enumerate(nodes):
            if nid is not None:
                node = model.Node(nid)
                positions[i, :] = node.get_position_no_xref(model)
        return positions
Esempio n. 17
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by PLOADX1 lid=%s' % self.sid
        self.eid_ref = model.Element(self.eid, msg=msg)
        self.ga_ref = model.Node(self.ga, msg=msg)
        self.gb_ref = model.Node(self.gb, msg=msg)
Esempio n. 18
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by PLOTEL eid=%s' % self.eid
        self.nodes_ref = [
            model.Node(self.nodes[0], msg=msg),
            model.Node(self.nodes[1], msg=msg),
        ]
Esempio n. 19
0
    def safe_cross_reference(self, model: BDF, xref_errors):
        msg = ', which is required by CBEAM eid=%s' % (self.eid)
        self.nodes_ref = [
            model.Node(self.ga, msg=msg),
            model.Node(self.gb, msg=msg),
        ]
        self.nodes_ref = [self.ga_ref, self.gb_ref]
        self.pid_ref = model.safe_property(self.pid, self.eid, xref_errors, msg=msg)

        if self.g0:
            try:
                self.g0_ref = model.nodes[self.g0]
                ga_ref = self.nodes_ref[0]
                self.g0_vector = self.g0_ref.get_position() - ga_ref.get_position()
            except KeyError:
                model.log.warning('Node=%s%s' % (self.g0, msg))
        else:
            self.g0_vector = self.x
Esempio n. 20
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object
        """
        msg = ', which is required by CBUSH eid=%s' % self.eid
        self.nodes_ref = model.EmptyNodes(self.node_ids, msg=msg)
        self.pid_ref = model.Property(self.pid, msg=msg)
        if self.g0 is not None:
            self.g0_ref = model.Node(self.g0, msg=msg)
        if self.cid is not None:
            self.cid_ref = model.Coord(self.cid, msg=msg)
        if self.ocid is not None and self.ocid != -1:
            self.ocid_ref = model.Coord(self.ocid, msg=msg)
Esempio n. 21
0
    def test_cord2r_1(self):
        grid = ['GRID       20143       7 -9.31-4  .11841 .028296']
        coord = [
            'CORD2R         7           1.135 .089237  -.0676    .135 .089237  -.0676',
            '           1.135 .089237   .9324'
        ]

        model = BDF()
        card = model.process_card(grid)
        model.add_card(card, card[0])
        card = model.process_card(coord)
        model.add_card(card, card[0])
        model.cross_reference()

        g = model.Node(20143)
        #print(g.Position(debug=False))
        diff = g.Position() - array([1.106704, .207647, -0.068531])

        assert allclose(diff, 0.)
Esempio n. 22
0
    def test_grid_01(self):
        model = BDF(debug=False)
        cards = [
            #['CORD1R', 1, 1, 2, 3],  # fails on self.k
            ['GRID', 1, 0, 0., 0., 0.],
            ['GRID', 2, 0, 1., 0., 0.],
            ['GRID', 4, 0, 1., 2., 3.],
        ]
        for card in cards:
            model.add_card(card, card[0], comment='comment', is_list=True)

        #+------+-----+----+----+----+----+----+----+------+
        #|   0  |  1  | 2  | 3  | 4  | 5  |  6 | 7  |  8   |
        #+======+=====+====+====+====+====+====+====+======+
        #| GRID | NID | CP | X1 | X2 | X3 | CD | PS | SEID |
        #+------+-----+----+----+----+----+----+----+------+
        node = model.Node(4)
        self.assertEqual(node.get_field(1), 4)
        self.assertEqual(node.get_field(2), 0)
        self.assertEqual(node.get_field(3), 1.)
        self.assertEqual(node.get_field(4), 2.)
        self.assertEqual(node.get_field(5), 3.)

        node.update_field(1, 5)
        node.update_field(2, 6)
        node.update_field(3, 7.)
        node.update_field(4, 8.)
        node.update_field(5, 9.)
        with self.assertRaises(KeyError):
            node.update_field(9, 'dummy')

        self.assertEqual(node.get_field(1), 5)
        self.assertEqual(node.get_field(2), 6)
        self.assertEqual(node.get_field(3), 7.)
        self.assertEqual(node.get_field(4), 8.)
        self.assertEqual(node.get_field(5), 9.)
        with self.assertRaises(KeyError):
            node.get_field(9)
Esempio n. 23
0
    def cross_reference(self, model: BDF) -> None:
        """
        Cross links the card so referenced cards can be extracted directly

        Parameters
        ----------
        model : BDF()
            the BDF object

        """
        msg = ', which is required by CBEAM eid=%s' % (self.eid)
        self.ga_ref = model.Node(self.ga, msg=msg)
        self.gb_ref = model.Node(self.gb, msg=msg)
        self.nodes_ref = [self.ga_ref, self.gb_ref]
        self.pid_ref = model.Property(self.pid, msg=msg)
        if self.g0:
            self.g0_ref = model.nodes[self.g0]
            self.g0_vector = self.g0_ref.get_position(
            ) - self.ga_ref.get_position()
        else:
            self.g0_vector = self.x
        if model.is_nx:
            assert self.offt == 'GGG', 'NX only support offt=GGG; offt=%r' % self.offt
Esempio n. 24
0
model_output = BDF()
pid_pbush = 99000000
prop_pbush_k =[1.0e+8,1.0e+8,1.0e+8,1.0e+12,1.0e+12,1.0e+12]
model_output.add_pbush(pid_pbush,prop_pbush_k,'','')

list_len = int(len(list_input_node) / 2 )
count = -1

for ta in range(list_len):
    count = count + 1
    id_grid_new = int(list_input_node[count])

    count = count + 1
    id_grid_input = int(list_input_node[count])
    grid_input = model_input.Node(id_grid_input)

    grid_input_pos = grid_input.get_position()
    model_output.add_grid(id_grid_new,grid_input_pos)

    list_node_pair = [id_grid_new,id_grid_input]
    model_output.add_cbush(id_grid_new,pid_pbush,list_node_pair,'','',0)

model_output.write_bdf('cbush.bdf')






Esempio n. 25
0
    def test_cord2_rcs_03(self):
        """
        all points are located at <30,40,50>
        """
        model = BDF(debug=False)
        cards = [
            [
                'CORD2S*                2               0              0.              0.',
                '*                     0.              0.              0.              1.*       ',
                '*                     1.              0.              1.',
            ],
            [
                #'$ Coordinate System 30 : rectangular in spherical',
                'CORD2R*               30               2             14.             30.',
                '*                    70.    13.431863852   32.1458443949   75.2107442927*       ',
                '*          14.4583462334   33.4569982885   68.2297989286',
            ],
            [
                #'$ Coordinate System 31 : cylindrical in spherical',
                'CORD2C*               31               2              3.             42.',
                '*                  -173.   2.86526881213   45.5425615252   159.180363517*       ',
                '*          3.65222385965   29.2536614627  -178.631312271',
            ],
            [
                #'$ Coordinate System 32 : spherical in spherical',
                'CORD2S*               32               2             22.             14.',
                '*                    85.   22.1243073983   11.9537753718   77.9978191005*       ',
                '*          21.0997242967   13.1806120497   88.4824763008',
            ],
            [
                'GRID*                 30              30   40.7437952957  -23.6254877994',
                '*           -33.09784854               0',
            ],
            [
                'GRID*                 31              31   62.9378078196   15.9774797923',
                '*          31.0484428362               0',
            ],
            [
                'GRID*                 32              32   53.8270847449   95.8215692632',
                '*          159.097767463               0',
            ],
        ]
        for lines in cards:
            card = model.process_card(lines)
            model.add_card(card, card[0])
        xyz_cid0b = model.get_xyz_in_coord_no_xref(cid=0, fdtype='float64')
        xyz_cid0c = model.get_xyz_in_coord_no_xref(cid=32, fdtype='float64')
        model.cross_reference()

        xyz_cid0_actual = array([
            [30., 40., 50.],
            [30., 40., 50.],
            [30., 40., 50.],
        ],
                                dtype='float64')
        for nid in model.nodes:
            a = array([30., 40., 50.])
            b = model.Node(nid).get_position()
            self.assertTrue(
                allclose(array([30., 40., 50.]),
                         model.Node(nid).get_position()), str(a - b))
        xyz_cid0 = model.get_xyz_in_coord(cid=0, fdtype='float64')
        array_equal(xyz_cid0_actual, xyz_cid0)

        icd_transform, icp_transform, xyz_cp, nid_cp_cd = model.get_displacement_index_xyz_cp_cd(
        )
        xyz_cid0_xform = model.transform_xyzcp_to_xyz_cid(xyz_cp,
                                                          icp_transform,
                                                          cid=0)
        array_equal(xyz_cid0_actual, xyz_cid0_xform)
        assert array_equal(nid_cp_cd[:, 0], array([30, 31, 32]))

        xyz_cid_30 = model.transform_xyzcp_to_xyz_cid(xyz_cp,
                                                      icp_transform,
                                                      cid=30)
        xyz_cid_31 = model.transform_xyzcp_to_xyz_cid(xyz_cp,
                                                      icp_transform,
                                                      cid=31)
        xyz_cid_32 = model.transform_xyzcp_to_xyz_cid(xyz_cp,
                                                      icp_transform,
                                                      cid=32)
Esempio n. 26
0
    def test_cord2_rcs_02(self):
        """
        all points are located at <30,40,50>
        """
        model = BDF(debug=False)
        cards = [
            [
                'CORD2C*                1               0              0.              0.',
                '*                     0.              0.              0.              1.*       ',
                '*                     1.              0.              1.',],
            [
                #'$ Coordinate System 20 : rectangular defined in cylindrical',
                'CORD2R*               20               1              7.             20.',
                '*                    -6.   7.07106781187   28.1301023542             -6.*       ',
                '*          7.70710678119             20.  -5.29289321881',],
            [
                #'$ Coordinate System 21 : cylindrical defined in cylindrical',
                'CORD2C*               21               1             15.            -30.',
                '*                    12.   14.6565766735  -30.3177805524   12.9355733712*       ',
                '*          14.6234241583  -26.4257323272   11.9304419665',],
            [
                #'$ Coordinate System 22 : spherical defined in cylindrical',
                'CORD2S*               22               1              5.            -75.',
                '*                    20.   5.66032384035  -82.9319986389   19.8502545865*       ',
                '*          4.88876051026  -73.8006653677   19.0116094889',],
            [
                'GRID*                 20              20   64.2559135157  -14.9400459772',
                '*          27.3271005317               0',],
            [
                'GRID*                 21              21   52.8328862418  -28.8729017195',
                '*           34.615939507               0',],
            [
                'GRID*                 22              22   61.1042111232   158.773483595',
                '*           -167.4951724               0',],
        ]
        for lines in cards:
            card = model._process_card(lines)
            model.add_card(card, card[0])
        unused_xyz_cid0b = model.get_xyz_in_coord_no_xref(cid=0, fdtype='float64')
        unused_xyz_cid0c = model.get_xyz_in_coord_no_xref(cid=22, fdtype='float64')
        model.cross_reference()

        xyz_cid0_actual = array([
            [30., 40., 50.],
            [30., 40., 50.],
            [30., 40., 50.],
        ], dtype='float64')
        for nid in model.nodes:
            a = array([30., 40., 50.])
            b = model.Node(nid).get_position()
            self.assertTrue(allclose(array([30., 40., 50.]),
                                     model.Node(nid).get_position()), str(a - b))
        xyz_cid0 = model.get_xyz_in_coord(cid=0, fdtype='float64')
        array_equal(xyz_cid0_actual, xyz_cid0)

        unused_icd_transform, icp_transform, xyz_cp, nid_cp_cd = model.get_displacement_index_xyz_cp_cd()
        xyz_cid0_xform = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=0)
        array_equal(xyz_cid0_actual, xyz_cid0_xform)
        assert array_equal(nid_cp_cd[:, 0], array([20, 21, 22]))

        unused_xyz_cid_20 = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=20)
        unused_xyz_cid_21 = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=21)
        unused_xyz_cid_22 = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=22)
Esempio n. 27
0
    def test_cord2_rcs_01(self):
        """
        all points are located at <30,40,50>
        """
        model = BDF(debug=False)
        cards = [
            [
                #'$ Coordinate System 10 : rectangular defined in a rectangular',
                'CORD2R*               10               0             10.              5.',
                '*                     3.   10.3420201433   4.53015368961   3.81379768136*       ',
                '*          10.7198463104   5.68767171433   3.09449287122',],
            [
                #'$ Coordinate System 11 : cylindrical defined in rectangular',
                'CORD2C*               11               0              7.              3.',
                '*                     9.   7.64278760969   2.73799736977   9.71984631039*       ',
                '*          7.75440650673   3.37968226211   8.46454486422',],
            [
                #'$ Coordinate System 12 : spherical defined in rectangular',
                'CORD2S*               12               0             12.              8.',
                '*                     5.   12.6427876097   7.86697777844   5.75440650673*       ',
                '*          12.6634139482   8.58906867688   4.53861076379',],

            [
                'GRID*                 10              10   42.9066011565   34.2422137135',
                '*          28.6442730262               0',],
            [
                'GRID*                 11              11   48.8014631871   78.8394787869',
                '*          34.6037164304               0',],
            [
                'GRID*                 12              12   58.0775343829   44.7276544324',
                '*          75.7955331161               0',],
        ]
        for lines in cards:
            card = model._process_card(lines)
            model.add_card(card, card[0])

        unused_xyz_cid0b = model.get_xyz_in_coord_no_xref(cid=0, fdtype='float64')
        unused_xyz_cid0c = model.get_xyz_in_coord_no_xref(cid=12, fdtype='float64')
        model.cross_reference()

        xyz_cid0_actual = array([
            [30., 40., 50.],
            [30., 40., 50.],
            [30., 40., 50.],
        ], dtype='float64')
        for nid in model.nodes:
            node = model.Node(nid)
            a = array([30., 40., 50.])
            b = node.get_position()
            self.assertTrue(allclose(array([30., 40., 50.]),
                                     node.get_position()), str(a - b))

        xyz_cid0 = model.get_xyz_in_coord(cid=0, fdtype='float64')
        array_equal(xyz_cid0_actual, xyz_cid0)

        unused_icd_transform, icp_transform, xyz_cp, nid_cp_cd = model.get_displacement_index_xyz_cp_cd()
        xyz_cid0_xform = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=0)
        array_equal(xyz_cid0_actual, xyz_cid0_xform)
        assert array_equal(nid_cp_cd[:, 0], array([10, 11, 12]))

        unused_xyz_cid_10 = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=10)
        unused_xyz_cid_11 = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=11)
        unused_xyz_cid_12 = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nid_cp_cd[:, 0], icp_transform, cid=12)
Esempio n. 28
0
def sum_forces_moments(model: BDF, p0: np.ndarray, loadcase_id: int,
                       cid: int=0,
                       include_grav: bool=False,
                       xyz_cid0: Optional[Dict[int, NDArray3float]]=None,
                       ) -> Tuple[NDArray3float, NDArray3float]:
    """
    Sums applied forces & moments about a reference point p0 for all
    load cases.

    Considers:
      - FORCE, FORCE1, FORCE2
      - MOMENT, MOMENT1, MOMENT2
      - PLOAD, PLOAD2, PLOAD4
      - LOAD

    Parameters
    ----------
    model : BDF()
        a BDF object
    p0 : NUMPY.NDARRAY shape=(3,) or integer (node ID)
        the reference point
    loadcase_id : int
        the LOAD=ID to analyze
    cid : int; default=0
        the coordinate system for the summation
    include_grav : bool; default=False
        includes gravity in the summation (not supported)
    xyz_cid0 : None / Dict[int] = (3, ) ndarray
        the nodes in the global coordinate system

    Returns
    -------
    forces : NUMPY.NDARRAY shape=(3,)
        the forces
    moments : NUMPY.NDARRAY shape=(3,)
        the moments

    .. warning:: not full validated
    .. todo:: It's super slow for cid != 0.   We can speed this up a lot
             if we calculate the normal, area, centroid based on
             precomputed node locations.

    Pressure acts in the normal direction per model/real/loads.bdf and loads.f06

    """
    if not isinstance(loadcase_id, integer_types):
        raise RuntimeError('loadcase_id must be an integer; loadcase_id=%r' % loadcase_id)

    p = _get_load_summation_point(model, p0, cid=0)
    loads, scale_factors, unused_is_grav = model.get_reduced_loads(
        loadcase_id, skip_scale_factor0=True)

    F = array([0., 0., 0.])
    M = array([0., 0., 0.])
    xyz = get_xyz_cid0_dict(model, xyz_cid0=xyz_cid0)

    unsupported_types = set()
    for load, scale in zip(loads, scale_factors):
        #if load.type not in ['FORCE1']:
            #continue
        if load.type == 'FORCE':
            if load.Cid() != 0:
                cp_ref = load.cid_ref
                #from pyNastran.bdf.bdf import CORD2R
                #cp_ref = CORD2R()
                f = load.mag * cp_ref.transform_vector_to_global(load.xyz) * scale
            else:
                f = load.mag * load.xyz * scale

            node = model.Node(load.node_id)
            r = xyz[node.nid] - p
            m = cross(r, f)
            F += f
            M += m
        elif load.type == 'FORCE1':
            f = load.mag * load.xyz * scale
            node = model.Node(load.node_id)
            r = xyz[node.nid] - p
            m = cross(r, f)
            F += f
            M += m
        elif load.type == 'FORCE2':
            f = load.mag * load.xyz * scale
            node = model.Node(load.node_id)
            r = xyz[node.nid] - p
            m = cross(r, f)
            F += f
            M += m
        elif load.type == 'MOMENT':
            if load.Cid() != 0:
                cp = load.cid_ref
                #from pyNastran.bdf.bdf import CORD2R
                #cp = CORD2R()
                m = load.mag * cp.transform_vector_to_global(load.xyz) * scale
            else:
                m = load.mag * load.xyz * scale
            M += m
        elif load.type == 'MOMENT1':
            m = load.mag * load.xyz * scale
            M += m
        elif load.type == 'MOMENT2':
            m = load.mag * load.xyz * scale
            M += m

        elif load.type == 'PLOAD':
            nodes = load.node_ids
            nnodes = len(nodes)
            if nnodes == 3:
                n1, n2, n3 = xyz[nodes[0]], xyz[nodes[1]], xyz[nodes[2]]
                axb = cross(n1 - n2, n1 - n3)
                centroid = (n1 + n2 + n3) / 3.
            elif nnodes == 4:
                n1, n2, n3, n4 = xyz[nodes[0]], xyz[nodes[1]], xyz[nodes[2]], xyz[nodes[3]]
                axb = cross(n1 - n3, n2 - n4)
                centroid = (n1 + n2 + n3 + n4) / 4.
            else:
                msg = 'invalid number of nodes on PLOAD card; nodes=%s' % str(nodes)
                raise RuntimeError(msg)

            area, normal = _get_area_normal(axb, nodes, xyz)
            r = centroid - p
            f = load.pressure * area * normal * scale
            m = cross(r, f)

            F += f
            M += m

        elif load.type == 'PLOAD1':
            _pload1_total(model, loadcase_id, load, scale, xyz, F, M, p)

        elif load.type == 'PLOAD2':
            pressure = load.pressure * scale
            for eid in load.element_ids:
                elem = model.elements[eid]
                if elem.type in ['CTRIA3', 'CQUAD4', 'CSHEAR', 'CQUADR', 'CTRIAR']:
                    n = elem.Normal()
                    area = elem.Area()
                    f = pressure * n * area
                    r = elem.Centroid() - p
                    m = cross(r, f)
                    F += f
                    M += m
                else:
                    model.log.warning('case=%s etype=%r loadtype=%r not supported' % (
                        loadcase_id, elem.type, load.type))
        elif load.type == 'PLOAD4':
            _pload4_total(loadcase_id, load, scale, xyz, F, M, p)

        elif load.type == 'GRAV':
            if include_grav:  # this will be super slow
                gravity = load.GravityVector() * scale
                for eid, elem in model.elements.items():
                    centroid = elem.Centroid()
                    mass = elem.Mass()
                    r = centroid - p
                    f = mass * gravity
                    m = cross(r, f)
                    F += f
                    M += m
        else:
            # we collect them so we only get one print
            unsupported_types.add(load.type)

    for load_type in unsupported_types:
        model.log.warning('case=%s loadtype=%r not supported' % (loadcase_id, load_type))

    #forces, moments = sum_forces_moments(self, p0, loadcase_id,
    #include_grav=include_grav, xyz_cid0=xyz_cid0)
    if cid == 0:
        return F, M
    cid0 = 0
    F2, M2 = transform_load(F, M, cid0, cid, model)
    return F2, M2
Esempio n. 29
0
    def test_cord2_rcs_03(self):
        """
        all points are located at <30,40,50>
        """
        model = BDF(debug=False)
        cards = [
            [
                'CORD2S*                2               0              0.              0.',
                '*                     0.              0.              0.              1.*       ',
                '*                     1.              0.              1.',],
            [
                #'$ Coordinate System 30 : rectangular in spherical',
                'CORD2R*               30               2             14.             30.',
                '*                    70.    13.431863852   32.1458443949   75.2107442927*       ',
                '*          14.4583462334   33.4569982885   68.2297989286',],
            [
                #'$ Coordinate System 31 : cylindrical in spherical',
                'CORD2C*               31               2              3.             42.',
                '*                  -173.   2.86526881213   45.5425615252   159.180363517*       ',
                '*          3.65222385965   29.2536614627  -178.631312271',],
            [
                #'$ Coordinate System 32 : spherical in spherical',
                'CORD2S*               32               2             22.             14.',
                '*                    85.   22.1243073983   11.9537753718   77.9978191005*       ',
                '*          21.0997242967   13.1806120497   88.4824763008',],
            [
                'GRID*                 30              30   40.7437952957  -23.6254877994',
                '*           -33.09784854               0',],
            [
                'GRID*                 31              31   62.9378078196   15.9774797923',
                '*          31.0484428362               0',],
            [
                'GRID*                 32              32   53.8270847449   95.8215692632',
                '*          159.097767463               0',],
        ]
        for lines in cards:
            card = model._process_card(lines)
            model.add_card(card, card[0])
        unused_xyz_cid0b = model.get_xyz_in_coord_no_xref(cid=0, fdtype='float64')
        unused_xyz_cid0c = model.get_xyz_in_coord_no_xref(cid=32, fdtype='float64')
        bdf_file = StringIO()
        model.write_bdf(bdf_file, close=False)
        bdf_file.seek(0)

        #-------------------------------------------------
        model.cross_reference()

        model2 = BDFv(debug=False)
        model2.read_bdf(bdf_file, punch=True, xref=False, save_file_structure=False)
        bdf_file.seek(0)
        #-------------------------------------------------

        xyz_cid0_actual = array([
            [30., 40., 50.],
            [30., 40., 50.],
            [30., 40., 50.],
        ], dtype='float64')
        for nid in model.nodes:
            node = model.Node(nid)
            a = array([30., 40., 50.])
            b = node.get_position()
            self.assertTrue(allclose(array([30., 40., 50.]),
                                     node.get_position()), str(a - b))
        xyz_cid0 = model.get_xyz_in_coord(cid=0, fdtype='float64')
        assert np.allclose(xyz_cid0_actual, xyz_cid0), '%s' % (xyz_cid0_actual - xyz_cid0)

        out = model.get_displacement_index_xyz_cp_cd()
        unused_icd_transform, icp_transform, xyz_cp, nid_cp_cd = out
        nids = nid_cp_cd[:, 0]
        xyz_cid0_xform = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nids, icp_transform, cid=0)
        array_equal(xyz_cid0_actual, xyz_cid0_xform)
        assert array_equal(nids, array([30, 31, 32]))
        model2.nodes.nids = nid_cp_cd[:, 0]


        for cid in [30, 31, 32]:
            unused_xyz_cid_a = model.transform_xyzcp_to_xyz_cid(
                xyz_cp, nids, icp_transform, cid=cid)
            unused_xyz_cid_b = model2.transform_xyzcp_to_xyz_cid(
                xyz_cp, nids, icp_transform, cid=cid, atol=None)
            #assert np.allclose(xyz_cid_a, xyz_cid_b), '%s' % np.isclose(xyz_cid_a, xyz_cid_b)

            #print(xyz_cid_a)
            #print(xyz_cid_b)
            #print(xyz_cid_a - xyz_cid_b)
            #print('-------------')
            #assert array_equal(xyz_cid_a, xyz_cid_b), 'error=%s'  % (
                #xyz_cid_a - xyz_cid_b)

        #---------------------------------------------
        xyz_cid0 = model.transform_xyzcp_to_xyz_cid(
            xyz_cp, nids, icp_transform,
            cid=0, atol=None)
        array_equal(xyz_cid0_actual, xyz_cid0)

        model.write_bdf(bdf_file, close=False)

        model3 = BDF(debug=False)
        origin = [14., 30., 70.]
        zaxis = [13.431863852, 32.1458443949, 75.2107442927]
        xzplane = [14.4583462334, 33.4569982885, 68.2297989286]
        cord2r = model3.add_cord2r(30, origin, zaxis, xzplane, rid=2, comment='')

        origin = [3., 42., -173.]
        zaxis = [2.86526881213, 45.5425615252, 159.180363517]
        xzplane = [3.65222385965, 29.2536614627, -178.631312271]
        cord2c = model3.add_cord2c(31, origin, zaxis, xzplane, rid=2, comment='')

        origin = [22., 14., 85.]
        zaxis = [22.1243073983, 11.9537753718, 77.9978191005]
        xzplane = [21.0997242967, 13.1806120497, 88.4824763008]
        cord2s = model3.add_cord2s(32, origin, zaxis, xzplane, rid=2, comment='')

        assert cord2r == model.coords[cord2r.cid], 'cord2r:\n%r\ncord2r[cid]:\n%r' % (str(cord2r), str(model.coords[cord2r.cid]))
        assert cord2c == model.coords[cord2c.cid], 'cord2c:\n%r\ncord2c[cid]:\n%r' % (str(cord2c), str(model.coords[cord2c.cid]))
        assert cord2s == model.coords[cord2s.cid], 'cord2s:\n%r\ncord2s[cid]:\n%r' % (str(cord2s), str(model.coords[cord2s.cid]))
Esempio n. 30
0
def sum_forces_moments_elements(model: BDF, p0: int, loadcase_id: int,
                                eids: List[int], nids: List[int],
                                cid: int=0,
                                include_grav: bool=False,
                                xyz_cid0: Optional[Dict[int, NDArray3float]]=None,
                                ) -> Tuple[NDArray3float, NDArray3float]:
    """
    Sum the forces/moments based on a list of nodes and elements.

    Parameters
    ----------
    model : BDF()
        a BDF object
    eids : List[int]
        the list of elements to include (e.g. the loads due to a PLOAD4)
    nids : List[int]
        the list of nodes to include (e.g. the loads due to a FORCE card)
    p0 : int; (3,) ndarray
       the point to sum moments about
       type = int
           sum moments about the specified grid point
       type = (3, ) ndarray/list (e.g. [10., 20., 30]):
           the x, y, z location in the global frame
    loadcase_id : int
        the LOAD=ID to analyze
    include_grav : bool; default=False
        includes gravity in the summation (not supported)
    xyz_cid0 : None / Dict[int] = (3, ) ndarray
        the nodes in the global coordinate system

    Returns
    -------
    forces : NUMPY.NDARRAY shape=(3,)
        the forces
    moments : NUMPY.NDARRAY shape=(3,)
        the moments

    Nodal Types  : FORCE, FORCE1, FORCE2,
                   MOMENT, MOMENT1, MOMENT2,
                   PLOAD
    Element Types: PLOAD1, PLOAD2, PLOAD4, GRAV

    If you have a CQUAD4 (eid=3) with a PLOAD4 (sid=3) and a FORCE
    card (nid=5) acting on it, you can incldue the PLOAD4, but
    not the FORCE card by using:

    For just pressure:

    .. code-block:: python

       eids = [3]
       nids = []

    For just force:

    .. code-block:: python

       eids = []
       nids = [5]

    or both:

    .. code-block:: python

       eids = [3]
       nids = [5]

    .. note:: If you split the model into sections and sum the loads
              on each section, you may not get the same result as
              if you summed the loads on the total model.  This is
              due to the fact that nodal loads on the boundary are
              double/triple/etc. counted depending on how many breaks
              you have.

    .. todo:: not done...

    """
    if not isinstance(loadcase_id, integer_types):
        raise RuntimeError('loadcase_id must be an integer; loadcase_id=%r' % loadcase_id)
    p = _get_load_summation_point(model, p0, cid=0)

    if eids is None:
        eids = list(model.element_ids)
    if nids is None:
        nids = list(model.node_ids)

    #for (key, load_case) in model.loads.items():
        #if key != loadcase_id:
            #continue

    loads, scale_factors, unused_is_grav = model.get_reduced_loads(
        loadcase_id, skip_scale_factor0=True)

    F = array([0., 0., 0.])
    M = array([0., 0., 0.])

    xyz = get_xyz_cid0_dict(model, xyz_cid0)

    unsupported_types = set()
    shell_elements = {
        'CTRIA3', 'CQUAD4', 'CTRIAR', 'CQUADR',
        'CTRIA6', 'CQUAD8', 'CQUAD', 'CSHEAR'}
    skip_loads = {'QVOL'}
    for load, scale in zip(loads, scale_factors):
        #if load.type not in ['FORCE1']:
            #continue
        #print(load.type)
        loadtype = load.type
        if loadtype == 'FORCE':
            if load.node_id not in nids:
                continue
            if load.Cid() != 0:
                cp_ref = load.cid_ref
                #from pyNastran.bdf.bdf import CORD2R
                #cp = CORD2R()
                f = load.mag * cp_ref.transform_vector_to_global(load.xyz) * scale
            else:
                f = load.mag * load.xyz * scale

            node = model.Node(load.node_id)
            r = xyz[node.nid] - p
            m = cross(r, f)
            F += f
            M += m

        elif load.type == 'FORCE1':
            not_found_nid = False
            for nid in load.node_ids:
                if nid not in nids:
                    not_found_nid = True
                    break
            if not_found_nid:
                continue

            f = load.mag * load.xyz * scale
            node = model.Node(load.node_id)
            r = xyz[node.nid] - p
            m = cross(r, f)
            F += f
            M += m
        elif load.type == 'FORCE2':
            not_found_nid = False
            for nid in load.node_ids:
                if nid not in nids:
                    not_found_nid = True
                    break
            if not_found_nid:
                continue

            f = load.mag * load.xyz * scale
            node = model.Node(load.node_id)
            r = xyz[node.nid] - p
            m = cross(r, f)
            F += f
            M += m
        elif load.type == 'MOMENT':
            not_found_nid = False
            for nid in load.node_ids:
                if nid not in nids:
                    not_found_nid = True
                    break
            if not_found_nid:
                continue

            if load.Cid() != 0:
                cp_ref = load.cid_ref
                m = cp_ref.transform_vector_to_global(load.xyz)
            else:
                m = load.xyz
            M += load.mag * m * scale
        elif load.type == 'MOMENT1':
            not_found_nid = False
            for nid in load.node_ids:
                if nid not in nids:
                    not_found_nid = True
                    break
            if not_found_nid:
                continue
            m = load.mag * load.xyz * scale
            M += m
        elif loadtype == 'MOMENT2':
            not_found_nid = False
            for nid in load.node_ids:
                if nid not in nids:
                    not_found_nid = True
                    break
            if not_found_nid:
                continue
            m = load.mag * load.xyz * scale
            M += m

        elif loadtype == 'PLOAD':
            nodes = load.node_ids
            nnodes = len(nodes)
            nodesi = 0
            if nnodes == 3:
                n1, n2, n3 = xyz[nodes[0]], xyz[nodes[1]], xyz[nodes[2]]
                axb = cross(n1 - n2, n1 - n3)
                centroid = (n1 + n2 + n3) / 3.

            elif nnodes == 4:
                n1, n2, n3, n4 = xyz[nodes[0]], xyz[nodes[1]], xyz[nodes[2]], xyz[nodes[3]]
                axb = cross(n1 - n3, n2 - n4)
                centroid = (n1 + n2 + n3 + n4) / 4.
                if nodes[3] in nids:
                    nodesi += 1
            else:
                raise RuntimeError('invalid number of nodes on PLOAD card; '
                                   'nodes=%s' % str(nodes))
            if nodes[0] in nids:
                nodesi += 1
            if nodes[1] in nids:
                nodesi += 1
            if nodes[2] in nids:
                nodesi += 1

            area, normal = _get_area_normal(axb, nodes, xyz)
            r = centroid - p
            f = load.pressure * area * normal * scale
            m = cross(r, f)

            node_scale = nodesi / float(nnodes)
            F += f * node_scale
            M += m * node_scale

        elif loadtype == 'PLOAD1':
            _pload1_elements(model, loadcase_id, load, scale, eids, xyz, F, M, p)

        elif loadtype == 'PLOAD2':
            pressure = load.pressure * scale
            for eid in load.element_ids:
                if eid not in eids:
                    continue
                elem = model.elements[eid]
                if elem.type in shell_elements:
                    normal = elem.Normal()
                    area = elem.Area()
                    f = pressure * normal * area
                    r = elem.Centroid() - p
                    m = cross(r, f)
                    F += f
                    M += m
                else:
                    #model.log.warning('case=%s etype=%r loadtype=%r not supported' % (
                        #loadcase_id, elem.type, loadtype))
                    raise NotImplementedError('case=%s etype=%r loadtype=%r not supported' % (
                        loadcase_id, elem.type, loadtype))
        elif loadtype == 'PLOAD4':
            _pload4_elements(loadcase_id, load, scale, eids, xyz, F, M, p)

        elif loadtype == 'GRAV':
            if include_grav:  # this will be super slow
                g = load.GravityVector() * scale
                for eid, elem in model.elements.items():
                    if eid not in eids:
                        continue
                    centroid = elem.Centroid()
                    mass = elem.Mass()
                    r = centroid - p
                    f = mass * g
                    m = cross(r, f)
                    F += f
                    M += m
        elif loadtype in skip_loads:
            continue
        else:
            # we collect them so we only get one print
            unsupported_types.add(loadtype)

    for loadtype in unsupported_types:
        model.log.warning('case=%s loadtype=%r not supported' % (loadcase_id, loadtype))
    #model.log.info("case=%s F=%s M=%s\n" % (loadcase_id, F, M))

    if cid == 0:
        return F, M
    cid0 = 0
    F2, M2 = transform_load(F, M, cid0, cid, model)
    return F2, M2