def _mass_area_normal(self, element_id=None, node_ids=None, xyz_cid0=None, calculate_mass=True, calculate_area=True, calculate_normal=True): """ Gets the mass, area, and normals of the CQUAD4s on a per element basis. Parameters ---------- element_id : (nelements, ) int ndarray; (default=None -> all) the elements to consider :param xyz_cid0: the GRIDs as an (nnodes, 3) NDARRAY in CORD2R=0 (or None) calculate_mass : bool; default=True should the mass be calculated calculate_area : bool; default=True should the area be calculated calculate_normal : bool; default=True should the normals be calculated .. note:: If node_ids is None, the positions of all the GRID cards must be calculated """ if element_id is None: element_id = self.element_id property_id = self.property_id i = None else: i = searchsorted(self.element_id, element_id) property_id = self.property_id[i] n1, n2, n3, n4 = self._node_locations(xyz_cid0, i) if calculate_mass: calculate_area = True normal, A = _cquad4_normal_A(n1, n2, n3, n4, calculate_area=calculate_area, normalize=True) massi = None if calculate_mass: mpa = self.model.properties_shell.get_mass_per_area(property_id) assert mpa is not None massi = mpa * A return massi, A, normal
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 = full(nelements, nan, 'float64') if sort_output: i = 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) TypeMap = { #'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 = zeros(nelements_orig, dtype='int32') #mass = full(nelements, nan, dtype='float64') mass = full(nelements_orig, 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 iteritems(data2): #self.model.log.debug('pid=%s eType=%s element_ids=%s' % (pid, eType, element_ids)) elements = TypeMap[eType] i = 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 = TypeMap[eType] i = 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) L = norm(n2 - n1, axis=1) #print('prop = %s' % prop) #print(' calling get_mass_per_area for pid=%s' % (pid)) if eType in ['CONROD']: rho = self.model.materials.get_density_by_material_id(elements.material_id) mass[ni:ni+n] = L * elements.A[i] * rho[i] + elements.nsm[i] else: mpl = prop.get_mass_per_length_by_property_id() mass[ni:ni+n] = mpl * L 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), :] normal, A = _ctria3_normal_A(n1, n2, n3, calculate_area=True, normalize=True) 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), :] normal, A = _cquad4_normal_A(n1, n2, n3, n4, calculate_area=True, normalize=True) 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 * A 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), :] Vi = zeros(n, self.model.float) i = 0 for n1i, n2i, n3i, n4i in zip(n1, n2, n3, n4): Vi[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), :] (A1, c1) = tri_area_centroid(n1, n2, n3) (A2, c2) = tri_area_centroid(n4, n5, n6) Vi = (A1 + A2) / 2. * norm(c1 - c2, 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), :] (A1, c1) = quad_area_centroid(n1, n2, n3, n4) (A2, c2) = quad_area_centroid(n5, n6, n7, n8) Vi = (A1 + A2) / 2. * norm(c1 - c2, axis=1) else: self.model.log.debug("Element.get_mass doesn't support %s; try %s.get_mass" % (eType, eType)) ni += n continue mass[ni:ni+n] = Vi * rho else: self.model.log.debug(" Element.get_mass doesn't support %s; try %s.get_mass" % (eType, eType)) raise NotImplementedError("Element.get_mass doesn't support %s; try %s.get_mass" % (eType, eType)) #self.model.log.debug("") ni += n #self.model.log.debug('data2 = %s' % data2) diff = 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 = argsort(eids2) eids2 = eids2[i] mass = mass[i] return eids2, mass
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 iteritems(data2): #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