pyNastran
0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
|
00001 ## GNU Lesser General Public License 00002 ## 00003 ## Program pyNastran - a python interface to NASTRAN files 00004 ## Copyright (C) 2011-2012 Steven Doyle, Al Danial 00005 ## 00006 ## Authors and copyright holders of pyNastran 00007 ## Steven Doyle <mesheb82@gmail.com> 00008 ## Al Danial <al.danial@gmail.com> 00009 ## 00010 ## This file is part of pyNastran. 00011 ## 00012 ## pyNastran is free software: you can redistribute it and/or modify 00013 ## it under the terms of the GNU Lesser General Public License as published by 00014 ## the Free Software Foundation, either version 3 of the License, or 00015 ## (at your option) any later version. 00016 ## 00017 ## pyNastran is distributed in the hope that it will be useful, 00018 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 ## GNU General Public License for more details. 00021 ## 00022 ## You should have received a copy of the GNU Lesser General Public License 00023 ## along with pyNastran. If not, see <http://www.gnu.org/licenses/>. 00024 ## 00025 # pylint: disable=R0904,R0902 00026 00027 from __future__ import division, print_function 00028 from numpy import array, cross 00029 00030 from pyNastran.bdf.cards.loads.staticLoads import Moment, Force 00031 from pyNastran.bdf.cards.elements.shell import ShellElement 00032 00033 00034 class BDFMethods(object): 00035 def __init__(self): 00036 pass 00037 #-------------------- 00038 # METHODS 00039 00040 def MassProperties(self): 00041 """ 00042 Caclulates mass properties in the global system about <0,0,0> 00043 I = mass*centroid*centroid 00044 Ixx = mass*(y^2+z^2) 00045 Iyz = -mass*y*z 00046 http://en.wikipedia.org/wiki/Moment_of_inertia#Moment_of_inertia_tensor 00047 """ 00048 #Ixx Iyy Izz, Ixy, Ixz Iyz 00049 I = array([0., 0., 0., 0., 0., 0.,]) 00050 cg = array([0., 0., 0.]) 00051 mass = 0. 00052 for element in self.elements.itervalues(): 00053 try: 00054 p = element.Centroid() # not really coded across the board 00055 m = element.Mass() 00056 (x, y, z) = p 00057 x2 = x*x 00058 y2 = y*y 00059 z2 = z*z 00060 I[0] += m*(y2+z2) # Ixx 00061 I[1] += m*(x2+z2) # Iyy 00062 I[2] += m*(x2+y2) # Izz 00063 I[3] -= m*x*y # Ixy 00064 I[4] -= m*x*z # Ixz 00065 I[5] -= m*y*z # Iyz 00066 mass += m 00067 cg += m*p 00068 except: 00069 self.log().warning("could not get inertia for element" 00070 "...\n%s" %(element)) 00071 ### 00072 ### 00073 cg = cg/mass 00074 return (mass, cg, I) 00075 00076 def Mass(self): 00077 """Caclulates mass in the global coordinate system""" 00078 mass = 0. 00079 for element in self.elements.itervalues(): 00080 m = element.Mass() 00081 mass += m 00082 return (mass) 00083 00084 def resolveGrids(self, cid=0): 00085 """ 00086 Puts all nodes in a common coordinate system (mainly for cid testing) 00087 @param self the object pointer 00088 @param cid the cid to resolve the nodes to 00089 @note loses association with previous coordinate systems so to go back 00090 requires another fem 00091 """ 00092 assert cid in self.coords, ('cannot resolve nodes to ' 00093 'cid=|%s| b/c it doesnt exist' %(cid)) 00094 for nid,node in sorted(self.nodes.iteritems()): 00095 p = node.PositionWRT(self, cid) 00096 #p = node.Position(self) 00097 #print "p = ",p 00098 node.UpdatePosition(self, p, cid) 00099 ### 00100 00101 def unresolveGrids(self, femOld): 00102 """ 00103 Puts all nodes back to original coordinate system. 00104 @param self 00105 the object pointer 00106 @param femOld 00107 the old model that hasnt lost it's connection to the node cids 00108 @warning 00109 hasnt been tested well... 00110 """ 00111 debug = False 00112 for (nid, nodeOld) in femOld.nodes.iteritems(): 00113 coord = femOld.node.cp 00114 (p, matrix) = coord.transformToGlobal(self.xyz, debug=debug) 00115 p2 = coord.transformToLocal(p,matrix, debug=debug) 00116 self.nodes[nid].UpdatePosition(self, p2, coord.cid) 00117 ### 00118 00119 def sumForces(self): 00120 """ 00121 Sums applied forces for all load cases. 00122 Considers FORCE, FORCE1, FORCE2. 00123 00124 @retval Forces the forces as a numpy array 00125 @warning not validated 00126 """ 00127 for (key, loadCase) in self.loads.iteritems(): 00128 F = array([0., 0., 0.]) 00129 #print "loadCase = ",loadCase 00130 for load in loadCase: 00131 #print "load = ",load 00132 if isinstance(load, Force): 00133 f = load.mag*load.xyz 00134 #print "f = ",f 00135 F += f 00136 ### 00137 self.log.info("case=%s F=%s\n\n" %(key, F)) 00138 ### 00139 return F 00140 00141 def sumMoments(self, p0): 00142 """ 00143 Sums applied forces & moments about a reference point p0 00144 for all load cases. 00145 Considers FORCE, FORCE1, FORCE2, MOMENT, MOMENT1, MOMENT2. 00146 00147 @param p0 the reference point 00148 @retval Moments the moments as a numpy array 00149 @retval Forces the forces as a numpy array 00150 @warning not validated 00151 """ 00152 p = array(p0) 00153 for (key, loadCase) in self.loads.iteritems(): 00154 M = array([0., 0., 0.]) 00155 F = array([0., 0., 0.]) 00156 #print "loadCase = ",loadCase 00157 for load in loadCase: 00158 #print "load = ",load 00159 if isinstance(load, Force): 00160 f = load.mag*load.xyz 00161 node = self.Node(load.node) 00162 #print "node = ",node 00163 r = node.Position() - p 00164 m = cross(r,f) 00165 #print "m = ",m 00166 M += m 00167 F += f 00168 elif isinstance(load, Moment): 00169 m = load.mag*load.xyz 00170 M += m 00171 ### 00172 print("case=%s F=%s M=%s\n\n" %(key, F, M)) 00173 ### 00174 return (M, F) 00175