示例#1
0
    def center_of_mass(self):
        """the centroid formuala is way more complicated if you consider the nonstructural mass axis"""
        elem = self
        prop = self.pid_ref
        node1 = self.ga_ref
        node2 = self.gb_ref
        xyz1 = node1.get_position()
        xyz2 = node2.get_position()
        #centroid = ( + self.gb_ref.get_position()) / 2.
        centroid = (xyz1 + xyz2) / 2.
        #length = norm(xyz2 - xyz1)
        #cda = model.nodes[n1].cid_ref
        #cdb = model.nodes[n2].cid_ref

        model = None
        log = None
        is_failed, out = elem.get_axes_by_nodes(model, self.pid_ref, node1, node2, xyz1, xyz2, log)
        if is_failed:
            #model.log.error(out)
            raise RuntimeError(out)

        wa, wb, _ihat, jhat, khat = out
        p1 = xyz1 + wa
        p2 = xyz2 + wb

        if prop.type == 'PBEAM':
            rho = prop.Rho()

            # we don't call the MassPerLength method so we can put the NSM centroid
            # on a different axis (the PBEAM is weird)
            mass_per_lengths = []
            nsm_per_lengths = []
            for (area, nsm) in zip(prop.A, prop.nsm):
                mass_per_lengths.append(area * rho)
                nsm_per_lengths.append(nsm)
            mass_per_length = integrate_positive_unit_line(prop.xxb, mass_per_lengths)
            nsm_per_length = integrate_positive_unit_line(prop.xxb, nsm_per_lengths)
            nsm_n1 = (p1 + jhat * prop.m1a + khat * prop.m2a)
            nsm_n2 = (p2 + jhat * prop.m1b + khat * prop.m2b)
            #print("nsm_per_length=%s" % nsm_per_length)
            #print("nsm_n1=%s" % nsm_n1)
            #print("nsm_n2=%s" % nsm_n2)
            nsm_centroid = (nsm_n1 + nsm_n2) / 2.
            #if nsm != 0.:
                #p1_nsm = p1 + prop.ma
                #p2_nsm = p2 + prop.mb
        elif prop.type == 'PBEAML':
            mass_per_lengths = prop.get_mass_per_lengths()
            #mass_per_length = prop.MassPerLength() # includes simplified nsm

            # m1a, m1b, m2a, m2b=0.
            nsm_centroid = (p1 + p2) / 2.

            # mass_per_length already includes nsm
            mass_per_length = integrate_positive_unit_line(prop.xxb, mass_per_lengths)
            nsm_per_length = 0.

            #print('mass_per_lengths=%s nsm_per_lengths=%s' % (
                #mass_per_lengths, nsm_per_lengths))
            #print('mass_per_length=%s nsm_per_length=%s' % (
                #mass_per_length, nsm_per_length))

            #nsm_centroid = np.zeros(3) # TODO: what is this...
            #nsm = prop.nsm[0] * length # TODO: simplified
        elif prop.type == 'PBCOMP':
            mass_per_length = prop.MassPerLength()
            nsm_per_length = prop.nsm
            nsm_n1 = (p1 + jhat * prop.m1 + khat * prop.m2)
            nsm_n2 = (p2 + jhat * prop.m1 + khat * prop.m2)
            nsm_centroid = (nsm_n1 + nsm_n2) / 2.
        #elif prop.type == 'PBMSECT':
            #continue
            #mass_per_length = prop.MassPerLength()
            #m = mass_per_length * length
            #nsm = prop.nsm
        else:
            raise NotImplementedError(prop.type)

        total_mass = mass_per_length + nsm_per_length
        if total_mass == 0.0:
            return centroid
        centroid2 = (centroid * mass_per_length + nsm_centroid * nsm_per_length) / total_mass
        return centroid2
示例#2
0
def _mass_properties_new(model,
                         element_ids=None,
                         mass_ids=None,
                         reference_point=None,
                         sym_axis=None,
                         scale=None,
                         xyz_cid0=None):  # pragma: no cover
    """
    half implemented, not tested, should be faster someday...
    don't use this

    Caclulates mass properties in the global system about the
    reference point.

    Parameters
    ----------
    model : BDF()
        a BDF object
    element_ids : list[int]; (n, ) ndarray, optional
        An array of element ids.
    mass_ids : list[int]; (n, ) ndarray, optional
        An array of mass ids.
    reference_point : ndarray/str/int, optional
        type : ndarray
            An array that defines the origin of the frame.
            default = <0,0,0>.
        type : str
            'cg' is the only allowed string
        type : int
            the node id
    sym_axis : str, optional
        The axis to which the model is symmetric. If AERO cards are used, this can be left blank
        allowed_values = 'no', x', 'y', 'z', 'xy', 'yz', 'xz', 'xyz'
    scale : float, optional
        The WTMASS scaling value.
        default=None -> PARAM, WTMASS is used
        float > 0.0
    xyz_cid0 : dict[nid] : xyz; default=None -> auto-calculate
        mapping of the node id to the global position

    Returns
    -------
    mass : float
        The mass of the model.
    cg : ndarray
        The cg of the model as an array.
    I : ndarray
        Moment of inertia array([Ixx, Iyy, Izz, Ixy, Ixz, Iyz]).

    I = mass * centroid * centroid

    .. math:: I_{xx} = m (dy^2 + dz^2)

    .. math:: I_{yz} = -m * dy * dz

    where:

    .. math:: dx = x_{element} - x_{ref}

    .. seealso:: http://en.wikipedia.org/wiki/Moment_of_inertia#Moment_of_inertia_tensor

    .. note::
       This doesn't use the mass matrix formulation like Nastran.
       It assumes m*r^2 is the dominant term.
       If you're trying to get the mass of a single element, it
       will be wrong, but for real models will be correct.

    Example 1
    ---------
    # mass properties of entire structure
    mass, cg, I = model.mass_properties()
    Ixx, Iyy, Izz, Ixy, Ixz, Iyz = I


    Example 2
    ---------
    # mass properties of model based on Property ID
    pids = list(model.pids.keys())
    pid_eids = model.get_element_ids_dict_with_pids(pids)

    for pid, eids in sorted(iteritems(pid_eids)):
        mass, cg, I = mass_properties(model, element_ids=eids)
    """
    #if reference_point is None:
    reference_point = array([0., 0., 0.])

    if xyz_cid0 is None:
        xyz = {}
        for nid, node in iteritems(model.nodes):
            xyz[nid] = node.get_position()
    else:
        xyz = xyz_cid0

    elements, masses = _mass_properties_elements_init(model, element_ids,
                                                      mass_ids)

    #mass = 0.
    #cg = array([0., 0., 0.])
    #I = array([0., 0., 0., 0., 0., 0., ])
    #if isinstance(reference_point, string_types):
    #if reference_point == 'cg':
    #mass = 0.
    #for pack in [elements, masses]:
    #for element in pack:
    #try:
    #p = element.Centroid()
    #m = element.Mass()
    #mass += m
    #cg += m * p
    #except:
    #pass
    #if mass == 0.0:
    #return mass, cg, I

    #reference_point = cg / mass
    #else:
    ## reference_point = [0.,0.,0.] or user-defined array
    #pass

    mass = 0.
    cg = array([0., 0., 0.])
    I = array([
        0.,
        0.,
        0.,
        0.,
        0.,
        0.,
    ])

    no_mass = [
        'CELAS1',
        'CELAS2',
        'CELAS3',
        'CELAS4',  #'CLEAS5',
        'CDAMP1',
        'CDAMP2',
        'CDAMP3',
        'CDAMP4',
        'CDAMP5',
        'CBUSH',
        'CBUSH1D',
        'CBUSH2D',
        'CVISC',
        'CGAP',  # is this right?
        'CFAST',
        'CRAC2D',
        'CRAC3D',
        'CSSCHD',
        'CAERO1',
        'CAERO2',
        'CAERO3',
        'CAERO4',
        'CAERO5',
        'CBARAO',
        'CORD1R',
        'CORD2R',
        'CORD1C',
        'CORD2C',
        'CORD1S',
        'CORD2S',
        'CORD3G',
        'CONV',
        'CONVM',
        'CSET',
        'CSET1',
        'CLOAD',
        'CHBDYG',
        'CHBDYE',
        'CHBDYP',
        'CTRAX3',
        'CTRAX6',
        'CQUADX8',
        'CQUADX4',
        'CPLSTN3',
        'CPLSTN6',
        'CPLSTN4',
        'CPLSTN8',
    ]
    all_eids = np.array(list(model.elements.keys()), dtype='int32')
    all_eids.sort()

    all_mass_ids = np.array(list(model.masses.keys()), dtype='int32')
    all_mass_ids.sort()

    #def _increment_inertia0(centroid, reference_point, m, mass, cg, I):
    #"""helper method"""
    #(x, y, z) = centroid - reference_point
    #mass += m
    #cg += m * centroid
    #return mass

    def _increment_inertia(centroid, reference_point, m, mass, cg, I):
        """helper method"""
        (x, y, z) = centroid - reference_point
        x2 = x * x
        y2 = y * y
        z2 = z * z
        I[0] += m * (y2 + z2)  # Ixx
        I[1] += m * (x2 + z2)  # Iyy
        I[2] += m * (x2 + y2)  # Izz
        I[3] += m * x * y  # Ixy
        I[4] += m * x * z  # Ixz
        I[5] += m * y * z  # Iyz
        mass += m
        cg += m * centroid
        return mass

    def get_sub_eids(all_eids, eids):
        """supports limiting the element/mass ids"""
        eids = np.array(eids)
        ieids = np.searchsorted(all_eids, eids)
        eids2 = eids[all_eids[ieids] == eids]
        return eids2

    etypes_skipped = set([])
    for etype, eids in iteritems(model._type_to_id_map):
        if etype in no_mass:
            continue
        elif etype in ['CROD', 'CONROD']:
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2 = elem.node_ids
                length = norm(xyz[n2] - xyz[n1])
                centroid = (xyz[n1] + xyz[n2]) / 2.
                mpl = elem.MassPerLength()
                m = mpl * length
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype == 'CTUBE':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2 = elem.node_ids
                length = norm(xyz[n2] - xyz[n1])
                centroid = (xyz[n1] + xyz[n2]) / 2.
                mpl = elem.pid_ref.MassPerLength()
                m = mpl * length
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype == 'CBAR':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2 = elem.node_ids
                centroid = (xyz[n1] + xyz[n2]) / 2.
                length = norm(xyz[n2] - xyz[n1])
                mpl = elem.pid_ref.MassPerLength()
                m = mpl * length
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype == 'CBEAM':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                prop = elem.pid_ref
                n1, n2 = elem.node_ids
                node1 = xyz[n1]
                node2 = xyz[n2]
                centroid = (node1 + node2) / 2.
                length = norm(node2 - node1)
                #cda = model.nodes[n1].cid_ref
                #cdb = model.nodes[n2].cid_ref

                is_failed, wa, wb, _ihat, jhat, khat = elem.get_axes(model)
                p1 = node1 + wa
                p2 = node2 + wb
                if prop.type == 'PBEAM':
                    rho = prop.Rho()
                    mass_per_lengths = []
                    nsm_per_lengths = []
                    for (area, nsm) in zip(prop.A, prop.nsm):
                        mass_per_lengths.append(area * rho)
                        nsm_per_lengths.append(nsm)
                    mass_per_length = integrate_positive_unit_line(
                        prop.xxb, mass_per_lengths)
                    nsm_per_length = integrate_positive_unit_line(
                        prop.xxb, nsm_per_lengths)
                    #nsm = np.mean(prop.nsm)
                    nsm = nsm_per_length * length
                    m = mass_per_length * length
                    nsm_n1 = (p1 + jhat * prop.m1a + khat * prop.m2a)
                    nsm_n2 = (p2 + jhat * prop.m1b + khat * prop.m2b)
                    nsm_centroid = (nsm_n1 + nsm_n2) / 2.
                    #if nsm != 0.:
                    #p1_nsm = p1 + prop.ma
                    #p2_nsm = p2 + prop.mb
                elif prop.type == 'PBEAML':
                    #mass_per_lengths = elem.get_mass_per_lengths()
                    mass_per_length = prop.MassPerLength(
                    )  # includes simplified nsm
                    m = mass_per_length * length
                    nsm_centroid = np.zeros(3)
                    nsm = prop.nsm[0]  # TODO: simplified
                elif prop.type == 'PBCOMP':
                    mass_per_length = prop.MassPerLength()
                    m = mass_per_length * length
                    nsm = prop.nsm
                    nsm_n1 = (p1 + jhat * prop.m1 + khat * prop.m2)
                    nsm_n2 = (p2 + jhat * prop.m1 + khat * prop.m2)
                    nsm_centroid = (nsm_n1 + nsm_n2) / 2.
                else:
                    raise NotImplementedError(prop.type)

                #mpl = elem.pid_ref.MassPerLength()
                #m = mpl * length

                (x, y, z) = centroid - reference_point
                (xm, ym, zm) = nsm_centroid - reference_point
                x2 = x * x
                y2 = y * y
                z2 = z * z
                xm2 = xm * xm
                ym2 = ym * ym
                zm2 = zm * zm

                # Ixx, Iyy, Izz, Ixy, Ixz, Iyz
                I[0] += m * (y2 + z2) + nsm * (ym2 + zm2)
                I[1] += m * (x2 + z2) + nsm * (xm2 + zm2)
                I[2] += m * (x2 + y2) + nsm * (xm2 + ym2)
                I[3] += m * x * y + nsm * xm * ym
                I[4] += m * x * z + nsm * xm * zm
                I[5] += m * y * z + nsm * ym * zm
                mass += m + nsm
                cg += m * centroid + nsm * nsm_centroid

        elif etype in ['CTRIA3', 'CTRIA6', 'CTRIAR']:
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3 = elem.node_ids[:3]
                prop = elem.pid_ref
                centroid = (xyz[n1] + xyz[n2] + xyz[n3]) / 3.
                area = 0.5 * norm(cross(xyz[n1] - xyz[n2], xyz[n1] - xyz[n3]))
                if prop.type == 'PSHELL':
                    tflag = elem.tflag
                    ti = prop.Thickness()
                    if tflag == 0:
                        # absolute
                        t1 = elem.T1 if elem.T1 else ti
                        t2 = elem.T2 if elem.T2 else ti
                        t3 = elem.T3 if elem.T3 else ti
                    elif tflag == 1:
                        # relative
                        t1 = elem.T1 * ti if elem.T1 else ti
                        t2 = elem.T2 * ti if elem.T2 else ti
                        t3 = elem.T3 * ti if elem.T3 else ti
                    else:
                        raise RuntimeError('tflag=%r' % tflag)
                    assert t1 + t2 + t3 > 0., 't1=%s t2=%s t3=%s' % (t1, t2,
                                                                     t3)
                    t = (t1 + t2 + t3) / 3.

                    # m/A = rho * A * t + nsm
                    #mass_per_area = elem.nsm + rho * elem.t

                    mpa = prop.nsm + prop.Rho() * t
                    #mpa = elem.pid_ref.MassPerArea()
                    m = mpa * area
                elif prop.type in ['PCOMP', 'PCOMPG']:
                    # PCOMP, PCOMPG
                    #rho_t = prop.get_rho_t()
                    #nsm = prop.nsm
                    #rho_t = [mat.Rho() * t for (mat, t) in zip(prop.mids_ref, prop.ts)]
                    #mpa = sum(rho_t) + nsm

                    # works for PCOMP
                    # F:\Program Files\Siemens\NXNastran\nxn10p1\nxn10p1\nast\tpl\cqr3compbuck.dat
                    mpa = prop.get_mass_per_area()
                elif prop.type == 'PLPLANE':
                    continue
                else:
                    raise NotImplementedError(prop.type)
                m = area * mpa
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype in ['CQUAD4', 'CQUAD8', 'CQUADR']:
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3, n4 = elem.node_ids[:4]
                prop = elem.pid_ref
                centroid = (xyz[n1] + xyz[n2] + xyz[n3] + xyz[n4]) / 4.
                area = 0.5 * norm(cross(xyz[n3] - xyz[n1], xyz[n4] - xyz[n2]))

                if prop.type == 'PSHELL':
                    tflag = elem.tflag
                    ti = prop.Thickness()
                    if tflag == 0:
                        # absolute
                        t1 = elem.T1 if elem.T1 else ti
                        t2 = elem.T2 if elem.T2 else ti
                        t3 = elem.T3 if elem.T3 else ti
                        t4 = elem.T4 if elem.T4 else ti
                    elif tflag == 1:
                        # relative
                        t1 = elem.T1 * ti if elem.T1 else ti
                        t2 = elem.T2 * ti if elem.T2 else ti
                        t3 = elem.T3 * ti if elem.T3 else ti
                        t4 = elem.T4 * ti if elem.T4 else ti
                    else:
                        raise RuntimeError('tflag=%r' % tflag)
                    assert t1 + t2 + t3 + t4 > 0., 't1=%s t2=%s t3=%s t4=%s' % (
                        t1, t2, t3, t4)
                    t = (t1 + t2 + t3 + t4) / 4.

                    # m/A = rho * A * t + nsm
                    #mass_per_area = model.nsm + rho * model.t

                    mpa = prop.nsm + prop.Rho() * t
                    #mpa = elem.pid_ref.MassPerArea()
                    #m = mpa * area
                elif prop.type in ['PCOMP', 'PCOMPG']:
                    # PCOMP, PCOMPG
                    #rho_t = prop.get_rho_t()
                    #nsm = prop.nsm
                    #rho_t = [mat.Rho() * t for (mat, t) in zip(prop.mids_ref, prop.ts)]
                    #mpa = sum(rho_t) + nsm
                    mpa = prop.get_mass_per_area()
                elif prop.type == 'PLPLANE':
                    continue
                    #raise NotImplementedError(prop.type)
                else:
                    raise NotImplementedError(prop.type)
                m = area * mpa
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype == 'CQUAD':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3, n4 = elem.node_ids[:4]
                prop = elem.pid_ref
                centroid = (xyz[n1] + xyz[n2] + xyz[n3] + xyz[n4]) / 4.
                area = 0.5 * norm(cross(xyz[n3] - xyz[n1], xyz[n4] - xyz[n2]))

                if prop.type == 'PSHELL':
                    t = prop.Thickness()
                    mpa = prop.nsm + prop.Rho() * t
                elif prop.type in ['PCOMP', 'PCOMPG']:
                    mpa = prop.get_mass_per_area()
                elif prop.type == 'PLPLANE':
                    continue
                    #raise NotImplementedError(prop.type)
                else:
                    raise NotImplementedError(prop.type)
                m = area * mpa
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)

        elif etype == 'CSHEAR':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3, n4 = elem.node_ids
                prop = elem.pid_ref
                centroid = (xyz[n1] + xyz[n2] + xyz[n3] + xyz[n4]) / 4.
                area = 0.5 * norm(cross(xyz[n3] - xyz[n1], xyz[n4] - xyz[n2]))
                mpa = prop.MassPerArea()
                m = area * mpa
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype in [
                'CONM1', 'CONM2', 'CMASS1', 'CMASS2', 'CMASS3', 'CMASS4'
        ]:
            eids2 = get_sub_eids(all_mass_ids, eids)
            for eid in eids2:
                elem = model.masses[eid]
                m = elem.Mass()
                centroid = elem.Centroid()
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype == 'CTETRA':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3, n4 = elem.node_ids[:4]
                centroid = (xyz[n1] + xyz[n2] + xyz[n3] + xyz[n4]) / 4.
                #V = -dot(n1 - n4, cross(n2 - n4, n3 - n4)) / 6.
                volume = -dot(xyz[n1] - xyz[n4],
                              cross(xyz[n2] - xyz[n4], xyz[n3] - xyz[n4])) / 6.
                m = elem.Rho() * volume
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype == 'CPYRAM':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3, n4, n5 = elem.node_ids[:5]
                centroid1 = (xyz[n1] + xyz[n2] + xyz[n3] + xyz[n4]) / 4.
                area1 = 0.5 * norm(cross(xyz[n3] - xyz[n1], xyz[n4] - xyz[n2]))
                centroid5 = xyz[n5]
                centroid = (centroid1 + centroid5) / 2.
                volume = area1 / 3. * norm(centroid1 - centroid5)
                m = elem.Rho() * volume
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)
        elif etype == 'CPENTA':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3, n4, n5, n6 = elem.node_ids[:6]
                area1 = 0.5 * norm(cross(xyz[n3] - xyz[n1], xyz[n2] - xyz[n1]))
                area2 = 0.5 * norm(cross(xyz[n6] - xyz[n4], xyz[n5] - xyz[n4]))
                centroid1 = (xyz[n1] + xyz[n2] + xyz[n3]) / 3.
                centroid2 = (xyz[n4] + xyz[n5] + xyz[n6]) / 3.
                centroid = (centroid1 + centroid2) / 2.
                volume = (area1 + area2) / 2. * norm(centroid1 - centroid2)
                m = elem.Rho() * volume
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)

        elif etype == 'CHEXA':
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]
                n1, n2, n3, n4, n5, n6, n7, n8 = elem.node_ids[:8]
                #(A1, c1) = area_centroid(n1, n2, n3, n4)
                centroid1 = (xyz[n1] + xyz[n2] + xyz[n3] + xyz[n4]) / 4.
                area1 = 0.5 * norm(cross(xyz[n3] - xyz[n1], xyz[n4] - xyz[n2]))
                #(A2, c2) = area_centroid(n5, n6, n7, n8)
                centroid2 = (xyz[n5] + xyz[n6] + xyz[n7] + xyz[n8]) / 4.
                area2 = 0.5 * norm(cross(xyz[n7] - xyz[n5], xyz[n8] - xyz[n6]))

                volume = (area1 + area2) / 2. * norm(centroid1 - centroid2)
                m = elem.Rho() * volume
                centroid = (centroid1 + centroid2) / 2.
                mass = _increment_inertia(centroid, reference_point, m, mass,
                                          cg, I)

        elif etype in no_mass:
            continue
        elif etype == 'CBEND':
            model.log.info('elem.type=%s doesnt have mass' % etype)
            continue
        elif etype.startswith('C'):
            eids2 = get_sub_eids(all_eids, eids)
            for eid in eids2:
                elem = model.elements[eid]

                #if elem.pid_ref.type in ['PPLANE']:
                try:
                    m = elem.Mass()
                except:
                    model.log.error('etype = %r' % etype)
                    print(elem)
                    print(elem.pid_ref)
                    raise
                centroid = elem.Centroid()
                if m > 0.0:
                    model.log.info('elem.type=%s is not supported in new '
                                   'mass properties method' % elem.type)
                    mass = _increment_inertia(centroid, reference_point, m,
                                              mass, cg, I)
                elif etype not in etypes_skipped:
                    model.log.info('elem.type=%s doesnt have mass' % elem.type)
                    etypes_skipped.add(etype)

    if mass:
        cg /= mass
    mass, cg, I = _apply_mass_symmetry(model, sym_axis, scale, mass, cg, I)
    # Ixx, Iyy, Izz, Ixy, Ixz, Iyz = I
    return mass, cg, I