def findStructElemIDs(elefile, structNodeIDs): import sys import numpy as n import fem_mesh header_comment_skips = fem_mesh.count_header_comment_skips(elefile) elems = n.loadtxt(elefile, delimiter=',', comments='*', skiprows=header_comment_skips, dtype=[('id', 'i4'), ('pid', 'i4'), ('n1', 'i4'), ('n2', 'i4'), ('n3', 'i4'), ('n4', 'i4'), ('n5', 'i4'), ('n6', 'i4'), ('n7', 'i4'), ('n8', 'i4')]) structElemIDs = {} for i in elems: # I hate this hard-coded syntax, but this works (for now) j = i.tolist() insideStruct = any(x in structNodeIDs for x in j[2:10]) if insideStruct: structElemIDs[i[0]] = True if structElemIDs.__len__ == 0: sys.exit('ERROR: no structure elements were found') return (elems, structElemIDs)
def findStructElemIDs(elefile, structNodeIDs): """ Find the elements that contain nodes in structNodeIDs. """ import sys import numpy as n import fem_mesh header_comment_skips = fem_mesh.count_header_comment_skips(elefile) elems = n.loadtxt(elefile, delimiter=',', comments='*', skiprows=header_comment_skips, dtype=[('id', 'i4'), ('pid', 'i4'), ('n1', 'i4'), ('n2', 'i4'), ('n3', 'i4'), ('n4', 'i4'), ('n5', 'i4'), ('n6', 'i4'), ('n7', 'i4'), ('n8', 'i4')]) structElemIDs = {} for i in elems: # I hate this hard-coded syntax, but this works (for now) j = i.tolist() insideStruct = any(x in structNodeIDs for x in j[2:10]) if insideStruct: structElemIDs[i[0]] = True if len(structElemIDs) == 0: sys.exit('ERROR: no structure elements were found') return (elems, structElemIDs)
def load_nodeIDs_coords(nodefile): """ load in node IDs and coordinates, excluding '*' keyword lines """ import fem_mesh import numpy as n header_comment_skips = fem_mesh.count_header_comment_skips(nodefile) nodeIDcoords = n.loadtxt(nodefile, delimiter=',', comments='*', skiprows=header_comment_skips, dtype=[('id', 'i4'), ('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) return nodeIDcoords
def findStructNodeIDs(args): import sys import numpy as n import math as m import fem_mesh header_comment_skips = fem_mesh.count_header_comment_skips(args.nodefile) nodeIDcoords = n.loadtxt(args.nodefile, delimiter=',', skiprows=header_comment_skips, comments='*', dtype=[('id', 'i4'), ('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) structNodeIDs = {} sopts = args.sopts if args.sphere: ''' sopts is assumed to be a 4 element tuple with the following items: sphere center coordinates (x,y,z) sphere radius ''' for i in nodeIDcoords: nodeRad = n.sqrt(n.power((i[1] - sopts[0]), 2) + n.power((i[2] - sopts[1]), 2) + n.power((i[3] - sopts[2]), 2)) if nodeRad < sopts[3]: structNodeIDs[i[0]] = True elif args.layer: ''' sopts is assumed to be a 3 element tuple with the following items: dimension for normal to layer (x = 1, y = 2, z = 3) layer bounds (min,max) ''' for i in nodeIDcoords: if i[sopts[0]] > sopts[1] and i[sopts[0]] < sopts[2]: structNodeIDs[i[0]] = True elif args.ellipsoid: ''' sopts is assumed to be a 9 element tuple with the following items: ellipsoid center coordinates (x,y,z) ellipsoid half-axis lengths (a,b,c) ellipsoid euler angles (phi,theta,psi) in DEGREES ''' cph = m.cos(m.radians(sopts[6])) # cos(phi) sph = m.sin(m.radians(sopts[6])) # sin(phi) cth = m.cos(m.radians(sopts[7])) # cos(theta) sth = m.sin(m.radians(sopts[7])) # sin(theta) cps = m.cos(m.radians(sopts[8])) # cos(psi) sps = m.sin(m.radians(sopts[8])) # sin(psi) # rotation matrix R = n.matrix([[cth * cps, -cph * sps + sph * sth * cps, sph * sps + cph * sth * cps], [cth * sps, cph * cps + sph * sth * sps, -sph * cps + cph * sth * sps], [-sth, sph * cth, cph * cth]]) # diagonal maxtrix of squared ellipsoid half-axis lengths A = n.matrix([[n.power(sopts[3], 2), 0, 0], [0, n.power(sopts[4], 2), 0], [0, 0, n.power(sopts[5], 2)]]) # A matrix - eigenvalues are a^2,b^2,c^2 (square of half-axis lengths), # eigenvectors are directions of the orthogonal principal axes A = R.transpose().dot(A).dot(R) # locate nodes within ellipsoid for i in nodeIDcoords: radVec = n.matrix([[i[1] - sopts[0]], [i[2] - sopts[1]], [i[3] - sopts[2]]]) if radVec.transpose().dot(A.I).dot(radVec) <= 1: structNodeIDs[i[0]] = True elif args.cube: ''' sopts is assumed to be a 6 element tuple with the following items: Location of most-negative corner (x,y,z) Respective cube dimensions (x,y,z) ''' for i in nodeIDcoords: if i[1] >= sopts[0] and \ i[1] <= (sopts[0] + sopts[3]) and \ i[2] >= sopts[1] and \ i[2] <= (sopts[1] + sopts[4]) and \ i[3] >= sopts[2] and \ i[3] <= (sopts[2] + sopts[5]): structNodeIDs[i[0]] = True else: sys.exit('ERROR: The specified structure is not defined') if len(structNodeIDs) == 0: sys.exit('ERROR: no structure nodes were found') return structNodeIDs
def main(): import sys import numpy as n from bc import SortNodeIDs, extractPlane import fem_mesh fem_mesh.check_version() opts = read_cli() loadtype = opts.loadtype direction = int(opts.direction) amplitude = float(opts.amplitude) lcid = int(opts.lcid) # open the top load file to write LOADFILE = open(opts.loadfile, 'w') if loadtype == 'disp' or loadtype == 'vel' or loadtype == 'accel': LOADFILE.write("*BOUNDARY_PRESCRIBED_MOTION_NODE\n") elif loadtype == 'force': LOADFILE.write("*LOAD_NODE_POINT\n") else: sys.exit('ERROR: Invalid loadtype specified (can only be disp, ' 'force, vel or accel)') LOADFILE.write("$ Generated using %s with the following " "options:\n" % sys.argv[0]) LOADFILE.write("$ %s\n" % opts) # load in all of the node data, excluding '*' lines header_comment_skips = fem_mesh.count_header_comment_skips(opts.nodefile) nodeIDcoords = n.loadtxt(opts.nodefile, delimiter=',', skiprows=header_comment_skips, comments='*', dtype=[('id', 'i4'), ('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) # there are 6 faces in these models; we need to (1) find the top face and # (2) apply the appropriate loads [snic, axes] = SortNodeIDs(nodeIDcoords) # extract spatially-sorted node IDs on a the top z plane plane = (2, axes[2].max()) planeNodeIDs = extractPlane(snic, axes, plane) # write out nodes on the top z plane with corresponding load values # (direction of motion, nodal displacement (accel, vel, etc), temporal load # curve ID, scale factor for load curve) # TODO: would like to clean this up with a dictionary to associate the # prescribed motions with their integer IDs with one statement instead of # three conditional statements below if loadtype == 'disp': writeNodeLoads(LOADFILE, planeNodeIDs, '%i,2,%i,%f' % (direction, lcid, amplitude)) elif loadtype == 'vel': writeNodeLoads(LOADFILE, planeNodeIDs, '%i,0,%i,%f' % (direction, lcid, amplitude)) elif loadtype == 'accel': writeNodeLoads(LOADFILE, planeNodeIDs, '%i,1,%i,%f' % (direction, lcid, amplitude)) elif loadtype == 'force': writeNodeLoads(LOADFILE, planeNodeIDs, '%i,%i,%f' % (direction, lcid, amplitude)) LOADFILE.write("*END\n") # close all of our files open for read/write LOADFILE.close()
def findStructNodeIDs(nodefile, struct_type, sopts): """ Find node IDs that fall within a specified geometry (sphere, layer, cube, ellipsoid). INPUTS: nodefile (nodes.dyn) struct_type (sphere, layer, ellipsoid, cube) sopts (struct-specific parameters) OUTPUTS: structNodeIDs (dict) """ import sys import numpy as n import math as m import fem_mesh header_comment_skips = fem_mesh.count_header_comment_skips(nodefile) nodeIDcoords = n.loadtxt(nodefile, delimiter=',', skiprows=header_comment_skips, comments='*', dtype=[('id', 'i4'), ('x', 'f4'), ('y', 'f4'), ('z', 'f4')]) structNodeIDs = {} if struct_type is 'sphere': ''' sopts is assumed to be a 4 element tuple with the following items: sphere center coordinates (x,y,z) sphere radius ''' for i in nodeIDcoords: nodeRad = n.sqrt(n.power((i[1] - sopts[0]), 2) + n.power((i[2] - sopts[1]), 2) + n.power((i[3] - sopts[2]), 2)) if nodeRad < sopts[3]: structNodeIDs[i[0]] = True elif struct_type is 'layer': ''' sopts is assumed to be a 3 element tuple with the following items: dimension for normal to layer (x = 1, y = 2, z = 3) layer bounds (min,max) ''' for i in nodeIDcoords: if i[sopts[0]] > sopts[1] and i[sopts[0]] < sopts[2]: structNodeIDs[i[0]] = True elif struct_type is 'ellipsoid': ''' sopts is assumed to be a 9 element tuple with the following items: ellipsoid center coordinates (x,y,z) ellipsoid half-axis lengths (a,b,c) ellipsoid euler angles (phi,theta,psi) in DEGREES ''' cph = m.cos(m.radians(sopts[6])) # cos(phi) sph = m.sin(m.radians(sopts[6])) # sin(phi) cth = m.cos(m.radians(sopts[7])) # cos(theta) sth = m.sin(m.radians(sopts[7])) # sin(theta) cps = m.cos(m.radians(sopts[8])) # cos(psi) sps = m.sin(m.radians(sopts[8])) # sin(psi) # rotation matrix R = n.matrix([[cth * cps, -cph * sps + sph * sth * cps, sph * sps + cph * sth * cps], [cth * sps, cph * cps + sph * sth * sps, -sph * cps + cph * sth * sps], [-sth, sph * cth, cph * cth]]) # diagonal maxtrix of squared ellipsoid half-axis lengths A = n.matrix([[n.power(sopts[3], 2), 0, 0], [0, n.power(sopts[4], 2), 0], [0, 0, n.power(sopts[5], 2)]]) # A matrix - eigenvalues are a^2,b^2,c^2 (square of half-axis lengths), # eigenvectors are directions of the orthogonal principal axes A = R.transpose().dot(A).dot(R) # locate nodes within ellipsoid for i in nodeIDcoords: radVec = n.matrix([[i[1] - sopts[0]], [i[2] - sopts[1]], [i[3] - sopts[2]]]) if radVec.transpose().dot(A.I).dot(radVec) <= 1: structNodeIDs[i[0]] = True elif struct_type is 'cube': ''' sopts is assumed to be a 6 element tuple with the following items: Location of most-negative corner (x,y,z) Respective cube dimensions (x,y,z) ''' for i in nodeIDcoords: if i[1] >= sopts[0] and \ i[1] <= (sopts[0] + sopts[3]) and \ i[2] >= sopts[1] and \ i[2] <= (sopts[1] + sopts[4]) and \ i[3] >= sopts[2] and \ i[3] <= (sopts[2] + sopts[5]): structNodeIDs[i[0]] = True else: sys.exit('ERROR: The specified structure is not defined') if len(structNodeIDs) == 0: sys.exit('ERROR: no structure nodes were found') return structNodeIDs