Пример #1
0
    def _get_bar_yz_arrays(self, model, bar_beam_eids, scale, debug):
        lines_bar_y = []
        lines_bar_z = []
        points_list = []

        bar_types = {
            # PBAR
            'bar' : [],

            # PBEAML/PBARL
            "ROD": [],
            "TUBE": [],
            "TUBE2" : [],
            "I": [],
            "CHAN": [],
            "T": [],
            "BOX": [],
            "BAR": [],
            "CROSS": [],
            "H": [],
            "T1": [],
            "I1": [],
            "CHAN1": [],
            "Z": [],
            "CHAN2": [],
            "T2": [],
            "BOX1": [],
            "HEXA": [],
            "HAT": [],
            "HAT1": [],
            "DBOX": [],  # was 12

            # PBEAM
            'beam' : [],

            # PBEAML specfic
            "L" : [],
        }  # for GROUP="MSCBML0"
        allowed_types = [
            'BAR', 'BOX', 'BOX1', 'CHAN', 'CHAN1', 'CHAN2', 'CROSS', 'DBOX',
            'H', 'HAT', 'HAT1', 'HEXA', 'I', 'I1', 'L', 'ROD',
            'T', 'T1', 'T2', 'TUBE', 'TUBE2', 'Z', 'bar', 'beam',
        ]

        # bar_types['bar'] = [ [...], [...], [...] ]
        #bar_types = defaultdict(lambda : defaultdict(list))

        found_bar_types = set([])
        #neids = len(self.element_ids)
        for bar_type, data in iteritems(bar_types):
            eids = []
            lines_bar_y = []
            lines_bar_z = []
            bar_types[bar_type] = (eids, lines_bar_y, lines_bar_z)
            #bar_types[bar_type] = [eids, lines_bar_y, lines_bar_z]

        ugrid = vtk.vtkUnstructuredGrid()
        node0 = 0

        nid_release_map = defaultdict(list)

        #debug = True
        bar_nids = set([])
        #print('bar_beam_eids = %s' % bar_beam_eids)
        for eid in bar_beam_eids:
            if eid not in self.eid_map:
                self.log.error('eid=%s is not a valid bar/beam element...' % eid)
                if debug:  # pragma: no cover
                    print('eid=%s is not a valid bar/beam element...' % eid)
                continue
            #unused_ieid = self.eid_map[eid]
            elem = model.elements[eid]
            pid_ref = elem.pid_ref
            if pid_ref is None:
                pid_ref = model.Property(elem.pid)
            assert not isinstance(pid_ref, integer_types), elem

            ptype = pid_ref.type
            bar_type = _get_bar_type(ptype, pid_ref)

            if debug:  # pragma: no cover
                print('%s' % elem)
                print('  bar_type =', bar_type)
            found_bar_types.add(bar_type)

            (nid1, nid2) = elem.node_ids
            bar_nids.update([nid1, nid2])
            node1 = model.nodes[nid1]
            node2 = model.nodes[nid2]
            n1 = node1.get_position()
            n2 = node2.get_position()

            # wa/wb are not considered in i_offset
            # they are considered in ihat
            i = n2 - n1
            Li = norm(i)
            ihat = i / Li

            if elem.pa != 0:
                nid_release_map[nid1].append((eid, elem.pa))
            if elem.pb != 0:
                nid_release_map[nid2].append((eid, elem.pb))

            unused_v, wa, wb, xform = rotate_v_wa_wb(
                model, elem,
                n1, n2, node1, node2,
                ihat, i, eid, Li)
            if wb is None:
                # one or more of v, wa, wb are bad
                continue

            yhat = xform[1, :]
            zhat = xform[2, :]

            ## concept has a GOO

            #if debug:  # pragma: no cover
                #print('  centroid = %s' % centroid)
                #print('  ihat = %s' % ihat)
                #print('  yhat = %s' % yhat)
                #print('  zhat = %s' % zhat)
                #print('  scale = %s' % scale)
            #if eid == 616211:
                #print('  check - eid=%s yhat=%s zhat=%s v=%s i=%s n%s=%s n%s=%s' % (
                      #eid, yhat, zhat, v, i, nid1, n1, nid2, n2))

                #print('adding bar %s' % bar_type)
                #print('   centroid=%s' % centroid)
                #print('   yhat=%s len=%s' % (yhat, np.linalg.norm(yhat)))
                #print('   zhat=%s len=%s' % (zhat, np.linalg.norm(zhat)))
                #print('   Li=%s scale=%s' % (Li, scale))
            if bar_type not in allowed_types:
                msg = 'bar_type=%r allowed=[%s]' % (bar_type, ', '.join(allowed_types))
                raise RuntimeError(msg)

            if bar_type in BEAM_GEOM_TYPES:
                node0 = add_3d_bar_element(
                    bar_type, ptype, pid_ref,
                    n1+wa, n2+wb, xform,
                    ugrid, node0, points_list)

            centroid = (n1 + n2) / 2.
            bar_types[bar_type][0].append(eid)
            bar_types[bar_type][1].append((centroid, centroid + yhat * Li * scale))
            bar_types[bar_type][2].append((centroid, centroid + zhat * Li * scale))

        if node0: # and '3d_bars' not in self.alt_grids:
            def update_grid_function(unused_nid_map, ugrid, points, nodes):  # pragma: no cover
                """custom function to update the 3d bars"""
                points_list = []
                node0b = 0
                for eid in bar_beam_eids:
                    elem = self.model.elements[eid]
                    pid_ref = elem.pid_ref
                    if pid_ref is None:
                        pid_ref = self.model.Property(elem.pid)
                    assert not isinstance(pid_ref, integer_types), elem

                    ptype = pid_ref.type
                    bar_type = _get_bar_type(ptype, pid_ref)

                    #nids = elem.nodes
                    (nid1, nid2) = elem.node_ids
                    node1 = model.nodes[nid1]
                    node2 = model.nodes[nid2]

                    i1, i2 = np.searchsorted(self.node_ids, [nid1, nid2])
                    n1 = nodes[i1, :]
                    n2 = nodes[i2, :]
                    #centroid = (n1 + n2) / 2.

                    i = n2 - n1
                    Li = norm(i)
                    ihat = i / Li

                    unused_v, wa, wb, xform = rotate_v_wa_wb(
                        model, elem,
                        n1, n2, node1, node2,
                        ihat, i, eid, Li)
                    if wb is None:
                        # one or more of v, wa, wb are bad
                        continue

                    ugridi = None
                    node0b = add_3d_bar_element(
                        bar_type, ptype, pid_ref,
                        n1+wa, n2+wb, xform,
                        ugridi, node0b, points_list, add_to_ugrid=False)

                points_array = _make_points_array(points_list)

                points_array2 = numpy_to_vtk(
                    num_array=points_array,
                    deep=1,
                    array_type=vtk.VTK_FLOAT,
                )
                points.SetData(points_array2)

                ugrid.SetPoints(points)
                points.Modified()
                ugrid.Modified()
                return

            if points_list:
                if not sys.argv[0].startswith('test_'):
                    update_grid_function = None
                self.gui.create_alternate_vtk_grid(
                    '3d_bars', color=BLUE, opacity=0.2,
                    representation='surface', is_visible=True,
                    follower_function=update_grid_function,
                    ugrid=ugrid,
                )
                points_array = _make_points_array(points_list)
                points = numpy_to_vtk_points(points_array)
                ugrid.SetPoints(points)

        #print('bar_types =', bar_types)
        for bar_type in list(bar_types):
            bars = bar_types[bar_type]
            if len(bars[0]) == 0:
                del bar_types[bar_type]
                continue
            #bar_types[bar_type][1] = np.array(bars[1], dtype='float32')  # lines_bar_y
            #bar_types[bar_type][2] = np.array(bars[2], dtype='float32')  # lines_bar_z

        debug = False
        if debug:  # pragma: no cover
            #np.set_printoptions(formatter={'float': '{: 0.3f}'.format})
            for bar_type, data in sorted(iteritems(bar_types)):
                eids, lines_bar_y, lines_bar_z = data
                if len(eids):
                    #print('barsi =', barsi)
                    #print('bar_type = %r' % bar_type)
                    for eid, line_y, line_z  in zip(eids, lines_bar_y, lines_bar_z):
                        print('eid=%s centroid=%s cy=%s cz=%s' % (
                            eid, line_y[0], line_y[1], line_z[1]))

        #print('found_bar_types =', found_bar_types)
        #no_axial_torsion = (no_axial, no_torsion)
        #no_shear_bending = (no_shear_y, no_shear_z, no_bending_y, no_bending_z)
        #no_dofs = (no_bending, no_bending_bad, no_6_16, no_0_456,
                   #no_0_56, no_56_456, no_0_6, no_0_16)
        return bar_nids, bar_types, nid_release_map
Пример #2
0
    def _get_bar_yz_arrays(self, model, bar_beam_eids, scale, debug):
        lines_bar_y = []
        lines_bar_z = []

        bar_types = {
            # PBAR
            'bar' : [],

            # PBEAML/PBARL
            "ROD": [],
            "TUBE": [],
            "TUBE2" : [],
            "I": [],
            "CHAN": [],
            "T": [],
            "BOX": [],
            "BAR": [],
            "CROSS": [],
            "H": [],
            "T1": [],
            "I1": [],
            "CHAN1": [],
            "Z": [],
            "CHAN2": [],
            "T2": [],
            "BOX1": [],
            "HEXA": [],
            "HAT": [],
            "HAT1": [],
            "DBOX": [],  # was 12

            # PBEAM
            'beam' : [],

            # PBEAML specfic
            "L" : [],
        }  # for GROUP="MSCBML0"
        allowed_types = [
            'BAR', 'BOX', 'BOX1', 'CHAN', 'CHAN1', 'CHAN2', 'CROSS', 'DBOX',
            'H', 'HAT', 'HAT1', 'HEXA', 'I', 'I1', 'L', 'ROD',
            'T', 'T1', 'T2', 'TUBE', 'TUBE2', 'Z', 'bar', 'beam',
        ]

        # bar_types['bar'] = [ [...], [...], [...] ]
        #bar_types = defaultdict(lambda : defaultdict(list))

        found_bar_types = set([])
        #neids = len(self.element_ids)
        for bar_type, data in iteritems(bar_types):
            eids = []
            lines_bar_y = []
            lines_bar_z = []
            bar_types[bar_type] = (eids, lines_bar_y, lines_bar_z)
            #bar_types[bar_type] = [eids, lines_bar_y, lines_bar_z]

        nid_release_map = defaultdict(list)

        #debug = True
        bar_nids = set([])
        #print('bar_beam_eids = %s' % bar_beam_eids)
        for eid in bar_beam_eids:
            if eid not in self.eid_map:
                self.log.error('eid=%s is not a valid bar/beam element...' % eid)
                if debug:
                    print('eid=%s is not a valid bar/beam element...' % eid)
                continue
            ieid = self.eid_map[eid]
            elem = model.elements[eid]
            pid = elem.pid_ref
            assert not isinstance(pid, integer_types), elem
            if pid.type in ['PBAR', 'PBEAM']:
                bar_type = 'bar'
            elif pid.type in ['PBEAM']:
                bar_type = 'beam'
            elif pid.type in ['PBARL', 'PBEAML']:
                bar_type = pid.Type
            else:
                if debug:
                    print('NotImplementedError(pid)')
                raise NotImplementedError(pid)
            #print('bar_type =', bar_type)

            if debug:
                print('%s' % elem)
                print('  bar_type =', bar_type)
            found_bar_types.add(bar_type)

            (nid1, nid2) = elem.node_ids
            bar_nids.update([nid1, nid2])
            node1 = model.nodes[nid1]
            node2 = model.nodes[nid2]
            n1 = node1.get_position()
            n2 = node2.get_position()
            centroid = (n1 + n2) / 2.
            i = n2 - n1
            Li = norm(i)
            ihat = i / Li

            if elem.pa != 0:
                #assert elem.pa in [], elem.pa
                nid_release_map[nid1].append((eid, elem.pa))
            if elem.pb != 0:
                nid_release_map[nid2].append((eid, elem.pb))


            # OFFT flag
            # ---------
            # ABC or A-B-C (an example is G-G-G or B-G-G)
            # while the slots are:
            #  - A -> orientation; values=[G, B]
            #  - B -> End A; values=[G, O]
            #  - C -> End B; values=[G, O]
            #
            # and the values for A,B,C mean:
            #  - B -> basic
            #  - G -> global
            #  - O -> orientation
            #
            # so for example G-G-G, that's global for all terms.
            # BOG means basic orientation, orientation end A, global end B
            #
            # so now we're left with what does basic/global/orientation mean?
            # - basic -> the glboal coordinate system defined by cid=0
            # - global -> the local coordinate system defined by the
            #             CD field on the GRID card, but referenced by
            #             the CBAR/CBEAM
            # - orientation -> ???
            #
            if elem.g0:
                #debug = False
                msg = 'which is required by %s eid=%s\n%s' % (elem.type, elem.g0, str(elem))
                g0_ref = model.Node(elem.g0, msg=msg)
                if debug:
                    print('  g0 = %s' % elem.g0)
                    print('  g0_ref = %s' % g0_ref)
                n0 = g0_ref.get_position()
                v = n0 - n1
            else:
                #debug = False
                ga = model.nodes[elem.Ga()]
                cda = ga.Cd()
                cda_ref = model.Coord(cda)
                v = cda_ref.transform_node_to_global(elem.x)
                if debug:
                    print('  ga = %s' % elem.ga)
                    if cda != 0:
                        print('  cd = %s' % cda_ref)
                    else:
                        print('  cd = 0')

                    print('  x = %s' % elem.x)
                    print('  v = %s' % v)
                #v = elem.x

            offt_vector, offt_end_a, offt_end_b = elem.offt
            if debug:
                print('  offt vector,A,B=%r' % (elem.offt))
            # if offt_end_a == 'G' or (offt_end_a == 'O' and offt_vector == 'G'):

            cd1 = node1.Cd()
            cd2 = node2.Cd()
            cd1_ref = model.Coord(cd1)
            cd2_ref = model.Coord(cd2)
            # node1.cd_ref, node2.cd_ref

            if offt_vector == 'G':
                # end A
                # global - cid != 0
                if cd1 != 0:
                    v = cd1_ref.transform_node_to_global_assuming_rectangular(v)
                    #if node1.cd_ref.type not in ['CORD2R', 'CORD1R']:
                        #msg = 'invalid Cd type (%r) on Node %i; expected CORDxR' % (
                            #node1.cd_ref.type, node1.nid)
                        #self.log.error(msg)
                        #continue
                        #raise NotImplementedError(node1.cd)
            elif offt_vector == 'B':
                # basic - cid = 0
                pass
            else:
                msg = 'offt_vector=%r is not supported; offt=%s' % (offt_vector, elem.offt)
                self.log.error(msg)
                continue
                #raise NotImplementedError(msg)
            #print('v = %s' % v)

            # rotate wa
            wa = elem.wa
            if offt_end_a == 'G':
                if cd1 != 0:
                    #if node1.cd.type not in ['CORD2R', 'CORD1R']:
                        #continue # TODO: support CD transform
                    # TODO: fixme
                    wa = cd1_ref.transform_node_to_global_assuming_rectangular(wa)
            elif offt_end_a == 'B':
                pass
            elif offt_end_a == 'O':
                # TODO: fixme
                wa = cd1_ref.transform_node_to_global_assuming_rectangular(n1 - wa)
            else:
                msg = 'offt_end_a=%r is not supported; offt=%s' % (offt_end_a, elem.offt)
                self.log.error(msg)
                continue
                #raise NotImplementedError(msg)

            #print('wa = %s' % wa)
            # rotate wb
            wb = elem.wb
            if offt_end_b == 'G':
                if cd2 != 0:
                    #if cd2_ref.type not in ['CORD2R', 'CORD1R']:
                        #continue # TODO: MasterModelTaxi
                    # TODO: fixme
                    wb = cd2_ref.transform_node_to_global_assuming_rectangular(wb)

            elif offt_end_b == 'B':
                pass
            elif offt_end_b == 'O':
                # TODO: fixme
                wb = cd1_ref.transform_node_to_global(n2 - wb)
            else:
                msg = 'offt_end_b=%r is not supported; offt=%s' % (offt_end_b, elem.offt)
                model.log.error(msg)
                continue
                #raise NotImplementedError(msg)

            #print('wb =', wb)
            ## concept has a GOO
            #if not elem.offt in ['GGG', 'BGG']:
                #msg = 'offt=%r for CBAR/CBEAM eid=%s is not supported...skipping' % (
                    #elem.offt, eid)
                #self.log.error(msg)
                #continue

            vhat = v / norm(v) # j
            try:
                z = np.cross(ihat, vhat) # k
            except ValueError:
                msg = 'Invalid vector length\n'
                msg += 'n1  =%s\n' % str(n1)
                msg += 'n2  =%s\n' % str(n2)
                msg += 'nid1=%s\n' % str(nid1)
                msg += 'nid2=%s\n' % str(nid2)
                msg += 'i   =%s\n' % str(i)
                msg += 'Li  =%s\n' % str(Li)
                msg += 'ihat=%s\n' % str(ihat)
                msg += 'v   =%s\n' % str(v)
                msg += 'vhat=%s\n' % str(vhat)
                msg += 'z=cross(ihat, vhat)'
                print(msg)
                raise ValueError(msg)

            zhat = z / norm(z)
            yhat = np.cross(zhat, ihat) # j
            if debug:
                print('  centroid = %s' % centroid)
                print('  ihat = %s' % ihat)
                print('  yhat = %s' % yhat)
                print('  zhat = %s' % zhat)
                print('  scale = %s' % scale)
            #if eid == 5570:
                #print('  check - eid=%s yhat=%s zhat=%s v=%s i=%s n%s=%s n%s=%s' % (
                      #eid, yhat, zhat, v, i, nid1, n1, nid2, n2))

            if norm(ihat) == 0.0 or norm(yhat) == 0.0 or norm(z) == 0.0:
                print('  invalid_orientation - eid=%s yhat=%s zhat=%s v=%s i=%s n%s=%s n%s=%s' % (
                    eid, yhat, zhat, v, i, nid1, n1, nid2, n2))
            elif not np.allclose(norm(yhat), 1.0) or not np.allclose(norm(zhat), 1.0) or Li == 0.0:
                print('  length_error        - eid=%s Li=%s Lyhat=%s Lzhat=%s'
                      ' v=%s i=%s n%s=%s n%s=%s' % (
                          eid, Li, norm(yhat), norm(zhat), v, i, nid1, n1, nid2, n2))

            #print('adding bar %s' % bar_type)
            #print('   centroid=%s' % centroid)
            #print('   yhat=%s len=%s' % (yhat, np.linalg.norm(yhat)))
            #print('   zhat=%s len=%s' % (zhat, np.linalg.norm(zhat)))
            #print('   Li=%s scale=%s' % (Li, scale))
            if bar_type not in allowed_types:
                msg = 'bar_type=%r allowed=[%s]' % (bar_type, ', '.join(allowed_types))
                raise RuntimeError(msg)

            bar_types[bar_type][0].append(eid)
            bar_types[bar_type][1].append((centroid, centroid + yhat * Li * scale))
            bar_types[bar_type][2].append((centroid, centroid + zhat * Li * scale))
            #if len(bar_types[bar_type][0]) > 5:
                #break

        #print('bar_types =', bar_types)
        for bar_type in list(bar_types):
            bars = bar_types[bar_type]
            if len(bars[0]) == 0:
                del bar_types[bar_type]
                continue
            #bar_types[bar_type][1] = np.array(bars[1], dtype='float32')  # lines_bar_y
            #bar_types[bar_type][2] = np.array(bars[2], dtype='float32')  # lines_bar_z

        debug = False
        if debug:
            #np.set_printoptions(formatter={'float': '{: 0.3f}'.format})
            for bar_type, data in sorted(iteritems(bar_types)):
                eids, lines_bar_y, lines_bar_z = data
                if len(eids):
                    #print('barsi =', barsi)
                    #print('bar_type = %r' % bar_type)
                    for eid, line_y, line_z  in zip(eids, lines_bar_y, lines_bar_z):
                        print('eid=%s centroid=%s cy=%s cz=%s' % (
                            eid, line_y[0], line_y[1], line_z[1]))

        #print('found_bar_types =', found_bar_types)
        #no_axial_torsion = (no_axial, no_torsion)
        #no_shear_bending = (no_shear_y, no_shear_z, no_bending_y, no_bending_z)
        #no_dofs = (no_bending, no_bending_bad, no_6_16, no_0_456,
                   #no_0_56, no_56_456, no_0_6, no_0_16)
        return bar_nids, bar_types, nid_release_map