def run_fem2(bdf_model, out_model, xref, punch, sum_load, size, is_double, reject, debug=False, log=None): """ Reads/writes the BDF to verify nothing has been lost Parameters ---------- bdf_model : str the filename to run xref : bool xrefs punch : bool punches """ assert os.path.exists(bdf_model), bdf_model assert os.path.exists(out_model), out_model fem2 = BDF(debug=debug, log=log) fem2.log.info('starting fem2') sys.stdout.flush() try: fem2.read_bdf(out_model, xref=xref, punch=punch) except: print("failed reading %r" % out_model) raise #fem2.sumForces() #fem2.sumMoments() out_model2 = bdf_model + '_out2' fem2.write_bdf(out_model2, interspersed=True) #fem2.writeAsCTRIA3(out_model_2) os.remove(out_model2) return fem2
def run_fem2(bdf_model, out_model, xref, punch, sum_load, size, precision, reject, debug=False, log=None): assert os.path.exists(bdf_model), bdf_model assert os.path.exists(out_model), out_model fem2 = BDF(debug=debug, log=log) fem2.log.info('starting fem2') sys.stdout.flush() try: fem2.read_bdf(out_model, xref=xref, punch=punch) except: print("failed reading %r" % out_model) raise #fem2.sumForces() #fem2.sumMoments() out_model2 = bdf_model + '_out2' fem2.write_bdf(out_model2, interspersed=True) #fem2.writeAsCTRIA3(out_model_2) os.remove(out_model2) return fem2
def bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False, starting_id_dict=None, round_ids=False, cards_to_skip=None): """ Renumbers a BDF Parameters ---------- bdf_filename : str a bdf_filename (string; supported) or a BDF model (BDF) that has been cross referenced and is fully valid (a equivalenced deck is not valid) bdf_filename_out : str a bdf_filename to write size : int; {8, 16}; default=8 the bdf write precision is_double : bool; default=False the field precision to write starting_id_dict : dict, None (default=None) None : renumber everything starting from 1 dict : {key : starting_id} key : str the key (e.g. eid, nid, cid, ...) starting_id : int, None int : the value to start from None : don't renumber this key round_ids : bool; default=False Should a rounding up be applied for each variable? This makes it easier to read a deck and verify that it's been renumbered properly. This only really applies when starting_id_dict is None cards_to_skip : List[str]; (default=None -> don't skip any cards) There are edge cases (e.g. FLUTTER analysis) where things can break due to uncross-referenced cards. You need to disable entire classes of cards in that case (e.g. all aero cards). .. todo:: bdf_model option for bdf_filename hasn't been tested .. todo:: add support for subsets (e.g. renumber only a subset of nodes/elements) .. todo:: doesn't support partial renumbering .. todo:: doesn't support element material coordinate systems ..warning :: spoints might be problematic...check ..warning :: still in development, but it usually brutally crashes if it's not supported ..warning :: be careful of card unsupported cards (e.g. ones not read in) Supports ======== - GRIDs - no superelements - COORDx - elements - CELASx/CONROD/CBAR/CBEAM/CQUAD4/CTRIA3/CTETRA/CPENTA/CHEXA - RBAR/RBAR1/RBE1/RBE2/RBE3/RSPLINE - properties - PSHELL/PCOMP/PCOMPG/PSOLID/PSHEAR/PBAR/PBARL PROD/PTUBE/PBEAM - mass - CMASSx/CONMx/PMASS - aero - FLFACT - SPLINEx - FLUTTER - partial case control - METHOD/CMETHOD/FREQENCY - LOAD/DLOAD/LSEQ/LOADSET...LOADSET/LSEQ is iffy - SET cards - nodes - elements - SPC/MPC/FLUTTER/FLFACT - constraints - SPC/SPCADD/SPCAX/SPCD - MPC/MPCADD - SUPORT/SUPORT1 - solution control/methods - TSTEP/TSTEPNL - NLPARM - EIGB/EIGC/EIGRL/EIGR - sets - USET - other - tables - materials - loads/dloads Not Done ======== - SPOINT - any cards with SPOINTs - DMIG/DMI/DMIJ/DMIJI/DMIK/etc. - CELASx - CDAMPx - superelements - aero cards - CAEROx - PAEROx - thermal cards? - optimization cards - SETx - PARAM,GRDPNT,x; where x>0 - GRID SEID - case control - STATSUB - SUBCASE - global SET cards won't be renumbered properly Examples -------- # Renumber Everything; Start from 1 >>> bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False, round_ids=False) # Renumber Everything; Start Material IDs from 100 >>> starting_id_dict = { 'mid' : 100, } >>> bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False, starting_ids_dict=starting_ids_dict, round_ids=False) # Only Renumber Material IDs >>> starting_id_dict = { 'cid' : None, 'nid' : None, 'eid' : None, 'pid' : None, 'mid' : 1, 'spc_id' : None, 'mpc_id' : None, 'load_id' : None, 'dload_id' : None, 'method_id' : None, 'cmethod_id' : None, 'spline_id' : None, 'table_id' : None, 'flfact_id' : None, 'flutter_id' : None, 'freq_id' : None, 'tstep_id' : None, 'tstepnl_id' : None, 'suport_id' : None, 'suport1_id' : None, 'tf_id' : None, } >>> bdf_renumber(bdf_filename, bdf_filename_out, size=8, is_double=False, starting_ids_dict=starting_ids_dict, round_ids=False) """ starting_id_dict_default = { 'cid': 1, 'nid': 1, 'eid': 1, 'pid': 1, 'mid': 1, 'spc_id': 1, 'mpc_id': 1, 'load_id': 1, 'dload_id': 1, 'method_id': 1, 'cmethod_id': 1, 'spline_id': 1, 'table_id': 1, 'flfact_id': 1, 'flutter_id': 1, 'freq_id': 1, 'tstep_id': 1, 'tstepnl_id': 1, 'suport_id': 1, 'suport1_id': 1, 'tf_id': 1, } # fill up starting_id_dict if starting_id_dict is None: starting_id_dict = starting_id_dict_default else: for key, value in iteritems(starting_id_dict_default): if key not in starting_id_dict: starting_id_dict[key] = value nid = None cid = None eid = None pid = None mid = None spc_id = None mpc_id = None load_id = None dload_id = None method_id = None cmethod_id = None spline_id = None table_id = None flfact_id = None flutter_id = None freq_id = None tstep_id = None tstepnl_id = None suport_id = None suport1_id = None tf_id = None # turn them into variables for key, value in sorted(iteritems(starting_id_dict)): #assert isinstance(key, string_types), key assert key in starting_id_dict_default, 'key=%r is invalid' % (key) if value is None: pass else: if not isinstance(value, integer_types): msg = 'key=%r value=%r must be an integer; type(value)=%s' % ( key, value, type(value)) raise TypeError(msg) if key == 'nid': nid = int(value) elif key == 'cid': if value is None: cid = None else: cid = int(value) elif key == 'eid': eid = int(value) elif key == 'pid': if value is None: pid = None else: pid = int(value) elif key == 'mid': if value is None: mid = None else: mid = int(value) elif key == 'spc_id': spc_id = int(value) elif key == 'mpc_id': mpc_id = int(value) elif key == 'load_id': load_id = int(value) elif key == 'dload_id': dload_id = int(value) elif key == 'method_id': method_id = int(value) elif key == 'cmethod_id': cmethod_id = int(value) elif key == 'spline_id': spline_id = int(value) elif key == 'table_id': table_id = int(value) elif key == 'flfact_id': flfact_id = int(value) elif key == 'flutter_id': flutter_id = int(value) elif key == 'freq_id': freq_id = int(value) elif key == 'tstep_id': tstep_id = int(value) elif key == 'tstepnl_id': tstepnl_id = int(value) elif key == 'suport_id': suport_id = int(value) elif key == 'suport1_id': suport1_id = int(value) elif key == 'tf_id': tf_id = int(value) else: raise NotImplementedError('key=%r' % key) # build the maps #eid_map = {} #nid_map = {} #reverse_nid_map = {} #pid_map = {} #mid_map = {} #mpc_map = {} #spc_map = {} dload_map = {} load_map = {} cmethod_map = {} method_map = {} #flfact_map = {} #flutter_map = {} #aefact_map = {} #freq_map = {} tstep_map = {} tstepnl_map = {} suport_map = {} suport1_map = {} if isinstance(bdf_filename, string_types): model = BDF(debug=False) model.disable_cards(cards_to_skip) model.read_bdf(bdf_filename) else: model = bdf_filename elements = [ model.celas1, model.celas2, model.celas3, model.celas4, #model.cdamp1, #model.cdamp2, #model.cdamp3, #model.cdamp4, model.conrod, model.crod, model.ctube, model.cbar, model.cbeam, model.cshear, model.cquad4, model.ctria3, model.cquad8, model.ctria6, #model.ctriax, model.ctriax6, model.ctetra4, model.ctetra10, model.cpenta6, model.cpenta15, #model.cpyram5, model.cpyram13, model.chexa8, model.chexa20, ] props = [ model.pelas, #model.pdamp, model.ptube, model.ptube, model.pbar, model.pbarl, model.pbeam, model.pbeaml, model.pshear, model.pshell, model.pcomp, #model.pcompg, model.psolid, model.plsolid, ] materials = [ model.mat1, #model.mat2, #model.mat3, #model.mat4, #model.mat5, model.mat8, #model.mat9, #model.mat10, #model.mat11, ] loads = [ model.force, model.force1, model.force2, model.moment, model.moment1, model.moment2, model.pload, model.pload1, model.pload2, model.pload4, #model.rforce, #model.dload, #model.load, #model.sload, ] nid_map = {} #reverse_nid_map = {} if 'nid' in starting_id_dict and nid is not None: #i = nid #nid_map = {} ngrids = model.grid.n if ngrids: nids = model.grid.node_id - 1 nid_map.update({(nid + nids[i]): (i + 1) for i in range(ngrids)}) #reverse_nid_map.update( #{(i+1) : (nid + nids[i]) for i in range(ngrids)}) # index to nid #print(min(nid_map)) # TODO: SPOINTs # TODO: EPOINTs #if model.spoints.points: cid_map = {} if 'cid' in starting_id_dict and cid is not None: cids = model.coords.coords.keys() #print(cids) ncoords = len(cids) cids.sort() #print('cids =', cids) cid_map.update({(cid + cids[i] - 1): (i) for i in range(ncoords)}) #print('cid_map =', cid_map) eid_map = {} if 'eid' in starting_id_dict and pid is not None: eids = [element.element_id for element in elements if element.n] eids.append(model.rigid_elements.keys()) eids = np.hstack(eids) neids = len(eids) eids.sort() eid_map.update({eids[i]: (i + eid) for i in range(neids)}) pid_map = {} if 'pid' in starting_id_dict and pid is not None: pids = np.hstack([prop.property_id for prop in props if prop.n]) npids = len(pids) pids.sort() pid_map.update({pids[i]: (i + pid) for i in range(npids)}) mid_map = {} if 'mid' in starting_id_dict and mid is not None: mids = np.hstack([mat.material_id for mat in materials]) nmids = len(mids) mids.sort() mid_map.update({mids[i]: (mid + i) for i in range(nmids)}) load_map = {} if 'load_id' in starting_id_dict and load_id is not None: loadsi = [load.load_id for load in loads if load.n] if loadsi: #print(loadsi) load_ids = np.unique(np.hstack(loadsi)) del loadsi nload_ids = len(load_ids) load_ids.sort() load_map.update( {load_ids[i]: (load_id + i) for i in range(nload_ids)}) spc_map = {} if 'spc_id' in starting_id_dict and spc_map is not None: spcs = [model.spc, model.spc1, model.spcadd] spcsi = [] for spc_obj in spcs: #print(spc_obj) #spc_ids = [spc.spc_id for spc_id, spc in iteritems(spc_obj) if spc.n] spc_ids = spc_obj.keys() if spc_ids: spcsi.append(spc_ids) #spcsi = [spc_id for spc_id in spcs] #print('spcsi =', spcsi) #asdf if spcsi: #print(loadsi) spc_ids = np.unique(np.hstack(spcsi)) #del spcsi nspc_ids = len(spc_ids) spc_ids.sort() spc_map.update({spc_ids[i]: (spc_id + i) for i in range(nspc_ids)}) #print('spc_ids =', spc_ids) caero_map = {} #if model.caeros: #caeros = model.caeros.keys() #caeros.sort() #ncaeros = len(caeros) #caero_map = {caeros[i] : (i+1) for i in range(ncaeros)} paero_map = {} if model.paeros: paeros = model.paeros.keys() paeros.sort() npaeros = len(paeros) paero_map = {paeros[i]: (i + 1) for i in range(npaeros)} aefact_map = {} if model.aefacts: aefacts = model.aefacts.keys() aefacts.sort() naefacts = len(aefacts) aefact_map = {aefacts[i]: (i + 1) for i in range(naefacts)} spline_map = {} #if model.splines: #splines = model.splines.keys() #splines.sort() #nsplines = len(splines) #spline_map = {splines[i] : (i+1) for i in range(nsplines)} set_map = {} if model.sets: sets = model.sets.keys() sets.sort() nsets = len(sets) set_map = {sets[i]: (i + 1) for i in range(nsets)} #load_map = {} maps = { 'node': nid_map, 'coord': cid_map, 'property': pid_map, 'element': eid_map, 'load': load_map, 'material': mid_map, 'caero': caero_map, # ??? 'paero': paero_map, # PAEROx 'aefact': aefact_map, # ??? 'spline': spline_map, # SPLINE1-SPLINE5 'set': set_map, } model.grid.update(maps) model.coords.update(maps) for elem in elements: elem.update(maps) rigid_elements2 = {} for eid, elem in iteritems(model.rigid_elements): eid2 = eid_map[eid] rigid_elements2[eid2] = eid_map[eid] elem.update(maps) for prop in props: prop.update(maps) for mat in materials: mat.update(maps) for spc_dict in spcs: for spc_id, spc in iteritems(spc_dict): spc.update(maps) if model.aero is not None: model.aero.update(maps) if model.aeros is not None: model.aeros.update(maps) for caero in itervalues(model.caeros): caero.update(maps) for spline in itervalues(model.splines): spline.update(model, maps) for flutter in itervalues(model.flutters): flutter.update(maps) for flfact in itervalues(model.flfacts): flfact.update(maps) for flutter in itervalues(model.flutters): flutter.update(maps) for desvar in itervalues(model.desvars): desvar.update(maps) for dconstr in itervalues(model.dconstrs): dconstr.update(maps) for dresp in itervalues(model.dresps): dresp.update(maps) for dconadd in itervalues(model.dconadds): dconadd.update(maps) for dvgrid in itervalues(model.dvgrids): dvgrid.update(maps) for dvcrel in itervalues(model.dvcrels): dvcrel.update(maps) for dvmrel in itervalues(model.dvmrels): dvmrel.update(maps) for dvprel in itervalues(model.dvprels): dvprel.update(maps) model.darea.update(maps) model.dphase.update(maps) if bdf_filename_out is not None: model.write_bdf(bdf_filename_out, size=size, is_double=is_double, interspersed=False) return model
def get_mass(self, nid1, nid2, xyz1, xyz2, eid, pid, mid, A, J, c, nsm, E, G, nu, rho, L): """tests a CROD and a CONROD""" card_count = { 'CONROD' : 1, 'CTUBE' : 1, 'PTUBE' : 1, 'CROD' : 1, 'PROD' : 1, 'GRID' : 2, 'MAT1' : 1, } model = BDF(debug=debug) model.allocate(card_count) lines = ['conrod,%i, %i, %i, %i, %f, %f, %f, %f' % (eid, nid1, nid2, mid, A, J, c, nsm)] model.add_card(lines, 'conrod', is_list=False) lines = ['crod,%i, %i, %i, %i' % (eid+1, pid, nid1, nid2)] model.add_card(lines, 'crod', is_list=False) lines = ['ctube,%i, %i, %i, %i' % (eid+2, pid+1, nid1, nid2)] model.add_card(lines, 'ctube', is_list=False) lines = ['prod,%i, %i, %f, %f, %f, %f' % (pid, mid, A, J, c, nsm)] model.add_card(lines, 'prod', is_list=False) OD1 = sqrt(4 * A / pi) t = 0. OD2 = OD1 lines = ['ptube,%i, %i, %f, %f, %f, %f' % (pid+1, mid, OD1, t, nsm, OD2)] model.add_card(lines, 'ptube', is_list=False) lines = ['mat1,%i, %.2e, %.2e, %f, %f' % (mid, E, G, nu, rho)] model.add_card(lines, 'mat1', is_list=False) lines = ['grid,%i, %i, %f, %f, %f' % (nid1, 0, xyz1[0], xyz1[1], xyz1[2])] model.add_card(lines, 'grid', is_list=False) lines = ['grid,%i, %i, %f, %f, %f' % (nid2, 0, xyz2[0], xyz2[1], xyz2[2])] model.add_card(lines, 'grid', is_list=False) model.build() mass = L * (rho * A + nsm) f = StringIO() model.write_bdf(out_filename=f, interspersed=True, size=8, precision='single', enddata=None) print(f.getvalue()) #positions = model.get_positions() grid_cid0 = None # conrod conrod = model.conrod.slice_by_element_id(eid) self.assertEqual(conrod.get_element_id_by_element_index(), eid) #self.assertEqual(conrod.get_property_id_by_element_id(), None) self.assertEqual(conrod.get_material_id_by_element_id(eid), mid) self.assertEqual(conrod.get_length_by_element_index(i=None, grid_cid0=grid_cid0), L) #self.assertEqual(conrod.Nsm(), nsm) rhoi = conrod.get_density_by_element_id(eid) Ai = conrod.get_area_by_element_id(eid) Li = conrod.get_length_by_element_id(eid, grid_cid0=grid_cid0) nsmi = conrod.get_non_structural_mass_by_element_id(eid) massa = conrod.get_mass_by_element_index() mass_msg_conrod = 'mass = L * (rho * A + nsm)\n' mass_msg_conrod += 'L=%s expected=%s\n' % (Li, L) mass_msg_conrod += 'rho=%s expected=%s\n' % (rhoi, rho) mass_msg_conrod += 'A=%s expected=%s\n' % (Ai, A) mass_msg_conrod += 'nsm=%s expected=%s\n' % (nsmi, nsm) mass_msg_conrod += 'mass=%s actual=%s expected=%s\n' % (Li * (rhoi*Ai + nsmi), massa, mass) #mass_msg_conrod += 'mass=%s expected=%s\n' % (Li * (rhoi*Ai + nsmi), mass) self.assertEqual(massa, mass, mass_msg_conrod) #self.assertEqual(conrod.E(), E) #self.assertEqual(conrod.G(), G) #self.assertEqual(conrod.area(), A) #self.assertEqual(conrod.J(), J) #self.assertEqual(conrod.C(), c) #self.assertEqual(conrod.Rho(), rho) # crod crod_eid = eid + 1 crod = model.crod.slice_by_element_id([crod_eid]) self.assertEqual(crod.get_element_id_by_element_index(), crod_eid) self.assertEqual(crod.get_property_id_by_element_id(crod_eid), pid) self.assertEqual(crod.get_material_id_by_element_id(crod_eid), mid) rhoi = crod.get_density_by_element_id(crod_eid) Ai = crod.get_area_by_element_id(crod_eid) Li = crod.get_length_by_element_id(crod_eid, grid_cid0=grid_cid0) nsmi = crod.get_non_structural_mass_by_element_id(crod_eid) self.assertEqual(Li, L) #self.assertEqual(crod.Nsm(), nsm) massa = crod.get_mass_by_element_id(crod_eid) mass_msg_crod = 'mass = L * (rho * A + nsm)\n' mass_msg_crod += 'L=%s expected=%s\n' % (Li, L) mass_msg_crod += 'rho=%s expected=%s\n' % (rhoi, rho) mass_msg_crod += 'A=%s expected=%s\n' % (Ai, A) mass_msg_crod += 'nsm=%s expected=%s\n' % (nsmi, nsm) mass_msg_crod += 'mass=%s actual=%s expected=%s\n' % (Li * (rhoi*Ai + nsmi), massa, mass) self.assertEqual(massa, mass, mass_msg_crod) #self.assertEqual(crod.E(), E) #self.assertEqual(crod.G(), G) #self.assertEqual(crod.area(), A) #self.assertEqual(crod.J(), J) #self.assertEqual(crod.C(), c) #self.assertEqual(crod.Rho(), rho) #self.assertEqual(crod.Nu(), nu) # prod prod = model.prod.slice_by_property_id([pid]) self.assertEqual(prod.property_id[0], pid) self.assertEqual(prod.get_material_id_by_property_id(pid), mid) self.assertEqual(prod.get_non_structural_mass_by_property_id(pid), nsm) self.assertEqual(prod.get_E_by_property_id(pid), E) self.assertEqual(prod.get_G_by_property_id(pid), G) self.assertEqual(prod.get_area_by_property_id(pid), A) self.assertEqual(prod.get_J_by_property_id(pid), J) self.assertEqual(prod.get_c_by_property_id(pid), c) self.assertEqual(prod.get_density_by_property_id(pid), rho) # ctube if 1: ctube_eid = eid + 2 ptube_pid = pid + 1 assert ctube_eid == 12, ctube_eid assert ptube_pid == 68, ptube_pid ctube = model.ctube.slice_by_element_id(ctube_eid) self.assertEqual(ctube.get_element_id_by_element_index(), ctube_eid) self.assertEqual(ctube.get_property_id_by_element_id(ctube_eid), ptube_pid) self.assertEqual(ctube.get_material_id_by_element_id(ctube_eid), mid) self.assertEqual(ctube.get_length_by_element_id(ctube_eid, grid_cid0), L) self.assertEqual(ctube.get_non_structural_mass_by_element_id(ctube_eid), nsm) self.assertAlmostEquals(ctube.get_mass_by_element_id(ctube_eid), mass, 5) self.assertEqual(ctube.get_E_by_element_id(ctube_eid), E) self.assertEqual(ctube.get_G_by_element_id(ctube_eid), G) self.assertAlmostEquals(ctube.get_area_by_element_id(ctube_eid), A, 5) ctube.get_J_by_element_id(ctube_eid) self.assertEqual(ctube.get_density_by_element_id(), rho) # ptube ptube = model.ptube.slice_by_property_id(pid+1) self.assertEqual(ptube.get_property_id_by_property_index(), pid+1) self.assertEqual(ptube.get_material_id_by_property_id(), mid) self.assertEqual(ptube.get_non_structural_mass_by_property_id(), nsm) self.assertEqual(ptube.get_E_by_property_id(), E) self.assertEqual(ptube.get_G_by_property_id(), G) self.assertAlmostEquals(ptube.get_area_by_property_id(), A, 5) ptube.get_J_by_property_id() self.assertEqual(ptube.get_density_by_property_id(), rho)