def test_coord_xform_b(self): origin = array([0., 0., 0.]) zaxis = array([0., 0., 1.]) xzplane = array([1., 0., 0.]) cid0 = CORD2R(cid=0, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane) Lx = 2. Ly = 3. Lz = 5. Fy = 1.5 origin = array([-Lx, -Ly, -Lz]) z_axis = origin + array([0., 0., 1.]) xz_plane = origin + array([1., 0., 1.]) rid = 0 data = [1, rid] + list(origin) + list(z_axis) + list(xz_plane) fxyz = [0., -Fy, 0.] mxyz = [0., 0., 0.] cid_new = CORD2R.add_op2_data(data=data) model = None fxyz_local, mxyz_local = TransformLoadWRT(fxyz, mxyz, cid0, cid_new, model) r = array([Lx, Ly, Lz]) F = array([0., -Fy, 0.]) M = cross(r, F) self.assertTrue(array_equal(fxyz_local, F), 'expected=%s actual=%s' % (F, fxyz_local)) self.assertTrue(array_equal(mxyz_local, M), 'expected=%s actual=%s' % (M, mxyz_local))
def __init__(self, model): """ Defines the ShellProperties object. Parameters ---------- model : BDF the BDF object """ VectorizedCard.__init__(self, model) float_fmt = self.model.float_fmt self.n = 1 ncards = 1 origin = [0., 0., 0.] zaxis = [0., 0., 1.] xzplane = [1., 0., 0.] self.coords = { 0: CORD2R(0, origin, zaxis, xzplane), } self.coord_id = zeros(ncards, dtype='int32') self.Type = full(ncards, 'R', dtype='|U1') # R-CORD2R, S-CORD2S, C-CORD2C self.T = full((ncards, 3, 3), nan, dtype=float_fmt) self.T[0, :, :] = eye(3) self.origin = zeros((ncards, 3), dtype=float_fmt) self.is_resolved = full(ncards, True, dtype='bool')
def test_coord_adding(self): origin = [0., 0., 0.] zaxis = [0., 0., 1.] xzplane = [1., 0., 0.] unused_cid1 = CORD2R(cid=1, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane, comment='cord2r') xaxis = [1., 0., 0.] yaxis = [0., 1., 0.] zaxis = [0., 0., 1.] xz_plane = [1., 0., 1.] yz_plane = [0., 1., 1.] xy_plane = [1., 1., 0.] # x-axis unused_cid2 = CORD2R.add_axes(cid=2, rid=0, origin=origin, xaxis=xaxis, yaxis=None, zaxis=None, xyplane=None, yzplane=None, xzplane=xz_plane) unused_cid3 = CORD2R.add_axes(cid=2, rid=0, origin=origin, xaxis=xaxis, yaxis=None, zaxis=None, xyplane=xy_plane, yzplane=None, xzplane=None) # y-axis unused_cid4 = CORD2R.add_axes(cid=4, rid=0, origin=origin, xaxis=None, yaxis=yaxis, zaxis=None, xyplane=xy_plane, yzplane=None, xzplane=None) unused_cid5 = CORD2R.add_axes(cid=5, rid=0, origin=origin, xaxis=None, yaxis=yaxis, zaxis=None, xyplane=None, yzplane=yz_plane, xzplane=None) # z-axis unused_cid4 = CORD2R.add_axes(cid=4, rid=0, origin=origin, xaxis=None, yaxis=None, zaxis=zaxis, xyplane=None, yzplane=None, xzplane=xz_plane) unused_cid5 = CORD2R.add_axes(cid=5, rid=0, origin=origin, xaxis=None, yaxis=None, zaxis=zaxis, xyplane=None, yzplane=yz_plane, xzplane=None) # ijk unused_cid6 = CORD2R.add_ijk(cid=6, rid=0, origin=origin, i=xaxis, j=yaxis, k=None) unused_cid7 = CORD2R.add_ijk(cid=7, rid=0, origin=origin, i=xaxis, j=None, k=zaxis) unused_cid8 = CORD2R.add_ijk(cid=8, rid=0, origin=origin, i=None, j=yaxis, k=zaxis)
def _cut_model(nids, xyz_cp, edges, view_up, p1, p2, tol, nodal_result, plane_atol=1e-5, plane_bdf_filename=None): """ Helper method for cut_edge_model_by_axes Parameters ---------- edges : (nedges, 2) int ndarray the edges view_up : (3,) float ndarray the up/z vector p1 / p2 : (3,) float ndarray the start/end points tol : float the tolerance to filter edges (using some large value) to prevent excessive computations plane_atol : float; default=1e-5 the tolerance for a line that's located on the y=0 local plane plane_bdf_filename : str; default=None optionally write a BDF of the cut Returns ------- local_points_array : (N, 3) float ndarray the xyz points in the cutting plane coordinate system global_points_array : (N, 3) float ndarray the xyz points in the global xyz coordinate system result_array : (N, 7) float ndarray inid, x, y, z, xg, yg, zg, result """ #view_up = camera.GetViewUp() #print('p1 =', p1) #print('p2 =', p2) z = view_up x = p2 - p1 origin = p1 #i = x / np.linalg.norm(x) #k = z / np.linalg.norm(z) # j axis (y direction) is normal to the plane #j = np.cross(k, i) #print("i = ", i) #print("j = ", j) #print("k = ", k) cid = 1 zaxis = origin + z xzplane = origin + x coord = CORD2R(cid, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane, comment='') local_points_array, global_points_array, result_array = _cut_edge_model_by_coord( nids, xyz_cp, edges, coord, tol, nodal_result, plane_atol=plane_atol, plane_bdf_filename=plane_bdf_filename) return local_points_array, global_points_array, result_array
def _cut_model(nids, xyz_cp, edges, view_up, p1, p2, tol, nodal_result, plane_atol=1e-5): """ Helper method for cut_edge_model_by_axes Parameters ---------- edges : (nedges, 2) int ndarray the edges view_up : (3,) float ndarray the up/z vector p1 / p2 : (3,) float ndarray the start/end points tol : float the plane tolerance """ #view_up = camera.GetViewUp() #print('p1 =', p1) #print('p2 =', p2) z = view_up x = p2 - p1 origin = p1 #i = x / np.linalg.norm(x) #k = z / np.linalg.norm(z) # j axis (y direction) is normal to the plane #j = np.cross(k, i) #print("i = ", i) #print("j = ", j) #print("k = ", k) cid = 1 zaxis = origin + z xzplane = origin + x coord = CORD2R(cid, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane, comment='') local_points_array, global_points_array, result_array = _cut_edge_model_by_coord( nids, xyz_cp, edges, coord, tol, nodal_result, plane_atol=plane_atol) return local_points_array, global_points_array, result_array
def _read_cord2r(self, data, n): """ (2101,21,8) - the marker for Record 5 """ nentries = (len(data) - n) // 52 for i in range(nentries): edata = data[n:n + 52] # 13*4 (cid, one, two, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3) = unpack(b(self._endian + '4i9f'), edata) assert one == 1, one assert two == 2, two data_in = [cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3] #print("cid=%s rid=%s a1=%s a2=%s a3=%s b1=%s b2=%s b3=%s c1=%s c2=%s c3=%s" %(cid,rid,a1,a2,a3,b1,b2,b3,c1,c2,c3)) if self.is_debug_file: self.binary_debug.write(' CORD2R=%s\n' % data_in) coord = CORD2R.add_op2_data(data_in) self.add_coord(coord, allow_overwrites=True) n += 52 self._increase_card_count('CORD2R', nentries) return n
def _read_cord2r(self, data, n): """ (2101,21,8) - the marker for Record 5 """ nentries = (len(data) - n) // 52 for i in range(nentries): edata = data[n:n + 52] # 13*4 (cid, one, two, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3) = unpack(b(self._endian + '4i9f'), edata) assert one == 1, one assert two == 2, two data_in = [cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3] #print("cid=%s rid=%s a1=%s a2=%s a3=%s b1=%s b2=%s b3=%s c1=%s c2=%s c3=%s" % #(cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3)) if self.is_debug_file: self.binary_debug.write(' CORD2R=%s\n' % data_in) coord = CORD2R.add_op2_data(data_in) self._add_coord_object(coord, allow_overwrites=True) n += 52 self._increase_card_count('CORD2R', nentries) return n
def test_cord2c_01(self): """simple CORD2R/CORD2C input/output test""" lines = [ 'CORD2C* 3 0 0. 0.', '* 0. 0. 0. 1.*', '* 1. 0. 1.' ] model = BDF(debug=False) card = model._process_card(lines) cardi = BDFCard(card) cord2c = CORD2C.add_card(cardi) model._add_coord_object(cord2c) lines = [ 'CORD2R 4 3 10. 0. 5. 10. 90. 5.', ' 10. 0. 6.' ] card = model._process_card(lines) cardi = BDFCard(card) cord2r = CORD2R.add_card(cardi) model._add_coord_object(cord2r) model.cross_reference() cord2r_b = model.Coord(3) self.assertEqual(cord2r_b.Cid(), 3) self.assertEqual(cord2r_b.Rid(), 0) cord2r_c = model.Coord(4) self.assertEqual(cord2r_c.Cid(), 4) self.assertEqual(cord2r_c.Rid(), 3) self.assertTrue(allclose(cord2r_c.i, array([0., 0., 1.]))) delta = cord2r_c.j - array([1., 1., 0.]) / 2**0.5 self.assertTrue(allclose(cord2r_c.j, array([1., 1., 0.]) / 2**0.5), str(delta)) delta = cord2r_c.k - array([-1., 1., 0.]) / 2**0.5 self.assertTrue(allclose(cord2r_c.k, array([-1., 1., 0.]) / 2**0.5), str(delta))
def _read_cord2r(self, data, n): """ (2101,21,8) - the marker for Record 5 """ ntotal = 52 * self.factor # 13*4 s = Struct(mapfmt(self._endian + b'4i9f', self.size)) nentries = (len(data) - n) // ntotal for unused_i in range(nentries): edata = data[n:n + ntotal] (cid, one, two, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3) = s.unpack(edata) assert one == 1, one assert two == 2, two data_in = [cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3] #print("cid=%s rid=%s a1=%s a2=%s a3=%s b1=%s b2=%s b3=%s c1=%s c2=%s c3=%s" % #(cid, rid, a1, a2, a3, b1, b2, b3, c1, c2, c3)) if self.is_debug_file: self.binary_debug.write(' CORD2R=%s\n' % data_in) coord = CORD2R.add_op2_data(data_in) self._add_coord_object(coord, allow_overwrites=False) n += ntotal self.increase_card_count('CORD2R', nentries) return n
def __init_attributes(self): # type: () -> None """ Creates storage objects for the BDF object. This would be in the init but doing it this way allows for better inheritance References: 1. http://www.mscsoftware.com/support/library/conf/wuc87/p02387.pdf """ self.bdf_filename = None self.punch = None self._encoding = None #: ignore any ECHOON flags self.force_echo_off = True #: list of Nastran SYSTEM commands self.system_command_lines = [] # type: List[str] #: list of execive control deck lines self.executive_control_lines = [] # type: List[str] #: list of case control deck lines self.case_control_lines = [] # type: List[str] self._auto_reject = False self._solmap_to_value = { 'NONLIN': 101, # 66 -> 101 per Reference 1 'SESTATIC': 101, 'SESTATICS': 101, 'SEMODES': 103, 'BUCKLING': 105, 'SEBUCKL': 105, 'NLSTATIC': 106, 'SEDCEIG': 107, 'SEDFREQ': 108, 'SEDTRAN': 109, 'SEMCEIG': 110, 'SEMFREQ': 111, 'SEMTRAN': 112, 'CYCSTATX': 114, 'CYCMODE': 115, 'CYCBUCKL': 116, 'CYCFREQ': 118, 'NLTRAN': 129, 'AESTAT': 144, 'FLUTTR': 145, 'SEAERO': 146, 'NLSCSH': 153, 'NLTCSH': 159, 'DBTRANS': 190, 'DESOPT': 200, # guessing #'CTRAN' : 115, 'CFREQ' : 118, # solution 200 names 'STATICS': 101, 'MODES': 103, 'BUCK': 105, 'DFREQ': 108, 'MFREQ': 111, 'MTRAN': 112, 'DCEIG': 107, 'MCEIG': 110, #'HEAT' : None, #'STRUCTURE': None, #'DIVERGE' : None, 'FLUTTER': 145, 'SAERO': 146, } self.rsolmap_to_str = { 66: 'NONLIN', 101: 'SESTSTATIC', # linear static 103: 'SEMODES', # modal 105: 'BUCKLING', # buckling 106: 'NLSTATIC', # non-linear static 107: 'SEDCEIG', # direct complex frequency response 108: 'SEDFREQ', # direct frequency response 109: 'SEDTRAN', # direct transient response 110: 'SEMCEIG', # modal complex eigenvalue 111: 'SEMFREQ', # modal frequency response 112: 'SEMTRAN', # modal transient response 114: 'CYCSTATX', 115: 'CYCMODE', 116: 'CYCBUCKL', 118: 'CYCFREQ', 129: 'NLTRAN', # nonlinear transient 144: 'AESTAT', # static aeroelastic 145: 'FLUTTR', # flutter/aeroservoelastic 146: 'SEAERO', # dynamic aeroelastic 153: 'NLSCSH', # nonlinear static thermal 159: 'NLTCSH', # nonlinear transient thermal 190: 'DBTRANS', 200: 'DESOPT', # optimization } # ------------------------ bad duplicates ---------------------------- self._iparse_errors = 0 self._nparse_errors = 0 self._stop_on_parsing_error = True self._stop_on_duplicate_error = True self._stored_parse_errors = [] # type: List[str] self._duplicate_nodes = [] # type: List[str] self._duplicate_elements = [] # type: List[str] self._duplicate_properties = [] # type: List[str] self._duplicate_materials = [] # type: List[str] self._duplicate_masses = [] # type: List[str] self._duplicate_thermal_materials = [] # type: List[str] self._duplicate_coords = [] # type: List[str] self.values_to_skip = {} # type: Dict[str, List[int]] # ------------------------ structural defaults ----------------------- #: the analysis type self._sol = None #: used in solution 600, method self.sol_method = None #: the line with SOL on it, marks ??? self.sol_iline = None # type : Optional[int] self.case_control_deck = None # type: Optional[Any] #: store the PARAM cards self.params = {} # type: Dict[str, Any] # ------------------------------- nodes ------------------------------- # main structural block #: stores POINT cards self.points = {} # type: Dict[int, Any] self.ringaxs = {} # type: Dict[int, Any] #self.grids = {} self.spoints = {} # type: Dict[int, Any] self.epoints = {} # type: Dict[int, Any] #: stores GRIDSET card self.grdset = None # type: Optional[Any] #: stores SEQGP cards self.seqgp = None # type: Optional[Any] #: stores elements (CQUAD4, CTRIA3, CHEXA8, CTETRA4, CROD, CONROD, #: etc.) self.elements = {} # type: Dict[int, Any] #: stores CBARAO, CBEAMAO self.ao_element_flags = {} # type: Dict[int, Any] #: stores rigid elements (RBE2, RBE3, RJOINT, etc.) self.rigid_elements = {} # type: Dict[int, Any] #: stores PLOTELs self.plotels = {} # type: Optional[Any] #: stores CONM1, CONM2, CMASS1,CMASS2, CMASS3, CMASS4, CMASS5 self.masses = {} # type: Dict[int, Any] #: stores PMASS self.properties_mass = {} # type: Dict[int, Any] #: stores NSM, NSM1 self.nsms = {} # type: Dict[int, List[Any]] #: stores LOTS of propeties (PBAR, PBEAM, PSHELL, PCOMP, etc.) self.properties = {} # type: Dict[int, Any] #: stores MAT1, MAT2, MAT3, MAT8, MAT10, MAT11 self.materials = {} # type: Dict[int, Any] #: defines the MAT4, MAT5 self.thermal_materials = {} # type: Dict[int, Any] #: defines the MATHE, MATHP self.hyperelastic_materials = {} # type: Dict[int, Any] #: stores MATSx self.MATS1 = {} # type: Dict[int, Any] self.MATS3 = {} # type: Dict[int, Any] self.MATS8 = {} # type: Dict[int, Any] #: stores MATTx self.MATT1 = {} # type: Dict[int, Any] self.MATT2 = {} # type: Dict[int, Any] self.MATT3 = {} # type: Dict[int, Any] self.MATT4 = {} # type: Dict[int, Any] self.MATT5 = {} # type: Dict[int, Any] self.MATT8 = {} # type: Dict[int, Any] self.MATT9 = {} # type: Dict[int, Any] #: stores the CREEP card self.creep_materials = {} # type: Dict[int, Any] self.tics = {} # type: Optional[Any] # stores DLOAD entries. self.dloads = {} # type: Dict[int, Any] # stores ACSRCE, RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE, # and QVECT entries. self.dload_entries = {} # type: Dict[int, Any] #self.gusts = {} # Case Control GUST = 100 #self.random = {} # Case Control RANDOM = 100 #: stores coordinate systems origin = array([0., 0., 0.]) zaxis = array([0., 0., 1.]) xzplane = array([1., 0., 0.]) coord = CORD2R(cid=0, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane) self.coords = {0 : coord} # type: Dict[int, Any] # --------------------------- constraints ---------------------------- #: stores SUPORT1s #self.constraints = {} # suport1, anything else??? self.suport = [] # type: List[Any] self.suport1 = {} # type: Dict[int, Any] self.se_suport = [] # type: List[Any] #: stores SPCADD, SPC, SPC1, SPCAX, GMSPC self.spcs = {} # type: Dict[int, List[Any]] self.spcadds = {} # type: Dict[int, List[Any]] self.spcoffs = {} # type: Dict[int, List[Any]] self.mpcs = {} # type: Dict[int, List[Any]] self.mpcadds = {} # type: Dict[int, List[Any]] # --------------------------- dynamic ---------------------------- #: stores DAREA self.dareas = {} # type: Dict[int, Any] self.dphases = {} # type: Dict[int, Any] self.pbusht = {} # type: Dict[int, Any] self.pdampt = {} # type: Dict[int, Any] self.pelast = {} # type: Dict[int, Any] #: frequencies self.frequencies = {} # type: Dict[int, List[Any]] # ---------------------------------------------------------------- #: direct matrix input - DMIG self.dmis = {} # type: Dict[str, Any] self.dmigs = {} # type: Dict[str, Any] self.dmijs = {} # type: Dict[str, Any] self.dmijis = {} # type: Dict[str, Any] self.dmiks = {} # type: Dict[str, Any] self.dti = {} # type: Dict[str, Any] self._dmig_temp = defaultdict(list) # type: Dict[str, List[str]] # ---------------------------------------------------------------- #: SETy self.sets = {} # type: Dict[int, Any] self.asets = [] # type: List[Any] self.bsets = [] # type: List[Any] self.csets = [] # type: List[Any] self.qsets = [] # type: List[Any] self.usets = {} # type: Dict[str, Any] #: SExSETy self.se_bsets = [] # type: List[Any] self.se_csets = [] # type: List[Any] self.se_qsets = [] # type: List[Any] self.se_usets = {} # type: Dict[str, Any] self.se_sets = {} # type: Dict[str, Any] # ---------------------------------------------------------------- #: tables # TABLES1, ... self.tables = {} # type: Dict[int, Any] # TABLEDx self.tables_d = {} # type: Dict[int, Any] # TABLEMx self.tables_m = {} # type: Dict[int, Any] #: random_tables self.random_tables = {} # type: Dict[int, Any] #: TABDMP1 self.tables_sdamping = {} # type: Dict[int, Any] # ---------------------------------------------------------------- #: EIGB, EIGR, EIGRL methods self.methods = {} # type: Dict[int, Any] # EIGC, EIGP methods self.cMethods = {} # type: Dict[int, Any] # ---------------------------- optimization -------------------------- # optimization self.dconadds = {} # type: Dict[int, Any] self.dconstrs = {} # type: Dict[int, Any] self.desvars = {} # type: Dict[int, Any] self.ddvals = {} # type: Dict[int, Any] self.dlinks = {} # type: Dict[int, Any] self.dresps = {} # type: Dict[int, Any] self.dtable = None # type: Optional[Any] self.dequations = {} # type: Dict[int, Any] #: stores DVPREL1, DVPREL2...might change to DVxRel self.dvprels = {} # type: Dict[int, Any] self.dvmrels = {} # type: Dict[int, Any] self.dvcrels = {} # type: Dict[int, Any] self.dvgrids = {} # type: Dict[int, Any] self.doptprm = None # type: Optional[Any] self.dscreen = {} # type: Dict[int, Any] # ------------------------- nonlinear defaults ----------------------- #: stores NLPCI self.nlpcis = {} # type: Dict[int, Any] #: stores NLPARM self.nlparms = {} # type: Dict[int, Any] #: stores TSTEPs, TSTEP1s self.tsteps = {} # type: Dict[int, Any] #: stores TSTEPNL self.tstepnls = {} # type: Dict[int, Any] #: stores TF self.transfer_functions = {} # type: Dict[int, Any] #: stores DELAY self.delays = {} # type: Dict[int, Any] #: stores ROTORG self.rotors = {} # type: Dict[int, Any] # --------------------------- aero defaults -------------------------- # aero cards #: stores CAEROx self.caeros = {} # type: Dict[int, Any] #: stores PAEROx self.paeros = {} # type: Dict[int, Any] # stores MONPNT1 self.monitor_points = [] # type: List[Any] #: stores AECOMP self.aecomps = {} # type: Dict[int, Any] #: stores AEFACT self.aefacts = {} # type: Dict[int, Any] #: stores AELINK self.aelinks = {} # type: Dict[int, List[Any]] #: stores AELIST self.aelists = {} # type: Dict[int, Any] #: stores AEPARAM self.aeparams = {} # type: Dict[int, Any] #: stores AESURF self.aesurf = {} # type: Dict[int, Any] #: stores AESURFS self.aesurfs = {} # type: Dict[int, Any] #: stores AESTAT self.aestats = {} # type: Dict[int, Any] #: stores CSSCHD self.csschds = {} # type: Dict[int, Any] #: store SPLINE1,SPLINE2,SPLINE4,SPLINE5 self.splines = {} # type: Dict[int, Any] # axisymmetric self.axic = None # type: Optional[Any] # ------ SOL 144 ------ #: stores AEROS self.aeros = None # type: Optional[Any] #: stores TRIM self.trims = {} # type: Dict[int, Any] #: stores DIVERG self.divergs = {} # type: Dict[int, Any] # ------ SOL 145 ------ #: stores AERO self.aero = None # type: Optional[Any] #: stores FLFACT #: .. todo:: can this be simplified ??? self.flfacts = {} # type: Dict[int, Any] #: stores FLUTTER self.flutters = {} # type: Dict[int, Any] #: mkaeros self.mkaeros = [] # type: List[Any] # ------ SOL 146 ------ #: stores GUST cards self.gusts = {} # type: Dict[int, Any] # ------------------------- thermal defaults ------------------------- # BCs #: stores thermal boundary conditions - CONV,RADBC self.bcs = {} # type: Dict[int, Any] #: stores PHBDY self.phbdys = {} # type: Dict[int, Any] #: stores convection properties - PCONV, PCONVM ??? self.convection_properties = {} # type: Dict[int, Any] #: stores TEMPD self.tempds = {} # type: Dict[int, Any] # -------------------------contact cards------------------------------- self.bcrparas = {} # type: Dict[int, Any] self.bctadds = {} # type: Dict[int, Any] self.bctparas = {} # type: Dict[int, Any] self.bctsets = {} # type: Dict[int, Any] self.bsurf = {} # type: Dict[int, Any] self.bsurfs = {} # type: Dict[int, Any] # --------------------------------------------------------------------- self._type_to_id_map = defaultdict(list) # type: Dict[int, List[Any]] self._slot_to_type_map = { 'params' : ['PARAM'], 'nodes' : ['GRID', 'SPOINT', 'EPOINT'], # 'RINGAX', 'points' : ['POINT'], 'ringaxs' : ['RINGAX', 'POINTAX'], 'axic' : ['AXIC'], 'grdset' : ['GRDSET'], 'seqgp' : ['SEQGP'], 'ao_element_flags' : ['CBARAO'], #'POINTAX', 'RINGAX', # CMASS4 lies in the QRG 'masses' : ['CONM1', 'CONM2', 'CMASS1', 'CMASS2', 'CMASS3', 'CMASS4'], 'elements' : [ 'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4', # 'CELAS5', 'CBUSH', 'CBUSH1D', 'CBUSH2D', 'CDAMP1', 'CDAMP2', 'CDAMP3', 'CDAMP4', 'CDAMP5', 'CFAST', 'CBAR', 'CROD', 'CTUBE', 'CBEAM', 'CBEAM3', 'CONROD', 'CBEND', 'CTRIA3', 'CTRIA6', 'CTRIAR', 'CQUAD4', 'CQUAD8', 'CQUADR', 'CQUAD', 'CPLSTN3', 'CPLSTN6', 'CPLSTN4', 'CPLSTN8', 'CPLSTS3', 'CPLSTS6', 'CPLSTS4', 'CPLSTS8', 'CTRAX3', 'CTRAX6', 'CTRIAX', 'CTRIAX6', 'CQUADX', 'CQUADX4', 'CQUADX8', 'CTETRA', 'CPYRAM', 'CPENTA', 'CHEXA', 'CIHEX1', 'CIHEX2', 'CSHEAR', 'CVISC', 'CRAC2D', 'CRAC3D', 'CGAP', # thermal 'CHBDYE', 'CHBDYG', 'CHBDYP', ], 'nsms' : ['NSM', 'NSM1', 'NSML', 'NSML1', 'NSMADD'], 'rigid_elements' : ['RBAR', 'RBAR1', 'RBE1', 'RBE2', 'RBE3', 'RROD', 'RSPLINE'], 'plotels' : ['PLOTEL',], 'properties_mass' : ['PMASS'], 'properties' : [ 'PELAS', 'PGAP', 'PFAST', 'PLPLANE', 'PPLANE', 'PBUSH', 'PBUSH1D', 'PDAMP', 'PDAMP5', 'PROD', 'PBAR', 'PBARL', 'PBEAM', 'PTUBE', 'PBEND', 'PBCOMP', 'PBRSECT', 'PBMSECT', 'PBEAML', # not fully supported # 'PBEAM3', 'PSHELL', 'PCOMP', 'PCOMPG', 'PSHEAR', 'PSOLID', 'PLSOLID', 'PVISC', 'PRAC2D', 'PRAC3D', 'PIHEX', 'PCOMPS', 'PCONEAX', ], 'pdampt' : ['PDAMPT',], 'pelast' : ['PELAST',], 'pbusht' : ['PBUSHT',], # materials 'materials' : ['MAT1', 'MAT2', 'MAT3', 'MAT8', 'MAT9', 'MAT10', 'MAT11', 'MAT3D', 'MATG'], 'hyperelastic_materials' : ['MATHE', 'MATHP',], 'creep_materials' : ['CREEP'], 'MATT1' : ['MATT1'], 'MATT2' : ['MATT2'], 'MATT3' : ['MATT3'], 'MATT4' : ['MATT4'], # thermal 'MATT5' : ['MATT5'], # thermal 'MATT8' : ['MATT8'], 'MATT9' : ['MATT9'], 'MATS1' : ['MATS1'], 'MATS3' : ['MATS3'], 'MATS8' : ['MATS8'], # 'MATHE' #'EQUIV', # testing only, should never be activated... # thermal materials 'thermal_materials' : ['MAT4', 'MAT5',], # spc/mpc constraints - TODO: is this correct? 'spcadds' : ['SPCADD'], 'spcs' : ['SPC', 'SPC1', 'SPCAX', 'GMSPC'], 'spcoffs' : ['SPCOFF', 'SPCOFF1'], 'mpcadds' : ['MPCADD'], 'mpcs' : ['MPC'], 'suport' : ['SUPORT'], 'suport1' : ['SUPORT1'], 'se_suport' : ['SESUP'], # loads 'load_combinations' : ['LOAD', 'LSEQ'], 'loads' : [ 'FORCE', 'FORCE1', 'FORCE2', 'MOMENT', 'MOMENT1', 'MOMENT2', 'GRAV', 'ACCEL', 'ACCEL1', 'PLOAD', 'PLOAD1', 'PLOAD2', 'PLOAD4', 'PLOADX1', 'RFORCE', 'RFORCE1', 'SLOAD', 'GMLOAD', 'SPCD', 'LOADCYN', # thermal 'TEMP', 'QBDY1', 'QBDY2', 'QBDY3', 'QHBDY', 'QVOL', ], 'dloads' : ['DLOAD', ], # stores RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE entries. 'dload_entries' : ['ACSRCE', 'TLOAD1', 'TLOAD2', 'RLOAD1', 'RLOAD2', 'QVECT', 'RANDPS'], # aero cards 'aero' : ['AERO'], 'aeros' : ['AEROS'], 'gusts' : ['GUST'], 'flutters' : ['FLUTTER'], 'flfacts' : ['FLFACT'], 'mkaeros' : ['MKAERO1', 'MKAERO2'], 'aecomps' : ['AECOMP'], 'aefacts' : ['AEFACT'], 'aelinks' : ['AELINK'], 'aelists' : ['AELIST'], 'aeparams' : ['AEPARM'], 'aesurf' : ['AESURF'], 'aesurfs' : ['AESURFS'], 'aestats' : ['AESTAT'], 'caeros' : ['CAERO1', 'CAERO2', 'CAERO3', 'CAERO4', 'CAERO5'], 'paeros' : ['PAERO1', 'PAERO2', 'PAERO3', 'PAERO4', 'PAERO5'], 'monitor_points' : ['MONPNT1', 'MONPNT2', 'MONPNT3'], 'splines' : ['SPLINE1', 'SPLINE2', 'SPLINE4', 'SPLINE5',], 'csschds' : ['CSSCHD',], #'SPLINE3', 'SPLINE6', 'SPLINE7', 'trims' : ['TRIM',], 'divergs' : ['DIVERG'], # coords 'coords' : ['CORD1R', 'CORD1C', 'CORD1S', 'CORD2R', 'CORD2C', 'CORD2S', 'GMCORD'], # temperature cards 'tempds' : ['TEMPD'], 'phbdys' : ['PHBDY'], 'convection_properties' : ['PCONV', 'PCONVM'], # stores thermal boundary conditions 'bcs' : ['CONV', 'RADBC', 'RADM'], # dynamic cards 'dareas' : ['DAREA'], 'tics' : ['TIC'], 'dphases' : ['DPHASE'], 'nlparms' : ['NLPARM'], 'nlpcis' : ['NLPCI'], 'tsteps' : ['TSTEP'], 'tstepnls' : ['TSTEPNL', 'TSTEP1'], 'transfer_functions' : ['TF'], 'delays' : ['DELAY'], 'rotors' : ['ROTORG', 'ROTORD'], 'frequencies' : ['FREQ', 'FREQ1', 'FREQ2', 'FREQ3', 'FREQ4', 'FREQ5'], # direct matrix input cards 'dmigs' : ['DMIG'], 'dmijs' : ['DMIJ'], 'dmijis' : ['DMIJI'], 'dmiks' : ['DMIK'], 'dmis' : ['DMI'], 'dti' : ['DTI'], # optimzation 'dequations' : ['DEQATN'], 'dtable' : ['DTABLE'], 'dconstrs' : ['DCONSTR', 'DCONADD'], 'desvars' : ['DESVAR'], 'ddvals' : ['DDVAL'], 'dlinks' : ['DLINK'], 'dresps' : ['DRESP1', 'DRESP2', 'DRESP3',], 'dvprels' : ['DVPREL1', 'DVPREL2'], 'dvmrels' : ['DVMREL1', 'DVMREL2'], 'dvcrels' : ['DVCREL1', 'DVCREL2'], 'dvgrids' : ['DVGRID'], 'doptprm' : ['DOPTPRM'], 'dscreen' : ['DSCREEN'], # sets 'asets' : ['ASET', 'ASET1'], 'bsets' : ['BSET', 'BSET1',], 'qsets' : ['QSET', 'QSET1'], 'csets' : ['CSET', 'CSET1',], 'usets' : ['USET', 'USET1',], 'sets' : ['SET1', 'SET3',], # super-element sets 'se_bsets' : ['SEBSET', 'SEBSET1'], 'se_csets' : ['SECSET', 'SECSET1',], 'se_qsets' : ['SEQSET', 'SEQSET1'], 'se_usets' : ['SEUSET', 'SEQSET1'], 'se_sets' : ['SESET'], # SEBSEP 'tables' : [ 'TABLEHT', 'TABRNDG', 'TABLES1', 'TABLEST', ], 'tables_d' : ['TABLED1', 'TABLED2', 'TABLED3', 'TABLED4', 'TABLED5'], 'tables_m' : ['TABLEM1', 'TABLEM2', 'TABLEM3', 'TABLEM4'], 'tables_sdamping' : ['TABDMP1'], 'random_tables' : ['TABRND1', 'TABRNDG',], # initial conditions - sid (set ID) ##'TIC', (in bdf_tables.py) # methods 'methods' : ['EIGB', 'EIGR', 'EIGRL',], # cMethods 'cMethods' : ['EIGC', 'EIGP',], # contact 'bctparas' : ['BCTPARA'], 'bcrparas' : ['BCRPARA'], 'bctadds' : ['BCTADD'], 'bctsets' : ['BCTSET'], 'bsurf' : ['BSURF'], 'bsurfs' : ['BSURFS'], ## other #'INCLUDE', # '=' #'ENDDATA', } # type: Dict[str, List[str]] self._type_to_slot_map = self.get_rslot_map()
def add_cord2r(self, card, comment=''): """adds a CORD2R card""" coord = CORD2R.add_card(card, comment=comment) self.coords[coord.cid] = coord self.n += 1
def __init_attributes(self) -> None: """ Creates storage objects for the BDF object. This would be in the init but doing it this way allows for better inheritance References: 1. http://www.mscsoftware.com/support/library/conf/wuc87/p02387.pdf """ self.reset_errors() self.bdf_filename = None self.punch = None self._encoding = None self._is_long_ids = False # ids > 8 characters #: ignore any ECHOON flags self.force_echo_off = True #: list of Nastran SYSTEM commands self.system_command_lines = [] # type: List[str] #: list of execive control deck lines self.executive_control_lines = [] # type: List[str] #: list of case control deck lines self.case_control_lines = [] # type: List[str] # dictionary of BDFs self.superelement_models = {} self.initial_superelement_models = [] # the keys before superelement mirroring self._auto_reject = False self._solmap_to_value = { 'NONLIN': 101, # 66 -> 101 per Reference 1 'SESTATIC': 101, 'SESTATICS': 101, 'SEMODES': 103, 'BUCKLING': 105, 'SEBUCKL': 105, 'NLSTATIC': 106, 'SEDCEIG': 107, 'SEDFREQ': 108, 'SEDTRAN': 109, 'SEMCEIG': 110, 'SEMFREQ': 111, 'SEMTRAN': 112, 'CYCSTATX': 114, 'CYCMODE': 115, 'CYCBUCKL': 116, 'CYCFREQ': 118, 'NLTRAN': 129, 'AESTAT': 144, 'FLUTTR': 145, 'SEAERO': 146, 'NLSCSH': 153, 'NLTCSH': 159, 'DBTRANS': 190, 'DESOPT': 200, # guessing #'CTRAN' : 115, 'CFREQ' : 118, # solution 200 names 'STATICS': 101, 'MODES': 103, 'BUCK': 105, 'DFREQ': 108, 'MFREQ': 111, 'MTRAN': 112, 'DCEIG': 107, 'MCEIG': 110, #'HEAT' : None, #'STRUCTURE': None, #'DIVERGE' : None, 'FLUTTER': 145, 'SAERO': 146, } self.rsolmap_to_str = { 66: 'NONLIN', 101: 'SESTSTATIC', # linear static 103: 'SEMODES', # modal 105: 'BUCKLING', # buckling 106: 'NLSTATIC', # non-linear static 107: 'SEDCEIG', # direct complex frequency response 108: 'SEDFREQ', # direct frequency response 109: 'SEDTRAN', # direct transient response 110: 'SEMCEIG', # modal complex eigenvalue 111: 'SEMFREQ', # modal frequency response 112: 'SEMTRAN', # modal transient response 114: 'CYCSTATX', 115: 'CYCMODE', 116: 'CYCBUCKL', 118: 'CYCFREQ', 129: 'NLTRAN', # nonlinear transient 144: 'AESTAT', # static aeroelastic 145: 'FLUTTR', # flutter/aeroservoelastic 146: 'SEAERO', # dynamic aeroelastic 153: 'NLSCSH', # nonlinear static thermal 159: 'NLTCSH', # nonlinear transient thermal #187 - Dynamic Design Analysis Method 190: 'DBTRANS', 200: 'DESOPT', # optimization } # ------------------------ bad duplicates ---------------------------- self._iparse_errors = 0 self._nparse_errors = 0 self._stop_on_parsing_error = True self._stop_on_duplicate_error = True self._stored_parse_errors = [] # type: List[str] self._duplicate_nodes = [] # type: List[str] self._duplicate_elements = [] # type: List[str] self._duplicate_properties = [] # type: List[str] self._duplicate_materials = [] # type: List[str] self._duplicate_masses = [] # type: List[str] self._duplicate_thermal_materials = [] # type: List[str] self._duplicate_coords = [] # type: List[str] self.values_to_skip = {} # type: Dict[str, List[int]] # ------------------------ structural defaults ----------------------- #: the analysis type self._sol = None #: used in solution 600, method self.sol_method = None #: the line with SOL on it, marks ??? self.sol_iline = None # type : Optional[int] self.case_control_deck = None # type: Optional[Any] #: store the PARAM cards self.params = {} # type: Dict[str, Any] # ------------------------------- nodes ------------------------------- # main structural block #: stores POINT cards self.points = {} # type: Dict[int, Any] #self.grids = {} self.spoints = {} # type: Dict[int, Any] self.epoints = {} # type: Dict[int, Any] #: stores GRIDSET card self.grdset = None # type: Optional[Any] #: stores SEQGP cards self.seqgp = None # type: Optional[Any] ## stores RINGAX self.ringaxs = {} # type: Dict[int, Any] ## stores GRIDB self.gridb = {} # type: Dict[int, Any] #: stores elements (CQUAD4, CTRIA3, CHEXA8, CTETRA4, CROD, CONROD, #: etc.) self.elements = {} # type: Dict[int, Any] #: stores CBARAO, CBEAMAO self.ao_element_flags = {} # type: Dict[int, Any] #: stores BAROR self.baror = None # type: Optional[Any] #: stores BEAMOR self.beamor = None # type: Optional[Any] #: stores SNORM self.normals = {} # type: Dict[int, Any] #: stores rigid elements (RBE2, RBE3, RJOINT, etc.) self.rigid_elements = {} # type: Dict[int, Any] #: stores PLOTELs self.plotels = {} # type: Optional[Any] #: stores CONM1, CONM2, CMASS1,CMASS2, CMASS3, CMASS4, CMASS5 self.masses = {} # type: Dict[int, Any] #: stores PMASS self.properties_mass = {} # type: Dict[int, Any] #: stores NSM, NSM1, NSML, NSML1 self.nsms = {} # type: Dict[int, List[Any]] #: stores NSMADD self.nsmadds = {} # type: Dict[int, List[Any]] #: stores LOTS of propeties (PBAR, PBEAM, PSHELL, PCOMP, etc.) self.properties = {} # type: Dict[int, Any] #: stores MAT1, MAT2, MAT3, MAT8, MAT10, MAT11 self.materials = {} # type: Dict[int, Any] #: defines the MAT4, MAT5 self.thermal_materials = {} # type: Dict[int, Any] #: defines the MATHE, MATHP self.hyperelastic_materials = {} # type: Dict[int, Any] #: stores MATSx self.MATS1 = {} # type: Dict[int, Any] self.MATS3 = {} # type: Dict[int, Any] self.MATS8 = {} # type: Dict[int, Any] #: stores MATTx self.MATT1 = {} # type: Dict[int, Any] self.MATT2 = {} # type: Dict[int, Any] self.MATT3 = {} # type: Dict[int, Any] self.MATT4 = {} # type: Dict[int, Any] self.MATT5 = {} # type: Dict[int, Any] self.MATT8 = {} # type: Dict[int, Any] self.MATT9 = {} # type: Dict[int, Any] self.nxstrats = {} # type: Dict[int, Any] #: stores the CREEP card self.creep_materials = {} # type: Dict[int, Any] self.tics = {} # type: Optional[Any] # stores DLOAD entries. self.dloads = {} # type: Dict[int, Any] # stores ACSRCE, RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE, # and QVECT entries. self.dload_entries = {} # type: Dict[int, Any] #self.gusts = {} # Case Control GUST = 100 #self.random = {} # Case Control RANDOM = 100 #: stores coordinate systems origin = array([0., 0., 0.]) zaxis = array([0., 0., 1.]) xzplane = array([1., 0., 0.]) coord = CORD2R(cid=0, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane) self.coords = {0 : coord} # type: Dict[int, Any] # --------------------------- constraints ---------------------------- #: stores SUPORT1s #self.constraints = {} # suport1, anything else??? self.suport = [] # type: List[Any] self.suport1 = {} # type: Dict[int, Any] self.se_suport = [] # type: List[Any] #: stores SPC, SPC1, SPCAX, GMSPC self.spcs = {} # type: Dict[int, List[Any]] #: stores SPCADD self.spcadds = {} # type: Dict[int, List[Any]] self.spcoffs = {} # type: Dict[int, List[Any]] self.mpcs = {} # type: Dict[int, List[Any]] self.mpcadds = {} # type: Dict[int, List[Any]] # --------------------------- dynamic ---------------------------- #: stores DAREA self.dareas = {} # type: Dict[int, Any] self.dphases = {} # type: Dict[int, Any] self.pbusht = {} # type: Dict[int, Any] self.pdampt = {} # type: Dict[int, Any] self.pelast = {} # type: Dict[int, Any] #: frequencies self.frequencies = {} # type: Dict[int, List[Any]] # ---------------------------------------------------------------- #: direct matrix input - DMIG self.dmi = {} # type: Dict[str, Any] self.dmig = {} # type: Dict[str, Any] self.dmij = {} # type: Dict[str, Any] self.dmiji = {} # type: Dict[str, Any] self.dmik = {} # type: Dict[str, Any] self.dmiax = {} # type: Dict[str, Any] self.dti = {} # type: Dict[str, Any] self._dmig_temp = defaultdict(list) # type: Dict[str, List[str]] # ---------------------------------------------------------------- #: SETy self.sets = {} # type: Dict[int, Any] self.asets = [] # type: List[Any] self.omits = [] # type: List[Any] self.bsets = [] # type: List[Any] self.csets = [] # type: List[Any] self.qsets = [] # type: List[Any] self.usets = {} # type: Dict[str, Any] #: SExSETy self.se_bsets = [] # type: List[Any] self.se_csets = [] # type: List[Any] self.se_qsets = [] # type: List[Any] self.se_usets = {} # type: Dict[str, Any] self.se_sets = {} # type: Dict[str, Any] # ---------------------------------------------------------------- #: parametric self.pset = {} self.pval = {} self.gmcurv = {} self.gmsurf = {} self.feedge = {} self.feface = {} # ---------------------------------------------------------------- #: tables # TABLES1, ... self.tables = {} # type: Dict[int, TABLES1] # TABLEDx self.tables_d = {} # type: Dict[int, Union[TABLED1, TABLED2, TABLED3, TABLED4]] # TABLEMx self.tables_m = {} # type: Dict[int, Union[TABLEM1, TABLEM2, TABLEM3, TABLEM4]] #: random_tables self.random_tables = {} # type: Dict[int, Any] #: TABDMP1 self.tables_sdamping = {} # type: Dict[int, TABDMP1] # ---------------------------------------------------------------- #: EIGB, EIGR, EIGRL methods self.methods = {} # type: Dict[int, Union[EIGR, EIGRL, EIGB]] # EIGC, EIGP methods self.cMethods = {} # type: Dict[int, Union[EIGC, EIGP]] # ---------------------------- optimization -------------------------- # optimization self.dconadds = {} # type: Dict[int, DCONADD] self.dconstrs = {} # type: Dict[int, DCONSTR] self.desvars = {} # type: Dict[int, DESVAR] self.topvar = {} # type: Dict[int, TOPVAR] self.ddvals = {} # type: Dict[int, DDVAL] self.dlinks = {} # type: Dict[int, DLINK] self.dresps = {} # type: Dict[int, Union[DRESP1, DRESP2, DRESP3]] self.dtable = None # type: Optional[DTABLE] self.dequations = {} # type: Dict[int, DEQATN] #: stores DVPREL1, DVPREL2...might change to DVxRel self.dvprels = {} # type: Dict[int, Union[DVPREL1, DVPREL2]] self.dvmrels = {} # type: Dict[int, Union[DVMREL1, DVMREL2]] self.dvcrels = {} # type: Dict[int, Union[DVCREL1, DVCREL2]] self.dvgrids = {} # type: Dict[int, DVGRID] self.doptprm = None # type: Optional[DOPTPRM] self.dscreen = {} # type: Dict[int, DSCREEN] # ------------------------- nonlinear defaults ----------------------- #: stores NLPCI self.nlpcis = {} # type: Dict[int, NLPCI] #: stores NLPARM self.nlparms = {} # type: Dict[int, NLPARM] #: stores TSTEPs, TSTEP1s self.tsteps = {} # type: Dict[int, Union[TSTEP, TSTEP1]] #: stores TSTEPNL self.tstepnls = {} # type: Dict[int, TSTEPNL] #: stores TF self.transfer_functions = {} # type: Dict[int, TF] #: stores DELAY self.delays = {} # type: Dict[int, DELAY] #: stores ROTORD, ROTORG self.rotors = {} # type: Dict[int, Union[ROTORD, ROTORG]] # --------------------------- aero defaults -------------------------- # aero cards #: stores CAEROx self.caeros = {} # type: Dict[int, Union[CAERO1, CAERO2, CAERO3, CAERO4, CAERO5]] #: stores PAEROx self.paeros = {} # type: Dict[int, Union[PAERO1, PAERO2, PAERO3, PAERO4, PAERO5]] # stores MONPNT1 self.monitor_points = [] # type: List[Union[MONPNT1, MONPNT2, MONPNT3]] #: stores AECOMP self.aecomps = {} # type: Dict[int, AECOMP] #: stores AEFACT self.aefacts = {} # type: Dict[int, AEFACT] #: stores AELINK self.aelinks = {} # type: Dict[int, List[AELINK]] #: stores AELIST self.aelists = {} # type: Dict[int, AELIST] #: stores AEPARAM self.aeparams = {} # type: Dict[int, AEPARAM] #: stores AESURF self.aesurf = {} # type: Dict[int, AESURF] #: stores AESURFS self.aesurfs = {} # type: Dict[int, AESURFS] #: stores AESTAT self.aestats = {} # type: Dict[int, AESTAT] #: stores CSSCHD self.csschds = {} # type: Dict[int, CSSCHD] #: store SPLINE1,SPLINE2,SPLINE4,SPLINE5 self.splines = {} # type: Dict[int, Union[SPLINE1, SPLINE2, SPLINE3, SPLINE4, SPLINE5]] self.zona = ZONA(self) # axisymmetric self.axic = None # type: Optional[AXIC] self.axif = None # type: Optional[AXIF] self.ringfl = {} # type: Dict[int, RINGFL] self._is_axis_symmetric = False # cyclic self.cyax = None # type: Optional[CYAX] self.cyjoin = {} # type: Dict[int, CYJOIN] self.modtrak = None # type: Optional[MODTRAK] # acoustic self.acmodl = None # ------ SOL 144 ------ #: stores AEROS self.aeros = None # type: Optional[AEROS] #: stores TRIM, TRIM2 self.trims = {} # type: Dict[int, Union[TRIM, TRIM2]] #: stores DIVERG self.divergs = {} # type: Dict[int, DIVERG] # ------ SOL 145 ------ #: stores AERO self.aero = None # type: Optional[AERO] #: stores FLFACT self.flfacts = {} # type: Dict[int, FLFACT] #: stores FLUTTER self.flutters = {} # type: Dict[int, FLUTTER] #: mkaeros self.mkaeros = [] # type: List[Union[MKAERO1,MKAERO2]] # ------ SOL 146 ------ #: stores GUST cards self.gusts = {} # type: Dict[int, GUST] # ------------------------- thermal defaults ------------------------- # BCs #: stores thermal boundary conditions - CONV,RADBC self.bcs = {} # type: Dict[int, Union[CONV, RADBC]] #: stores PHBDY self.phbdys = {} # type: Dict[int, PHBDY] #: stores convection properties - PCONV, PCONVM ??? self.convection_properties = {} # type: Dict[int, Union[PCONV, PCONVM]] #: stores TEMPD self.tempds = {} # type: Dict[int, TEMPD] #: stores VIEW self.views = {} # type: Dict[int, VIEW] #: stores VIEW3D self.view3ds = {} # type: Dict[int, VIEW3D] self.radset = None self.radcavs = {} # type: Dict[int, RADCAV] self.radmtx = {} # type: Dict[int, RADMTX] # -------------------------contact cards------------------------------- self.bcrparas = {} # type: Dict[int, BCRPARA] self.bctadds = {} # type: Dict[int, BCTADD] self.bctparas = {} # type: Dict[int, BCTPARA] self.bctsets = {} # type: Dict[int, BCTSET] self.bsurf = {} # type: Dict[int, BSURF] self.bsurfs = {} # type: Dict[int, BSURFS] self.bconp = {} # type: Dict[int, BCONP] self.blseg = {} # type: Dict[int, BLSEG] self.bfric = {} # type: Dict[int, BFRIC] #--------------------------superelements------------------------------ self.setree = {} # type: Dict[int, SETREE] self.senqset = {} # type: Dict[int, Union[SENQSET, SENQSET1]] self.sebulk = {} # type: Dict[int, SEBULK] self.sebndry = {} # type: Dict[int, SEBNDRY] self.release = {} # type: Dict[int, RELEASE] self.seloc = {} # type: Dict[int, SELOC] self.sempln = {} # type: Dict[int, SEMPLN] self.seconct = {} # type: Dict[int, SECONCT] self.selabel = {} # type: Dict[int, SELABEL] self.seexcld = {} # type: Dict[int, SEEXCLD] self.seelt = {} # type: Dict[int, SEELT] self.seload = {} # type: Dict[int, SELOAD] self.csuper = {} # type: Dict[int, CSUPER] self.csupext = {} # type: Dict[int, CSUPEXT] # --------------------------------------------------------------------- self._type_to_id_map = defaultdict(list) # type: Dict[int, List[Any]] self._slot_to_type_map = { 'params' : ['PARAM'], 'nodes' : ['GRID', 'SPOINT', 'EPOINT'], # 'RINGAX', 'points' : ['POINT'], 'ringaxs' : ['RINGAX', 'POINTAX'], 'ringfl' : ['RINGFL'], 'axic' : ['AXIC'], 'axif' : ['AXIF'], 'acmodl' : ['ACMODL'], 'grdset' : ['GRDSET'], 'gridb' : ['GRIDB'], 'seqgp' : ['SEQGP'], 'ao_element_flags' : ['CBARAO'], #'POINTAX', 'RINGAX', # CMASS4 lies in the QRG 'masses' : ['CONM1', 'CONM2', 'CMASS1', 'CMASS2', 'CMASS3', 'CMASS4'], 'elements' : [ 'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4', # 'CELAS5', 'CBUSH', 'CBUSH1D', 'CBUSH2D', 'CDAMP1', 'CDAMP2', 'CDAMP3', 'CDAMP4', 'CDAMP5', 'CFAST', 'GENEL', 'CBAR', 'CROD', 'CTUBE', 'CBEAM', 'CBEAM3', 'CONROD', 'CBEND', 'CTRIA3', 'CTRIA6', 'CTRIAR', 'CQUAD4', 'CQUAD8', 'CQUADR', 'CQUAD', 'CPLSTN3', 'CPLSTN6', 'CPLSTN4', 'CPLSTN8', 'CPLSTS3', 'CPLSTS6', 'CPLSTS4', 'CPLSTS8', 'CTRAX3', 'CTRAX6', 'CTRIAX', 'CTRIAX6', 'CQUADX', 'CQUADX4', 'CQUADX8', 'CCONEAX', 'CTETRA', 'CPYRAM', 'CPENTA', 'CHEXA', 'CIHEX1', 'CIHEX2', 'CSHEAR', 'CVISC', 'CRAC2D', 'CRAC3D', 'CGAP', # thermal 'CHBDYE', 'CHBDYG', 'CHBDYP', # acoustic 'CHACAB', 'CAABSF', 'CHACBR', ], 'normals' : ['SNORM'], 'nsms' : ['NSM', 'NSM1', 'NSML', 'NSML1'], 'nsmadds' : ['NSMADD'], 'rigid_elements' : ['RBAR', 'RBAR1', 'RBE1', 'RBE2', 'RBE3', 'RROD', 'RSPLINE', 'RSSCON'], 'plotels' : ['PLOTEL'], 'properties_mass' : ['PMASS'], #'properties_acoustic' : ['PACABS'], 'properties' : [ # acoustic 'PACABS', 'PAABSF', 'PACBAR', # 0d 'PELAS', 'PGAP', 'PFAST', 'PBUSH', 'PBUSH1D', 'PDAMP', 'PDAMP5', # 1d 'PROD', 'PBAR', 'PBARL', 'PBEAM', 'PTUBE', 'PBEND', 'PBCOMP', 'PBRSECT', 'PBMSECT', 'PBEAML', # not fully supported 'PBEAM3', # 2d 'PLPLANE', 'PPLANE', 'PSHELL', 'PCOMP', 'PCOMPG', 'PSHEAR', 'PSOLID', 'PLSOLID', 'PVISC', 'PRAC2D', 'PRAC3D', 'PIHEX', 'PCOMPS', 'PCONEAX', ], 'pdampt' : ['PDAMPT'], 'pelast' : ['PELAST'], 'pbusht' : ['PBUSHT'], # materials 'materials' : ['MAT1', 'MAT2', 'MAT3', 'MAT8', 'MAT9', 'MAT10', 'MAT11', 'MAT3D', 'MATG'], 'hyperelastic_materials' : ['MATHE', 'MATHP'], 'creep_materials' : ['CREEP'], 'MATT1' : ['MATT1'], 'MATT2' : ['MATT2'], 'MATT3' : ['MATT3'], 'MATT4' : ['MATT4'], # thermal 'MATT5' : ['MATT5'], # thermal 'MATT8' : ['MATT8'], 'MATT9' : ['MATT9'], 'MATS1' : ['MATS1'], 'MATS3' : ['MATS3'], 'MATS8' : ['MATS8'], 'nxstrats' : ['NXSTRAT'], # 'MATHE' #'EQUIV', # testing only, should never be activated... # thermal materials 'thermal_materials' : ['MAT4', 'MAT5'], # spc/mpc constraints - TODO: is this correct? 'spcadds' : ['SPCADD'], 'spcs' : ['SPC', 'SPC1', 'SPCAX', 'GMSPC'], 'spcoffs' : ['SPCOFF', 'SPCOFF1'], 'mpcadds' : ['MPCADD'], 'mpcs' : ['MPC'], 'suport' : ['SUPORT'], 'suport1' : ['SUPORT1'], 'se_suport' : ['SESUP'], 'setree' : ['SETREE'], 'senqset' : ['SENQSET'], 'sebulk' : ['SEBULK'], 'sebndry' : ['SEBNDRY'], 'release' : ['RELEASE'], 'seloc' : ['SELOC'], 'sempln' : ['SEMPLN'], 'seconct' : ['SECONCT'], 'selabel' : ['SELABEL'], 'seexcld' : ['SEEXCLD'], 'seelt' : ['SEELT'], 'seload' : ['SELOAD'], 'csuper' : ['CSUPER'], 'csupext' : ['CSUPEXT'], # loads 'load_combinations' : ['LOAD', 'LSEQ', 'CLOAD'], 'loads' : [ 'FORCE', 'FORCE1', 'FORCE2', 'MOMENT', 'MOMENT1', 'MOMENT2', 'GRAV', 'ACCEL', 'ACCEL1', 'PLOAD', 'PLOAD1', 'PLOAD2', 'PLOAD4', 'RFORCE', 'RFORCE1', 'SLOAD', 'GMLOAD', 'SPCD', 'LOADCYN', 'LOADCYH', 'DEFORM', # thermal 'TEMP', 'TEMPB3', 'TEMPRB', 'QBDY1', 'QBDY2', 'QBDY3', 'QHBDY', 'QVOL', # axisymmetric 'PLOADX1', 'FORCEAX', 'PRESAX', 'TEMPAX', ], 'cyjoin' : ['CYJOIN'], 'cyax' : ['CYAX'], 'modtrak' : ['MODTRAK'], 'dloads' : ['DLOAD'], # stores RLOAD1, RLOAD2, TLOAD1, TLOAD2, and ACSRCE entries. 'dload_entries' : ['ACSRCE', 'TLOAD1', 'TLOAD2', 'RLOAD1', 'RLOAD2', 'QVECT', 'RANDPS', 'RANDT1'], # aero cards 'aero' : ['AERO'], 'aeros' : ['AEROS'], 'gusts' : ['GUST', 'GUST2'], 'flutters' : ['FLUTTER'], 'flfacts' : ['FLFACT'], 'mkaeros' : ['MKAERO1', 'MKAERO2'], 'aecomps' : ['AECOMP', 'AECOMPL'], 'aefacts' : ['AEFACT'], 'aelinks' : ['AELINK'], 'aelists' : ['AELIST'], 'aeparams' : ['AEPARM'], 'aesurf' : ['AESURF'], 'aesurfs' : ['AESURFS'], 'aestats' : ['AESTAT'], 'caeros' : ['CAERO1', 'CAERO2', 'CAERO3', 'CAERO4', 'CAERO5', 'CAERO7', 'BODY7'], 'paeros' : ['PAERO1', 'PAERO2', 'PAERO3', 'PAERO4', 'PAERO5', 'SEGMESH'], 'monitor_points' : ['MONPNT1', 'MONPNT2', 'MONPNT3', 'MONDSP1'], 'splines' : ['SPLINE1', 'SPLINE2', 'SPLINE3', 'SPLINE4', 'SPLINE5', 'SPLINE6', 'SPLINE7'], 'panlsts' : ['PANLST1', 'PANLST2', 'PANLST3'], 'csschds' : ['CSSCHD',], #'SPLINE3', 'SPLINE6', 'SPLINE7', 'trims' : ['TRIM', 'TRIM2'], 'divergs' : ['DIVERG'], # coords 'coords' : ['CORD1R', 'CORD1C', 'CORD1S', 'CORD2R', 'CORD2C', 'CORD2S', 'GMCORD', 'ACOORD', 'CORD3G'], # temperature cards 'tempds' : ['TEMPD'], 'phbdys' : ['PHBDY'], 'convection_properties' : ['PCONV', 'PCONVM'], # stores thermal boundary conditions 'bcs' : ['CONV', 'CONVM', 'RADBC', 'RADM', 'TEMPBC'], # dynamic cards 'dareas' : ['DAREA'], 'tics' : ['TIC'], 'dphases' : ['DPHASE'], 'nlparms' : ['NLPARM'], 'nlpcis' : ['NLPCI'], 'tsteps' : ['TSTEP'], 'tstepnls' : ['TSTEPNL', 'TSTEP1'], 'transfer_functions' : ['TF'], 'delays' : ['DELAY'], 'rotors' : ['ROTORG', 'ROTORD'], 'frequencies' : ['FREQ', 'FREQ1', 'FREQ2', 'FREQ3', 'FREQ4', 'FREQ5'], # direct matrix input cards 'dmig' : ['DMIG'], 'dmiax' : ['DMIAX'], 'dmij' : ['DMIJ'], 'dmiji' : ['DMIJI'], 'dmik' : ['DMIK'], 'dmi' : ['DMI'], 'dti' : ['DTI'], # optimzation 'dequations' : ['DEQATN'], 'dtable' : ['DTABLE'], 'dconstrs' : ['DCONSTR', 'DCONADD'], 'desvars' : ['DESVAR'], 'topvar' : ['TOPVAR'], 'ddvals' : ['DDVAL'], 'dlinks' : ['DLINK'], 'dresps' : ['DRESP1', 'DRESP2', 'DRESP3'], 'dvprels' : ['DVPREL1', 'DVPREL2'], 'dvmrels' : ['DVMREL1', 'DVMREL2'], 'dvcrels' : ['DVCREL1', 'DVCREL2'], 'dvgrids' : ['DVGRID'], 'doptprm' : ['DOPTPRM'], 'dscreen' : ['DSCREEN'], # sets 'asets' : ['ASET', 'ASET1'], 'omits' : ['OMIT', 'OMIT1'], 'bsets' : ['BSET', 'BSET1'], 'qsets' : ['QSET', 'QSET1'], 'csets' : ['CSET', 'CSET1'], 'usets' : ['USET', 'USET1'], 'sets' : ['SET1', 'SET3'], # super-element sets 'se_bsets' : ['SEBSET', 'SEBSET1'], 'se_csets' : ['SECSET', 'SECSET1'], 'se_qsets' : ['SEQSET', 'SEQSET1'], 'se_usets' : ['SEUSET', 'SEQSET1'], 'se_sets' : ['SESET'], 'radset' : ['RADSET'], 'radcavs' : ['RADCAV', 'RADLST'], 'radmtx' : ['RADMTX'], # SEBSEP # parametric 'pset' : ['PSET'], 'pval' : ['PVAL'], 'gmcurv' : ['GMCURV'], 'gmsurf' : ['GMSURF'], 'feedge' : ['FEEDGE'], 'feface' : ['FEFACE'], # tables 'tables' : [ 'TABLEH1', 'TABLEHT', 'TABLES1', 'TABLEST', ], 'tables_d' : ['TABLED1', 'TABLED2', 'TABLED3', 'TABLED4', 'TABLED5'], 'tables_m' : ['TABLEM1', 'TABLEM2', 'TABLEM3', 'TABLEM4'], 'tables_sdamping' : ['TABDMP1'], 'random_tables' : ['TABRND1', 'TABRNDG'], # initial conditions - sid (set ID) ##'TIC', (in bdf_tables.py) # methods 'methods' : ['EIGB', 'EIGR', 'EIGRL'], # cMethods 'cMethods' : ['EIGC', 'EIGP'], # contact 'bctparas' : ['BCTPARA'], 'bcrparas' : ['BCRPARA'], 'bctadds' : ['BCTADD'], 'bctsets' : ['BCTSET'], 'bsurf' : ['BSURF'], 'bsurfs' : ['BSURFS'], 'bconp' : ['BCONP'], 'blseg' : ['BLSEG'], 'bfric' : ['BFRIC'], 'views' : ['VIEW'], 'view3ds' : ['VIEW3D'], ## other #'INCLUDE', # '=' #'ENDDATA', } # type: Dict[str, List[str]] self._type_to_slot_map = self.get_rslot_map()
def plot_shear_moment_torque(self, model_name, gpforce, p1, p2, p3, zaxis, method='Z-Axis Projection', cid_p1=0, cid_p2=0, cid_p3=0, cid_zaxis=0, nplanes=20, plane_color=None, plane_opacity=0.5, csv_filename=None, show=True): """Creates a shear moment torque plot for the active plot result""" log = self.gui.log if plane_color is None: plane_color = PURPLE_FLOAT assert len(plane_color) == 3, plane_color model = self.gui.models[model_name] out = model.get_displacement_index_xyz_cp_cd() icd_transform, icp_transform, xyz_cp, nid_cp_cd = out nids = nid_cp_cd[:, 0] nid_cd = nid_cp_cd[:, [0, 2]] xyz_cid0 = model.transform_xyzcp_to_xyz_cid(xyz_cp, nids, icp_transform, cid=0) #xyz_min, xyz_max = model.xyz_limits xyz_min = xyz_cid0.min(axis=0) xyz_max = xyz_cid0.max(axis=0) assert len(xyz_min) == 3, xyz_min dxyz = np.abs(xyz_max - xyz_min) dim_max = dxyz.max() izero = np.where(dxyz == 0) dxyz[izero] = dim_max xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r( model, p1, p2, zaxis, cid_p1=cid_p1, cid_p2=cid_p2, cid_zaxis=cid_zaxis, method=method) xyz3 = model.coords[cid_p3].transform_node_to_global(p3) dx = xyz3[0] - xyz1[0] stations = np.linspace(0., dx, num=nplanes, endpoint=True) x = stations try: # i/j/k vector is nan coord = CORD2R(1, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane, comment='') except: log.error( 'The coordinate system is invalid; check your cutting plane.') return None, None origin = coord.origin beta = coord.beta().T cid = '' self.gui.create_coordinate_system(cid, dim_max, label='%s' % cid, origin=origin, matrix_3x3=beta, coord_type='xyz') plane_actor = self.gui._create_plane_actor_from_points( xyz1, xyz2, i, k, dim_max, actor_name='smt_plane') props = self.gui.geometry_properties['smt_plane'] props.set_color(plane_color) props.opacity = plane_opacity prop = plane_actor.GetProperty() prop.SetColor(*plane_color) prop.SetOpacity(plane_opacity) # 0=transparent, 1=solid plane_actor.VisibilityOn() if 0: point_actor = self.gui.create_point_actor_from_points( [xyz1, xyz3], point_size=8, actor_name='smt_points') prop = point_actor.GetProperty() prop.SetColor(*plane_color) prop.SetOpacity(plane_opacity) # 0=transparent, 1=solid point_actor.VisibilityOn() self.gui.rend.Render() self.gui.Render() eids, element_centroids_cid0 = get_element_centriods(model) force_sum, moment_sum = gpforce.shear_moment_diagram( xyz_cid0, eids, nids, icd_transform, element_centroids_cid0, model.coords, nid_cd, stations, coord, idir=0, itime=0, debug=False, logger=log) plot_smt(x, force_sum, moment_sum, show=show) return force_sum, moment_sum
def get_stations(model: BDF, p1, p2, p3, zaxis, method: str = 'Z-Axis Projection', cid_p1: int = 0, cid_p2: int = 0, cid_p3: int = 0, cid_zaxis: int = 0, idir: int = 0, nplanes: int = 20) -> Tuple[NDArray3float, NDArray3float, ]: """ Gets the axial stations Parameters ---------- p1: (3,) float ndarray defines the starting point for the shear, moment, torque plot p3: (3,) float ndarray defines the end point for the shear, moment, torque plot p2: (3,) float ndarray defines the XZ plane for the shears/moments zaxis: (3,) float ndarray the direction of the z-axis cid_p1 / cid_p2 / cid_p3 : int the coordinate systems for p1, p2, and p3 method : str 'Z-Axis Projection' p1-p2 defines the x-axis k is defined by the z-axis 'CORD2R' : typical idir : int; default=0 the direction of the step direction Returns ------- xyz1 / xyz2 / xyz3 : (3,) float ndarray the 1=starting 2=ending, 3=normal coordinates of the coordinate frames to create in the cid=0 frame i / k : (3,) float ndarray the i and k vectors of the coordinate system coord_out : Coord the generated coordinate system stations : (n,) float ndarray ??? """ # define a local coordinate system xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r( model, p1, p2, zaxis, cid_p1=cid_p1, cid_p2=cid_p2, cid_zaxis=cid_zaxis, method=method) xyz3 = model.coords[cid_p3].transform_node_to_global(p3) coord_out = CORD2R(None, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane, comment='') #print(coord_out.get_stats()) xyz1p = coord_out.transform_node_to_local(xyz1) xyz3p = coord_out.transform_node_to_local(xyz3) dx = xyz3p[idir] - xyz1p[idir] if abs(dx) == 0.: msg = f'Coincident starting and end points. dx={dx} xyz1={xyz1} xyz3={xyz3}' raise ValueError(msg) stations = np.linspace(0., dx, num=nplanes, endpoint=True) return xyz1, xyz2, xyz3, i, k, coord_out, stations
def get_stations(model: BDF, p1, p2, p3, zaxis, method: str = 'Z-Axis Projection', cid_p1: int = 0, cid_p2: int = 0, cid_p3: int = 0, cid_zaxis: int = 0, idir: int = 0, nplanes: int = 20) -> Tuple[NDArray3float, NDArray3float, ]: """ Gets the axial stations Parameters ---------- p1: (3,) float ndarray defines the starting point for the shear, moment, torque plot p3: (3,) float ndarray defines the end point for the shear, moment, torque plot p2: (3,) float ndarray defines the XZ plane for the shears/moments zaxis: (3,) float ndarray the direction of the z-axis cid_p1 / cid_p2 / cid_p3 : int the coordinate systems for p1, p2, and p3 method : str 'Z-Axis Projection' p1-p2 defines the x-axis k is defined by the z-axis 'CORD2R' : typical idir : int; default=0 the direction of the step direction (0, 1, 2) Returns ------- xyz1 / xyz2 / xyz3 : (3,) float ndarray the 1=starting 2=ending, 3=normal coordinates of the coordinate frames to create in the cid=0 frame i / k : (3,) float ndarray the i and k vectors of the coordinate system coord_out : Coord the generated coordinate system where the x-axis defines the direction to be marched stations : (n,) float ndarray the coordinates in the x-axis that will be marched down Example ------- For the BWB example, we to calculate an SMT down the global x-axis 1--------> y | | | 2, 3 | v x # axial p1 = np.array([0., 0., 0.]) # origin p2 = np.array([1600., 0., 0.]) # xaxis p3 = np.array([1600., 0., 0.]) # end zaxis = np.array([0., 0., 1.]) method = 'Z-Axis Projection' idir = 0 xyz1, xyz2, xyz3, i, k, coord_out, stations = get_stations( model, p1, p2, p3, zaxis, method=method, cid_p1=0, cid_p2=0, cid_p3=0, cid_zaxis=0, idir=idir, nplanes=100) print(stations) """ # define a local coordinate system xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r( model, p1, p2, zaxis, cid_p1=cid_p1, cid_p2=cid_p2, cid_zaxis=cid_zaxis, method=method) xyz3 = model.coords[cid_p3].transform_node_to_global(p3) coord_out = CORD2R(None, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane, comment='') #print(coord_out.get_stats()) xyz1p = coord_out.transform_node_to_local(xyz1) xyz3p = coord_out.transform_node_to_local(xyz3) dx = xyz3p[idir] - xyz1p[idir] if abs(dx) == 0.: msg = f'Coincident starting and end points. dx={dx} xyz1={xyz1} xyz3={xyz3}\n' msg += coord_out.get_stats() raise ValueError(msg) stations = np.linspace(0., dx, num=nplanes, endpoint=True) return xyz1, xyz2, xyz3, i, k, coord_out, stations
def get_stations(model: BDF, p1: NDArray3float, p2: NDArray3float, p3: NDArray3float, zaxis: NDArray3float, method: str='Z-Axis Projection', cid_p1: int=0, cid_p2: int=0, cid_p3: int=0, cid_zaxis: int=0, nplanes: int=20) -> Tuple[NDArray3float, NDArray3float, NDArray3float, NDArray3float, NDArray3float, CORD2R, NDArray3float, NDArrayNfloat]: """ Gets the axial stations Parameters ---------- p1: (3,) float ndarray defines the starting point for the shear, moment, torque plot p3: (3,) float ndarray defines the end point for the shear, moment, torque plot p2: (3,) float ndarray defines the XZ plane for the shears/moments zaxis: (3,) float ndarray the direction of the z-axis cid_p1 / cid_p2 / cid_p3 : int the coordinate systems for p1, p2, and p3 method : str 'Z-Axis Projection' p1-p2 defines the x-axis k is defined by the z-axis 'CORD2R' : typical Returns ------- xyz1 / xyz2 / xyz3 : (3,) float ndarray the 1=starting 2=ending, 3=normal coordinates of the coordinate frames to create in the cid=0 frame i / k : (3,) float ndarray the i and k vectors of the coordinate system coord_out : Coord the output coordinate system iaxis_march : (3,) float ndarray the normalized x-axis that defines the direction to march stations : (n,) float ndarray the coordinates in the x-axis that will be marched down Example ------- For the BWB example, we to calculate an SMT down the global x-axis 1--------> y | | | 2, 3 | v x # axial p1 = np.array([0., 0., 0.]) # origin p2 = np.array([1600., 0., 0.]) # xaxis p3 = np.array([1600., 0., 0.]) # end zaxis = np.array([0., 0., 1.]) method = 'Z-Axis Projection' xyz1, xyz2, xyz3, i, k, coord_out, stations = get_stations( model, p1, p2, p3, zaxis, method=method, cid_p1=0, cid_p2=0, cid_p3=0, cid_zaxis=0, nplanes=100) print(stations) """ p1 = np.asarray(p1) # start p2 = np.asarray(p2) # xz-plane p3 = np.asarray(p3) # end point zaxis = np.asarray(zaxis) # define a local coordinate system xyz1, xyz2, unused_z_global, i, k, origin, zaxis2, xzplane = _p1_p2_zaxis_to_cord2r( model, p1, p2, zaxis, cid_p1=cid_p1, cid_p2=cid_p2, cid_zaxis=cid_zaxis, method=method) xyz3 = model.coords[cid_p3].transform_node_to_global(p3) coord_out = CORD2R(None, origin=origin, zaxis=zaxis2, xzplane=xzplane) #coord_march = coord_out xaxis_march = xyz3 - xyz1 xaxis_march_norm = np.linalg.norm(xaxis_march) if xaxis_march_norm == 0.: msg = f'Coincident starting and end points. dx={xaxis_march_norm} xyz1={xyz1} xyz3={xyz3}\n' #msg += coord_out.get_stats() raise ValueError(msg) iaxis_march = xaxis_march / xaxis_march_norm # k has been rotated into the output coordinte frame, so we'll maintain that # k is length=1 assert np.allclose(np.linalg.norm(k), 1.0) jaxis_march = np.cross(k, iaxis_march) kaxis_march = np.cross(iaxis_march, jaxis_march) coord_march = CORD2R(None, origin=origin, zaxis=origin+kaxis_march, xzplane=origin+iaxis_march) #coord_march = CORD2R(None, origin=origin, zaxis=axis_march, xzplane=xzplane) #print(coord_out.get_stats()) xyz1p = coord_march.transform_node_to_local(xyz1) xyz3p = coord_march.transform_node_to_local(xyz3) xaxis = xyz3p - xyz1p # we want to give the dx the right sign in the coord_out frame #i_abs = np.abs(coord_march.i) #i_abs_max = i_abs.max() #idir = np.where(i_abs == i_abs_max)[0][0] #isign = np.sign(coord_march.i[idir]) dx = xaxis[0] # * isign if abs(dx) == 0.: msg = f'Coincident starting and end points. dx={dx} xyz1={xyz1} xyz3={xyz3}\n' msg += coord_out.get_stats() raise ValueError(msg) x_stations_march = np.linspace(0., dx, num=nplanes, endpoint=True) assert x_stations_march.shape == (nplanes, ), x_stations_march.shape #stations.sort() return xyz1, xyz2, xyz3, i, k, coord_out, iaxis_march, x_stations_march
def make_cutting_plane(self, model_name, p1, p2, zaxis, method='Z-Axis Projection', cid_p1=0, cid_p2=0, cid_zaxis=0, ytol=1., plane_atol=1e-5, plane_color=None, plane_opacity=0.5, csv_filename=None, show=True): """Creates a cutting plane of the aero_model for the active plot result""" if plane_color is None: plane_color = PURPLE_FLOAT assert len(plane_color) == 3, plane_color log = self.gui.log model = self.gui.models[model_name] class_name = model.__class__.__name__ if class_name in ['BDF', 'OP2Geom']: out = model.get_displacement_index_xyz_cp_cd() unused_icd_transform, icp_transform, xyz_cp, nid_cp_cd = out nids = nid_cp_cd[:, 0] nid_cd = nid_cp_cd[:, [0, 2]] xyz_cid0 = model.transform_xyzcp_to_xyz_cid(xyz_cp, nids, icp_transform, cid=0) else: log.error('%r is not supported' % class_name) return #xyz_min, xyz_max = model.xyz_limits xyz_min = xyz_cid0.min(axis=0) xyz_max = xyz_cid0.max(axis=0) assert len(xyz_min) == 3, xyz_min dxyz = np.abs(xyz_max - xyz_min) dim_max = dxyz.max() izero = np.where(dxyz == 0) dxyz[izero] = dim_max xyz1, xyz2, unused_z_global, i, k, origin, zaxis, xzplane = _p1_p2_zaxis_to_cord2r( model, p1, p2, zaxis, cid_p1=cid_p1, cid_p2=cid_p2, cid_zaxis=cid_zaxis, method=method) plane_actor = self.gui._create_plane_actor_from_points( xyz1, xyz2, i, k, dim_max, actor_name='plane') prop = plane_actor.GetProperty() prop.SetColor(*plane_color) prop.SetOpacity(plane_opacity) # 0=transparent, 1=solid self.gui.rend.Render() try: # i/j/k vector is nan coord = CORD2R(1, rid=0, origin=origin, zaxis=zaxis, xzplane=xzplane, comment='') except: log.error( 'The coordinate system is invalid; check your cutting plane.') return #print(coord) origin = coord.origin beta = coord.beta().T cid = '' self.gui.create_coordinate_system(cid, dim_max, label='%s' % cid, origin=origin, matrix_3x3=beta, coord_type='xyz') nnodes = xyz_cid0.shape[0] #nodal_result = np.linspace(0., 1., num=nnodes) #case = self.result_cases[self.icase_aero] #res_scalars, location = model.aero_raw_plot_result() (obj, (i, name)) = self.gui.result_cases[self.gui.icase_fringe] res_scalars = obj.get_scalar(i, name) location = obj.get_location(i, name) if res_scalars is None: if plane_actor is not None: plane_actor.VisibilityOn() #print(self.model_frame.plane_actor) #print(dir(self.model_frame.plane_actor)) #plane_actor.VisibilityOff() log.error('No result is selected.') return if hasattr(obj, 'titles'): title = obj.titles[0] elif hasattr(obj, 'title'): title = obj.title else: raise NotImplementedError(obj) plane_actor.VisibilityOn() if location == 'centroid': if hasattr(model, 'map_centroidal_result'): nodal_result = model.map_centroidal_result(res_scalars) else: log.error('Centroidal results are not supported.') return #np.savetxt('Cp_centroid.csv', res_scalars, header='# Cp') #np.savetxt('Cp_nodal.csv', nodal_result, header='# Cp') else: nodal_result = res_scalars assert len(nodal_result) == nnodes invert_yaxis = False if title in ['Cp']: invert_yaxis = True cut_and_plot_model(title, p1, p2, zaxis, model, coord, nodal_result, log, ytol, plane_atol=plane_atol, csv_filename=csv_filename, invert_yaxis=invert_yaxis, cut_type='edge', show=show)