Source code for pyNastran.bdf.bdfInterface.getCard

# pylint: disable=E1101,C0103,C0111
from __future__ import (nested_scopes, generators, division, absolute_import,
                        print_function, unicode_literals)
from six import string_types, iteritems
#import sys
from numpy import ndarray

from pyNastran.bdf.deprecated import GetMethodsDeprecated
from pyNastran.bdf.cards.nodes import SPOINT


[docs]class GetMethods(GetMethodsDeprecated): def __init__(self): pass
[docs] def get_node_ids_with_element(self, eid, msg=''): return self.get_node_ids_with_elements([eid], msg=msg)
[docs] def get_node_ids_with_elements(self, eids, msg=''): """ Get the node IDs associated with a list of element IDs :param self: the BDF object :param eids: list of element ID :param msg: a additional message to print out if an element is not found :returns node_ids: set of node IDs For example .. code-block:: python >>> eids = [1, 2, 3] # list of elements with pid=1 >>> msg = ' which are required for pid=1' >>> node_ids = bdf.get_node_ids_with_elements(eids, msg=msg) """ nids2 = set([]) for eid in eids: element = self.Element(eid, msg=msg) self.log.debug("element.pid = %s" % (element.pid)) nids = set(element.nodeIDs()) nids2.update(nids) return nids2
[docs] def Node(self, nid, allowEmptyNodes=False, msg=''): if (nid == 0 or nid is None) and allowEmptyNodes: return None elif nid in self.nodes: return self.nodes[nid] elif self.spoints and nid in self.spoints.spoints: return SPOINT(nid) else: assert isinstance(nid, int), 'nid should be an integer; not %s' % type(nid) raise RuntimeError('nid=%s is not a GRID or SPOINT%s' % (nid, msg))
[docs] def Nodes(self, nids, allowEmptyNodes=False, msg=''): """ Returns a series of node objects given a list of node IDs """ nodes = [] for nid in nids: nodes.append(self.Node(nid, allowEmptyNodes, msg)) return nodes #-------------------- # ELEMENT CARDS
[docs] def get_element_ids_list_with_pids(self, pids): """ Gets all the element IDs with a specific property ID. :param self: the BDF object :param pids: list of property ID :returns element_ids: as a list For example, we want to get all the element ids with ``pids=[1, 2, 3]`` .. code-block:: python model = BDF() model.read_bdf(bdf_filename) pids = [1, 2, 3] eids_list = model.get_element_ids_with_pids(pids, mode='list') """ assert isinstance(pids, list), pids eids2 = [] for eid, element in sorted(iteritems(self.elements)): pid = element.Pid() if pid in pids: eids2.append(eid) return eids2
[docs] def get_element_ids_dict_with_pids(self, pids): """ Gets all the element IDs with a specific property ID. :param self: the BDF object :param pids: list of property ID :returns element_ids: as a dictionary of lists by property For example, we want all the elements with ``pids=[4, 5, 6]``, but we want them in separate groups .. code-block:: python model = BDF() model.read_bdf(bdf_filename) pids = [4, 5, 6] eids_dict = model.get_element_ids_with_pids(pids, mode='dict') """ assert isinstance(pids, list), pids eids2 = {} for pid in pids: eids2[pid] = [] for eid, element in iteritems(self.elements): try: pid = element.Pid() if pid in pids: eids2[pid].append(eid) except AttributeError: #eids2[0].append(eid) pass return eids2
[docs] def get_node_id_to_element_ids_map(self): """ Returns a dictionary that maps a node ID to a list of elemnents .. todo:: support 0d or 1d elements .. todo:: support elements with missing nodes (e.g. CQUAD8 with missing nodes) """ nidToElementsMap = {} for nid in self.nodes: # initalize the mapper nidToElementsMap[nid] = [] if self.spoints: # SPOINTs for nid in sorted(self.spoints.spoints): # SPOINTs nidToElementsMap[nid] = [] for (eid, element) in iteritems(self.elements): # load the mapper try: # not supported for 0-D and 1-D elements nids = element.nodeIDs() for nid in nids: # (e.g. CQUAD8 with missing node) nidToElementsMap[nid].append(eid) except: pass return nidToElementsMap
[docs] def get_property_id_to_element_ids_map(self): """ Returns a dictionary that maps a property ID to a list of elemnents """ pidToEidsMap = {} pids = self.property_ids for pid in pids: pidToEidsMap[pid] = [] for eid in self.element_ids: element = self.Element(eid) if hasattr(element, 'pid'): pid = element.Pid() if pid == 0: # CONM2 continue pidToEidsMap[pid].append(eid) return pidToEidsMap
[docs] def get_material_id_to_property_ids_map(self): """ Returns a dictionary that maps a material ID to a list of properties :returns mid_to_pids_map: the mapping .. code-block:: python >>> mid_to_pid_map = get_material_id_to_property_ids_map() >>> mid = 1 >>> pids = get_material_id_to_property_ids_map[mid] >>> pids [1, 2, 3] .. note:: all properties require an mid to be counted (except for PCOMP, which has multiple mids) """ mid_to_pids_map = {} for mid in self.get_material_ids(): mid_to_pids_map[mid] = [] for pid in self.property_ids: prop = self.Property(pid) if prop.type in ['PCOMP', 'PCOMPG']: mids = prop.Mids() for mid in mids: if pid not in mid_to_pids_map[mid]: mid_to_pids_map[mid].append(pid) else: # PCOMP if hasattr(prop, 'mid') and prop.Mid() in mids: if pid not in mid_to_pids_map[mid]: mid_to_pids_map[mid].append(pid) else: if hasattr(prop, 'Mids'): mids = prop.Mids() else: mids = [prop.Mid()] for mid in mids: mid_to_pids_map[mid].append(pid) return mid_to_pids_map
[docs] def Element(self, eid, msg=''): try: return self.elements[eid] except KeyError: raise KeyError('eid=%s not found%s. Allowed elements=%s' % (eid, msg, self.elements.keys()))
[docs] def Elements(self, eids, msg=''): elements = [] for eid in eids: elements.append(self.Element(eid, msg)) return elements
[docs] def Mass(self, eid, msg=''): try: return self.masses[eid] except KeyError: raise KeyError('eid=%s not found%s. Allowed masses=%s' % (eid, msg, self.masses.keys()))
[docs] def RigidElement(self, eid, msg=''): try: return self.rigidElements[eid] except KeyError: raise KeyError('eid=%s not found%s. Allowed rigidElements=%s' % (eid, msg, self.rigidElements.keys())) #-------------------- # PROPERTY CARDS
[docs] def Property(self, pid, msg=''): try: return self.properties[pid] except KeyError: raise KeyError('pid=%s not found%s. Allowed Pids=%s' % (pid, msg, self.property_ids))
[docs] def Properties(self, pids, msg=''): properties = [] for pid in pids: properties.append(self.Property(pid, msg)) return properties
[docs] def PropertyMass(self, pid, msg=''): try: return self.properties_mass[pid] except KeyError: raise KeyError('pid=%s not found%s. Allowed Mass Pids=%s' % (pid, msg, self.mass_property.keys()))
[docs] def Phbdy(self, pid, msg=''): try: return self.phbdys[pid] except KeyError: raise KeyError('pid=%s not found%s. Allowed PHBDY Pids=%s' % (pid, msg, self.phbdys.keys())) #-------------------- # MATERIAL CARDS
[docs] def get_structural_material_ids(self): return self.materials.keys()
[docs] def get_material_ids(self): return self.materials.keys() + self.thermalMaterials.keys()
[docs] def get_thermal_material_ids(self): return self.thermalMaterials.keys()
[docs] def Material(self, mid, msg=''): if mid in self.materials: return self.materials[mid] elif mid in self.thermalMaterials: return self.thermalMaterials[mid] else: msg = '\n' + msg raise KeyError('Invalid Material ID: mid=%s%s' % (mid, msg))
[docs] def StructuralMaterial(self, mid, msg=''): try: mat = self.materials[mid] except KeyError: msg = '\n' + msg raise KeyError('Invalid Structural Material ID: mid=%s%s' % (mid, msg)) return mat
[docs] def ThermalMaterial(self, mid, msg=''): try: mat = self.thermalMaterials[mid] except KeyError: msg = '\n' + msg raise KeyError('Invalid Thermal Material ID: mid=%s%s' % (mid, msg)) return mat
[docs] def HyperelasticMaterial(self, mid, msg=''): try: mat = self.hyperelasticMaterials[mid] except KeyError: msg = '\n' + msg raise KeyError('Invalid Hyperelastic Material ID: mid=%s%s' % (mid, msg)) return mat
[docs] def Materials(self, mids, msg=''): materials = [] for mid in mids: materials.append(self.Material(mid, msg)) return materials #-------------------- # LOADS
[docs] def Load(self, sid, msg=''): assert isinstance(sid, int), 'sid=%s is not an integer\n' % sid if sid in self.loads: load = self.loads[sid] else: raise KeyError('cannot find LoadID=%r%s.\nLoadIDs=%s\n' % (sid, msg, sorted(self.loads.keys()))) return load
[docs] def DLoad(self, sid, msg=''): assert isinstance(sid, int), 'sid=%s is not an integer\n' % sid if sid in self.dloads: load = self.dloads[sid] else: raise KeyError('cannot find DLoadID=%r%s.\nDLoadIDs=%s\n' % (sid, msg, sorted(self.dloads.keys()))) return load
[docs] def get_dload_entries(self, sid, msg=''): assert isinstance(sid, int), 'sid=%s is not an integer\n' % sid if sid in self.dload_entries: load = self.dload_entries[sid] else: raise KeyError('cannot find DLoad Entry ID=%r%s.\nDLoadEntryIDs=%s\n' % (sid, msg, sorted(self.dload_entries.keys()))) return load #-------------------- # SPCs
[docs] def SPC(self, conid, msg=''): assert isinstance(conid, int), 'conid=%s is not an integer\n' % conid if conid in self.spcs: constraint = self.spcs[conid] else: raise KeyError('cannot find ConstraintID=%r.\n%s' % (conid, msg)) return constraint #-------------------- # COORDINATES CARDS
[docs] def Coord(self, cid, msg=''): try: return self.coords[cid] except KeyError: raise KeyError('cid=%s not found%s. Allowed Cids=%s' % (cid, msg, self.coord_ids)) #-------------------- # AERO CARDS
[docs] def AEList(self, aelist, msg=''): try: return self.aelists[aelist] except KeyError: raise KeyError('aelist=%s not found%s. Allowed AELIST=%s' % (aelist, msg, self.aelists.keys()))
[docs] def AEFact(self, aefact, msg=''): try: return self.aefacts[aefact] except KeyError: raise KeyError('aefact=%s not found%s. Allowed AEFACT=%s' % (aefact, msg, self.aefacts.keys()))
[docs] def Aero(self, acsid, msg=''): try: return self.aero[acsid] except KeyError: raise KeyError('acsid=%s not found%s. Allowed AERO=%s' % (acsid, msg, self.aero.keys()))
[docs] def Aeros(self, acsid, msg=''): try: return self.aeros[acsid] except KeyError: raise KeyError('acsid=%s not found%s. Allowed AEROS=%s' % (acsid, msg, self.aeros.keys()))
[docs] def Spline(self, eid, msg=''): try: return self.splines[eid] except KeyError: raise KeyError('eid=%s not found%s. Allowed SPLINEx=%s' % (eid, msg, self.splines.keys()))
[docs] def CAero(self, eid, msg=''): try: return self.caeros[eid] except KeyError: raise KeyError('eid=%s not found%s. Allowed CAEROx=%s' % (eid, msg, self.caero_ids))
[docs] def PAero(self, pid, msg=''): try: return self.paeros[pid] except KeyError: raise KeyError('pid=%s not found%s. Allowed PAEROx=%s' % (pid, msg, self.paeros.keys()))
[docs] def Gust(self, sid, msg=''): try: return self.gusts[sid] except KeyError: raise KeyError('sid=%s not found%s. Allowed GUSTs=%s' % (sid, msg, self.gusts.keys())) #-------------------- # AERO CONTROL SURFACE CARDS
[docs] def AEStat(self, aid, msg=''): try: return self.aestats[aid] except KeyError: raise KeyError('aid=%s not found%s. Allowed AESTATs=%s' % (aid, msg, self.aestats.keys()))
[docs] def AEParam(self, aid, msg=''): try: return self.aeparams[aid] except KeyError: raise KeyError('aid=%s not found%s. Allowed AEPARMs=%s' % (aid, msg, self.aeparams.keys())) #-------------------- # FLUTTER CARDS
[docs] def FLFACT(self, sid, msg=''): try: return self.flfacts[sid] except KeyError: raise KeyError('sid=%s not found%s. Allowed FLFACTs=%s' % (sid, msg, self.flfacts.keys()))
[docs] def Flutter(self, fid, msg=''): try: return self.flutters[fid] except KeyError: raise KeyError('fid=%s not found%s. Allowed FLUTTERs=%s' % (fid, msg, self.flutters.keys())) #-------------------- # OPTIMIZATION CARDS
[docs] def DConstr(self, oid, msg=''): try: return self.dconstrs[oid] except KeyError: raise KeyError('oid=%s not found%s. Allowed DCONSTRs=%s' % (oid, msg, self.dconstrs.keys()))
[docs] def Desvar(self, oid, msg=''): try: return self.desvars[oid] except KeyError: raise KeyError('oid=%s not found%s. Allowed DESVARs=%s' % (oid, msg, self.desvars.keys()))
[docs] def DDVal(self, oid, msg=''): try: return self.ddvals[oid] except KeyError: raise KeyError('oid=%s not found%s. Allowed DDVALs=%s' % (oid, msg, self.ddvals.keys())) #-------------------- # SET CARDS
[docs] def Set(self, sid, msg=''): try: return self.sets[sid] except KeyError: raise KeyError('sid=%s not found%s. Allowed SETx=%s' % (sid, msg, self.sets.keys()))
[docs] def SetSuper(self, seid, msg=''): try: return self.setsSuper[seid] except KeyError: raise KeyError('seid=%s not found%s. Allowed SETx=%s' % (seid, msg, self.setsSuper.keys())) #-------------------- # METHOD CARDS
[docs] def Method(self, sid, msg=''): try: return self.methods[sid] except KeyError: raise KeyError('sid=%s not found%s. Allowed METHODs=%s' % (sid, msg, self.methods.keys()))
[docs] def CMethod(self, sid, msg=''): try: return self.cmethods[sid] except KeyError: raise KeyError('sid=%s not found%s. Allowed CMETHODs=%s' % (sid, msg, self.cmethods.keys())) #-------------------- # TABLE CARDS
[docs] def Table(self, tid, msg=''): try: return self.tables[tid] except KeyError: raise KeyError('tid=%s not found%s. Allowed TABLEs=%s' % (tid, msg, self.tables.keys()))
[docs] def RandomTable(self, tid, msg=''): try: return self.randomTables[tid] except KeyError: raise KeyError('tid=%s not found%s. Allowed TABLEs=%s' % (tid, msg, self.randomTables.keys())) #-------------------- # NONLINEAR CARDS
[docs] def NLParm(self, nid, msg=''): try: return self.nlparms[nid] except KeyError: raise KeyError('nid=%s not found%s. Allowed NLPARMs=%s' % (nid, msg, self.nlparms.keys())) #-------------------- # MATRIX ENTRY CARDS
[docs] def DMIG(self, dname, msg=''): try: return self.dmig[dname] except KeyError: raise KeyError('dname=%s not found%s. Allowed DMIGs=%s' % (dname, msg, self.dmig.keys()))
[docs] def get_x_associated_with_y(self, xdict, xkeys, ykeys, stop_on_failure=True): """ Get the range of sub-properties of a card. .. note:: Assumes you're taking a single path through the cards. You could probably explicitly code these queries faster, but this method has a lot of flexibility with very little user code. :param self: the BDF object :param xdict: the BDF attribute that should be querried (e.g. self.elements) :param xkeys: the list of object keys that should be stepped through associated with xdict (e.g. eids=[1, 2, 3]) :param ykeys: the list of response keys that should be stepped through (e.g. ['pid', 'mid', 'mid']) :param stop_on_failure: Should an error be raised if there is an invalid key? For example, get all material used by elements, but don't crash on CONRODs. :returns results: The set of all values used .. code-block:: python # Get nodes associated with eid=[1, 2, 3] nodes = self.get_x_associated_with_y( self.elements, [1, 2, 3], ['nodes']) # Get node IDs associated with eid=[1, 2, 3] nodesIDs = self.get_x_associated_with_y( self.elements, [1, 2, 3], ['nodes', 'nid']) # Get coord IDs associated with eid=[1, 2, 3] coordIDs = self.get_x_associated_with_y( self.elements, [1, 2, 3], ['nodes', 'cp', 'cid']) # Get properties associated with eid=[1, 2, 3] properties = self.get_x_associated_with_y( self.elements, [1, 2, 3], ['pid']) # Get materials associated with eid=[1, 2, 3] materials = self.get_x_associated_with_y( self.elements, [1, 2, 3], ['pid', 'mid']) # Get material IDs associated with eid=[1, 2, 3] materialIDs = self.get_x_associated_with_y( self.elements, [1, 2, 3], ['pid', 'mid', 'mid']) # Get the values for Young's Modulus E = self.get_x_associated_with_y( self.elements, None, ['pid', 'mid', 'e']) """ assert isinstance(xdict, dict), type(xdict) assert self._xref == True, self._xref if isinstance(xkeys, list) or isinstance(xkeys, tuple): pass elif isinstance(xkeys, ndarray): assert len(xkeys.shape) == 1, xkeys.shape assert isinstance(xkeys[0], int), type(xkeys[0]) elif xkeys is None: xkeys = xdict.iterkeys() else: raise RuntimeError('invalid type; type(xkeys)=%r' % type(xkeys)) assert isinstance(ykeys[0], string_types), ykeys out_set = set([]) for xkey in xkeys: xi = xdict[xkey] _getattr(out_set, xi, ykeys, len(ykeys)-1, stop_on_failure) return out_set
def __test_method(self): # getElementsAssociatedWithMaterialIDs(self): #getElementIDsAssociatedWithPropertyIDs #getPropertyIDsAssociatedWithMaterialIDs #get_x_associated_with_y(self, mids, 'pid', yname='mid') #CTETRA 1 1 8 13 67 33 #CTETRA 2 1 8 7 62 59 #CTETRA 3 1 8 45 58 66 #nids 7 8 13 33 45 58 59 62 66 67 cps = self.get_x_associated_with_y( self.elements, [1, 2, 3], ['nodes', 'cp', 'cast'], stop_on_failure=False) #print('*cps', cps) nids2 = self.get_x_associated_with_y(self.elements, [1, 2, 3], ['nodes', 'nid']) nids2 = list(nids2) nids2.sort() #print('*nids2', nids2) mids = self.get_x_associated_with_y( self.elements, [1, 2, 3, 4, 5], ['pid', 'mid']) #print('*mids', mids) mids2 = self.get_x_associated_with_y( self.elements, None, ['pid', 'mid', 'mid']) E = self.get_x_associated_with_y( self.elements, None, ['pid', 'mid', 'e']) #print('*E', E) #get_nodes_associated_with_elements #nids = get_x_associated_with_y(self, self.elements, 'nodes', 'nid') #pids = get_x_associated_with_y(self, self.elements, 'pid', 'pid') #mids = get_x_associated_with_y(self, self.properties, 'mid', 'mid')
[docs]def _getattr(out_set, xi, xkeys, nlevels_left=0, stop_on_failure=True): """ Recursive method to help get_x_associated_with_y get the value of xkeys for the given variable xi :param out_set: the SET of all outputs that will be filled and implicitly returned :type out_set: SET :param xi: the current variable being iterated over :type xi: BDF BaseCard :param xkeys: the variables left to iterate over :type xkeys: LIST of STRINGS :param nlevels_left: the number of levels still to iterate over :type nlevels_left: INT >= 0 :param stop_on_failure: should the code crash if a certain xkey cannot be found :type stop_on_failure: bool """ try: y = getattr(xi, xkeys[0]) except AttributeError: if stop_on_failure: raise return if nlevels_left: if isinstance(y, list): # handles nodes for yi in y: _getattr(out_set, yi, xkeys[1:], nlevels_left-1, stop_on_failure=stop_on_failure) else: _getattr(out_set, y, xkeys[1:], nlevels_left-1, stop_on_failure=stop_on_failure) else: # handles nodes if isinstance(y, list): for yi in y: out_set.add(yi) else: out_set.add(y)