Source code for pyNastran.bdf.mesh_utils.rbe_tools

import warnings
from collections import defaultdict
from typing import Optional

import numpy as np
from pyNastran.bdf.bdf import BDF
from pyNastran.bdf.cards.elements.mass import CONM2
from pyNastran.bdf.cards.elements.rigid import RBE2, RBE3
from pyNastran.bdf.mesh_utils.mass_properties import increment_inertia, transform_inertia

[docs] def rbe3_to_rbe2(model: BDF, eids_to_fix: list[int]) -> BDF: log = model.log # log.info(f'RBE3 -> RBE2: eids_to_fix = {eids_to_fix}') if len(eids_to_fix) == 0: # pragma: no cover raise RuntimeError('no eids were specified...') rigid_elements2 = {} for eid, elem in model.rigid_elements.items(): if eid not in eids_to_fix: log.warning(f'skipping eid={eid} because its not an element to fix\n{str(elem)}') rigid_elements2[eid] = elem continue if elem.type not in {'RBE3'}: log.warning(f'skipping eid={eid} because its not an RBE3\n{str(elem)}') rigid_elements2[eid] = elem continue # ---RBE3--- # Gijs : [[4407195, 4407212, 4407280, 4407288]] # independent_nodes : [4407195, 4407212, 4407280, 4407288] # # Cmi : [] # Gmi : [] # Gmi_node_ids : [] # # comps : ['123'] # dependent_nodes : [10913] # eid : 11913 # nodes : [4407195, 4407212, 4407280, 4407288, 10913] # ref_grid_id : 10913 # refc : '123456' # refgrid : 10913 # weights : [1.0] # wt_cg_groups : [(1.0, '123', [4407195, 4407212, 4407280, 4407288])] assert len(elem.Gmi) == 0, elem.Gmi assert elem.comps == ['123'], elem.comps assert elem.refc == '123456', elem.refc assert elem.weights == [1.0], elem.weights assert len(elem.comps) == 1 ind = elem.independent_nodes dep = elem.dependent_nodes gn = elem.refgrid # ind; was dep cm = '123456' Gmi = elem.independent_nodes elem = RBE2(eid, gn, cm, Gmi, tref=elem.tref, alpha=elem.alpha, comment=elem.comment.strip()) rigid_elements2[eid] = elem log.debug(f'adding RBE2:\n{str(elem)}') model.rigid_elements = rigid_elements2 assert len(model.rigid_elements) return model
[docs] def rbe2_to_rbe3(model: BDF, eids_to_fix: list[int]) -> BDF: if len(eids_to_fix) == 0: # pragma: no cover raise RuntimeError('no eids were specified...') rigid_elements2 = {} log = model.log # log.info(f'RBE2 -> RBE3: eids_to_fix = {eids_to_fix}') assert len(eids_to_fix) > 0, eids_to_fix for eid, elem in model.rigid_elements.items(): if eid not in eids_to_fix: log.warning(f'skipping eid={eid} because its not an element to fix\n{str(elem)}') rigid_elements2[eid] = elem continue if elem.type not in {'RBE2'}: log.warning(f'skipping eid={eid} because its not an RBE2\n{str(elem)}') rigid_elements2[eid] = elem continue # ---RBE2--- # Gmi : [1, 2] # cm : '123456' # gn : 10 assert len(elem.Gmi) > 0, elem.Gmi assert elem.cm == '123456', elem.cm # ind = elem.independent_nodes # dep = elem.dependent_nodes # gn = elem.refgrid # ind; was dep # cm = '123456' # Gmi = elem.independent_nodes # elem = RBE2(eid, gn, cm, Gmi, # tref=elem.tref, alpha=elem.alpha, # comment=elem.comment.strip()) refgrid = elem.gn refc = elem.cm weights = [1.0] comps = ['123'] Gijs = [elem.dependent_nodes] elem = RBE3( eid, refgrid, refc, weights, comps, Gijs, alpha=elem.alpha, tref=elem.tref, comment=elem.comment) #print(elem) rigid_elements2[eid] = elem log.debug(f'adding RBE3\n{str(elem)}') model.rigid_elements = rigid_elements2 return model
[docs] def merge_rbe2(model: BDF, rbe_eids_to_fix: list[int]) -> None: log = model.log eid_to_dependent_nodes = {} # eid_to_eids = {} dependent_nid_to_eids_map = defaultdict(set) nrigid = 0 for eid, elem in model.rigid_elements.items(): if eid not in rbe_eids_to_fix: log.warning(f'skipping eid={eid} because its not an element to fix\n{str(elem)}') if elem.type not in {'RBE2'}: log.warning(f'skipping eid={eid} because its not an RBE2\n{str(elem)}') continue dependent_nodes = elem.dependent_nodes eid_to_dependent_nodes[eid] = dependent_nodes for nid in dependent_nodes: dependent_nid_to_eids_map[nid].add(eid) nrigid += 1 dependent_nid_to_eids_map = dict(dependent_nid_to_eids_map) #print(f'dependent_nid_to_eids_map = {dependent_nid_to_eids_map}') eid_to_nids_map = get_eid_to_nid_map(eid_to_dependent_nodes, dependent_nid_to_eids_map) eid_to_nids_map = get_eid_to_nid_map(eid_to_nids_map, dependent_nid_to_eids_map) eid_to_nids_map = get_eid_to_nid_map(eid_to_nids_map, dependent_nid_to_eids_map) #print(f'eid_to_nids_map = {eid_to_nids_map}') nids_to_eids_map = defaultdict(list) for eid, nids in eid_to_nids_map.items(): nids_list = list(nids) nids_list.sort() nids_to_eids_map[tuple(nids_list)].append(eid) #print(f'nids_to_eids_map = {set(nids_to_eids_map)}') mass_nid_to_elem_map: dict[int, CONM2] = {} for eid, mass_elem in model.masses.items(): if mass_elem.type != 'CONM2': log.warning(f'skipping eid={eid} because its not a CONM2\n{str(mass_elem)}') continue #print(elem.get_stats()) mass_nid_to_elem_map[mass_elem.nid] = mass_elem mass_elem.cross_reference(model) for dep_nids_tuple, eids in nids_to_eids_map.items(): eid0 = eids[0] elem0: RBE2 = model.rigid_elements[eid0] log.info(f'eids={eids}; dep_nids={dep_nids_tuple}\n') if len(eids) == 1: log.debug('skipping\n' + str(elem0)) #log.debug('\n' + str(mass_elem0)) continue indep_nid0 = elem0.gn mass_elem0 = mass_nid_to_elem_map[indep_nid0] _merge_rbe2( model, eids, dep_nids_tuple, mass_nid_to_elem_map, elem0, mass_elem0=mass_elem0) return
def _get_mass_elem_from_node_id(model: BDF, indep_nid0: int, mass_elem0: Optional[CONM2]=None) -> CONM2: if mass_elem0 is None: for mass_eid, mass_elem in model.masses.items(): if mass_elem.nid == indep_nid0: mass_elem0 = mass_elem assert mass_elem0 is not None, mass_elem0 return mass_elem0 def _merge_rbe2(model: BDF, eids: list[int], dep_nids_tuple: tuple[int, ...], mass_nid_to_elem_map: dict[int, CONM2], elem0: RBE2, mass_elem0: CONM2=None) -> None: log = model.log indep_nid0 = elem0.gn mass_elem0 = _get_mass_elem_from_node_id( model, indep_nid0, mass_elem0=mass_elem0) mass_node0 = mass_elem0.nid_ref log.info('baseline:\n' + str(elem0)) log.info('\n' + str(mass_elem0)) mass_comments = [] reference_point = np.zeros(3, dtype='float64') mass_cg = np.zeros(3, dtype='float64') mass = 0. mass_list = [] cg_list = [] inertia_list = [] # [Ixx, Iyy, Izz, Ixy, Ixz, Iyz] inertia = np.zeros(6, dtype='float64') for eid in eids: rigid_elemi: RBE2 = model.rigid_elements[eid] indep_nid = rigid_elemi.gn mass_elem: CONM2 = mass_nid_to_elem_map[indep_nid] massi = mass_elem.mass mass_node = mass_elem.nid_ref centroidi = mass_elem.X + mass_node.get_position() log.debug(f'massi={massi}; centroidi={centroidi}') I11, I21, I22, I31, I32, I33 = mass_elem.I dinertia = [I11, I22, I33, I21, I31, I32] mass = increment_inertia(centroidi, reference_point, massi, mass, mass_cg, inertia, mass_list, cg_list, inertia_list) log.debug(f'mass_cg={mass_cg}') # [Ixx, Iyy, Izz, Ixy, Ixz, Iyz] inertia[0] += I11 # Ixx inertia[1] += I22 # Iyy inertia[2] += I33 # Izz inertia[3] += I21 # Ixy inertia[4] += I31 # Ixz inertia[5] += I32 # Iyz if mass_elem.comment: mass_comments.append(mass_elem.comment) # cleanup old elements log.warning('removing') for eid in eids[1:]: rigid_elemi = model.rigid_elements[eid] del model.rigid_elements[eid] indep_nid = rigid_elemi.gn mass_elemi = mass_nid_to_elem_map[indep_nid] mass_eid = mass_elemi.eid log.warning('\n' + str(rigid_elemi)) log.warning('\n' + str(mass_elemi)) del model.masses[mass_eid] # update the CONM2 mass log.debug(f'mass = {mass}') if mass: cg = mass_cg / mass else: cg = mass_cg log.debug(f'cg = {cg}') inertia2 = transform_inertia(mass, cg, reference_point, cg, inertia) Ixx, Iyy, Izz, Ixy, Ixz, Iyz = inertia2 mass_comments.append(f'Ixx={Ixx:g} Iyy={Iyy:g} Izz={Izz:g}\nIxy={Ixy:g} Ixz={Ixz:g} Iyz={Iyz:g}\n') if mass_comments: mass_elem0.comment = ''.join(mass_comments[::-1]) mass_elem0.X = np.zeros(3, dtype='float64') mass_elem0.mass = mass mass_node0.comment = f'xyz=[{cg[0]:g},{cg[1]:g},{cg[2]:g}]' mass_node0.xyz = cg # FEMAP Mass Table: 'Ixx, Iyy, Izz, Ixy, Iyz, Izx' mass_elem0.I = [Ixx, Ixy, Iyy, Ixz, Iyz, Izz] elem0.Gmi = list(dep_nids_tuple) log.info('\n' + str(elem0)) log.info('\n' + str(mass_elem0)) log.debug('---------------------')
[docs] def get_eid_to_nid_map( eid_to_nids_map: dict[int, set[int]], nid_to_eids_map: dict[int, set[int]],): eid_to_nids_map2 = defaultdict(set) for eid, nids in eid_to_nids_map.items(): for nid in nids: eid_to_nids_map2[eid].add(nid) eids2 = nid_to_eids_map[nid] for eid2 in eids2: nids2 = eid_to_nids_map[eid2] eid_to_nids_map2[eid].update(nids2) return dict(eid_to_nids_map2)