Exemplo n.º 1
0
    def get_mass_by_element_id(self,
                               element_ids_orig=None,
                               xyz_cid0=None,
                               sort_output=True):
        if xyz_cid0 is None:
            xyz_cid0 = self.model.grid.get_position_by_node_index()

        element_ids, element_ids_orig = self._get_element_ids(element_ids_orig)
        if len(element_ids) == 0:
            nelements = len(element_ids_orig)
            mass = np.full(nelements, np.nan, 'float64')
            if sort_output:
                i = np.argsort(element_ids_orig)
                #print("i =", i, i.shape)
                #print("element_ids_orig =", element_ids_orig, element_ids_orig.shape)
                return element_ids_orig[i], mass
            else:
                return element_ids_orig, mass
        nelements_orig = len(element_ids_orig)
        #print('eids orig = %s' % element_ids_orig)

        type_map = {
            #'CELAS1' : self.elements_spring.celas1,
            'CELAS2': self.elements_spring.celas2,
            'CELAS3': self.elements_spring.celas3,
            'CELAS4': self.elements_spring.celas4,
            'CBAR': self.cbar,
            'CBEAM': self.cbeam,
            'CROD': self.crod,
            'CONROD': self.conrod,
            'CTUBE': self.ctube,
            'CSHEAR': self.cshear,
            'CQUAD4': self.elements_shell.cquad4,
            'CTRIA3': self.elements_shell.ctria3,
            'CTETRA4': self.elements_solid.ctetra4,
            'CPENTA6': self.elements_solid.cpenta6,
            'CHEXA8': self.elements_solid.chexa8,
            'CTETRA10': self.elements_solid.ctetra10,
            'CPENTA15': self.elements_solid.cpenta15,
            'CHEXA20': self.elements_solid.chexa20,
        }

        exclude_types = [
            'CELAS1',
            'CELAS2',
            'CELAS3',
            'CELAS4',
            'CDAMP1',
            'CDAMP2',
            'CDAMP3',
            'CDAMP4',
            'CMASS1',
            'CMASS2',
            'CMASS3',
            'CMASS4',
            'CBUSH',
            'CBUSH1D',
            'CBUSH2D',
        ]
        pid_data = self.get_element_ids_by_property_type(
            element_ids, exclude_types=exclude_types)
        element_ids_to_analyze = pid_data[:, 0]
        data2 = self.group_elements_by_property_type_and_element_type(
            self, pid_data)

        #self.model.log.debug('**data2 = %s' % data2)
        nelements = len(element_ids)
        #self.model.log.debug('nelement_ids =', nelements)
        eids2 = np.zeros(nelements_orig, dtype='int32')
        #mass = full(nelements, nan, dtype='float64')
        mass = np.full(nelements_orig, np.nan, dtype='float64')
        #self.model.log.debug('mass.shape =', mass.shape)

        ni = 0
        self.model.log.debug('data2 = %s' % data2)
        for (pid, etype), element_ids in data2.items():
            #self.model.log.debug('pid=%s eType=%s element_ids=%s' % (pid, eType, element_ids))
            elements = type_map[etype]
            i = np.searchsorted(elements.element_id, element_ids)
            n = len(i)
            eids2[ni:ni + n] = elements.element_id[i]
            if pid == 0:
                # CONROD
                pass
            else:
                self.model.log.debug('*cat pid = %s' % pid)
                props = self.get_properties([pid])
                if len(props) == 0:
                    # the property doesn't exist
                    self.model.log.debug(
                        'Property %i does not exist and is needed by %s eid=%i'
                        % (pid, etype, element_ids[0]))
                    ni += n
                    #print('props = %s' % props)
                    continue

                # we only get one property at a time
                prop = props[0]
                #print('  prop = %s' % str(prop).rstrip())

            elements = type_map[etype]
            i = np.searchsorted(elements.element_id, element_ids)
            n = len(i)
            #print('ielements = %s' % i)

            if etype in [
                    'CELAS1',
                    'CELAS2',
                    'CELAS3',
                    'CELAS4',
            ]:
                pass
            elif etype in ['CROD', 'CONROD', 'CBAR', 'CBEAM']:
                msg = ', which is required for %ss' % etype
                n1 = self.get_nodes(elements.node_ids[i, 0], xyz_cid0, msg=msg)
                n2 = self.get_nodes(elements.node_ids[i, 1], xyz_cid0, msg=msg)
                length = np.linalg.norm(n2 - n1, axis=1)
                #print('prop = %s' % prop)
                #print('  calling get_mass_per_area for pid=%s' % (pid))
                if etype == 'CONROD':
                    rho = self.model.materials.get_density_by_material_id(
                        elements.material_id)
                    mass[ni:ni +
                         n] = length * elements.A[i] * rho[i] + elements.nsm[i]
                else:
                    mpl = prop.get_mass_per_length_by_property_id()
                    mass[ni:ni + n] = mpl * length
                    del prop
            elif etype in ['CTRIA3', 'CQUAD4', 'CSHEAR']:
                if etype == 'CTRIA3':
                    n1, n2, n3 = (elements.node_ids[i, 0],
                                  elements.node_ids[i,
                                                    1], elements.node_ids[i,
                                                                          2])
                    n1 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n1), :]
                    n2 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n2), :]
                    n3 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n3), :]
                    area = _ctria3_normal_A(n1,
                                            n2,
                                            n3,
                                            calculate_area=True,
                                            normalize=False)[1]
                elif etype in ['CQUAD4', 'CSHEAR']:
                    n1, n2, n3, n4 = (elements.node_ids[i, 0],
                                      elements.node_ids[i, 1],
                                      elements.node_ids[i, 2],
                                      elements.node_ids[i, 3])
                    n1 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n1), :]
                    n2 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n2), :]
                    n3 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n3), :]
                    n4 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n4), :]
                    area = _cquad4_normal_A(n1,
                                            n2,
                                            n3,
                                            n4,
                                            calculate_area=True,
                                            normalize=False)[1]
                else:
                    self.model.log.debug(
                        "Element.get_mass doesn't support %s; try %s.get_mass"
                        % (etype, etype))
                    ni += n
                    continue
                #print('prop = %s' % prop)
                #print('  calling get_mass_per_area for pid=%s' % (pid))
                mpa = prop.get_mass_per_area_by_property_id()
                mass[ni:ni + n] = mpa * area
                del prop
            elif etype in [
                    'CTETRA4', 'CTETRA10', 'CPENTA6', 'CPENTA15', 'CHEXA8',
                    'CHEXA20'
            ]:
                rho = prop.get_density_by_property_id()
                del prop
                if etype in ['CTETRA4', 'CTETRA10']:
                    n1, n2, n3, n4 = (elements.node_ids[i, 0],
                                      elements.node_ids[i, 1],
                                      elements.node_ids[i, 2],
                                      elements.node_ids[i, 3])
                    n1 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n1), :]
                    n2 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n2), :]
                    n3 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n3), :]
                    n4 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n4), :]

                    volumei = np.zeros(n, self.model.float_fmt)
                    i = 0
                    for n1i, n2i, n3i, n4i in zip(n1, n2, n3, n4):
                        volumei[i] = volume4(n1i, n2i, n3i, n4i)
                        i += 1
                elif etype in ['CPENTA6', 'CPENTA15']:
                    n1, n2, n3, n4, n5, n6 = (
                        elements.node_ids[i, 0],
                        elements.node_ids[i, 1],
                        elements.node_ids[i, 2],
                        elements.node_ids[i, 3],
                        elements.node_ids[i, 4],
                        elements.node_ids[i, 5],
                    )
                    n1 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n1), :]
                    n2 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n2), :]
                    n3 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n3), :]
                    n4 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n4), :]
                    n5 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n5), :]
                    n6 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n6), :]
                    (area1, centroid1) = tri_area_centroid(n1, n2, n3)
                    (area2, centroid2) = tri_area_centroid(n4, n5, n6)
                    volumei = (area1 + area2) / 2. * np.linalg.norm(
                        centroid1 - centroid2, axis=1)
                elif etype in ['CHEXA8', 'CHEXA20']:
                    n1, n2, n3, n4, n5, n6, n7, n8 = (
                        elements.node_ids[i, 0],
                        elements.node_ids[i, 1],
                        elements.node_ids[i, 2],
                        elements.node_ids[i, 3],
                        elements.node_ids[i, 4],
                        elements.node_ids[i, 5],
                        elements.node_ids[i, 6],
                        elements.node_ids[i, 7],
                    )
                    n1 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n1), :]
                    n2 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n2), :]
                    n3 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n3), :]
                    n4 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n4), :]
                    n5 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n5), :]
                    n6 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n6), :]
                    n7 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n7), :]
                    n8 = xyz_cid0[
                        self.model.grid.get_node_index_by_node_id(n8), :]

                    (area1, centroid1) = quad_area_centroid(n1, n2, n3, n4)
                    (area2, centroid2) = quad_area_centroid(n5, n6, n7, n8)
                    volumei = (area1 + area2) / 2. * np.linalg.norm(
                        centroid1 - centroid2, axis=1)
                else:
                    msg = "Element.get_mass doesn't support %s; try %s.get_mass" % (
                        etype, etype)
                    self.model.log.debug(msg)
                    ni += n
                    continue
                mass[ni:ni + n] = volumei * rho
            else:
                msg = "  Element.get_mass doesn't support %s; try %s.get_mass" % (
                    etype, etype)
                self.model.log.debug(msg)
                msg = "Element.get_mass doesn't support %s; try %s.get_mass" % (
                    etype, etype)
                raise NotImplementedError(msg)
            #self.model.log.debug("")
            ni += n
        #self.model.log.debug('data2 = %s' % data2)
        diff = np.setdiff1d(element_ids_orig, element_ids_to_analyze)
        #print('A = %s' % element_ids_orig)
        #print('B = %s' % element_ids_to_analyze)
        #print('A-B = %s' % (diff))
        #print('eids2 = %s' % eids2)
        #if len(diff):
        #print('****diff = %s' % list(diff))
        #print('eids out = %s' % eids2)
        #print('len(eids2) =', len(eids2))
        #print('len(diff) =', len(diff))
        eids2[ni:] = diff
        if sort_output:
            i = np.argsort(eids2)
            eids2 = eids2[i]
            mass = mass[i]
        return eids2, mass
Exemplo n.º 2
0
 def _area_centroid(self, element_id, xyz_cid0):
     (A1, c1) = tri_area_centroid(n1, n2, n3)
     (A2, c2) = tri_area_centroid(n4, n5, n6)
     return (A1, A2, c1, c2)