def find_closest_tet(self, m, closest_tet=None): """ Finds the closest tet. Has the potential to fail, but until then, skipping. Solution to failure: brute force method. m = aeroNode tets = """ tets = self.tets if closest_tet is None: closest_tet = tets[1] #startingTet = tets[1] #closest_tet = self.findClosestTet_recursion(m, startingTet, tets) #print("found tet = ", closest_tet.ID) #v1 = array([1.,0.,0.]) #tet, tet_id = self.bruteForce(m, tets) #return tet log.info("starting tet = %s" % (closest_tet)) tet_id = closest_tet.ID excluded = [] log.info("working on point = %s" % (list_print(m))) counter = 0 counterMax = 100 broken = False is_internal, local_vol = closest_tet.is_internal_node(m) if is_internal: log.info("***already Internal") while is_internal is False: log.info("excluding ID=%s" % tet_id) excluded.append(tet_id) new_tet, min_value = self.find_closer_tet(m, closest_tet, tets, excluded) closest_tet = copy.deepcopy(new_tet) tet_id = closest_tet.ID #print("excluded = ", len(excluded)) counter += 1 if counter == counterMax: break if tet_id in excluded: log.info("ERROR***ID=%s was already excluded...excluded=%s" % (tet_id, excluded)) broken = True break else: pass #print("ID=%s dist=%s" % (tet_id, minValue)) is_internal, local_vol = closest_tet.is_internal_node(m) if broken: closest_tet, tet_id = self.brute_force(m, tets, excluded) else: log.info("*findClosestTet worked!!!") #print("*tet[%s]=%s" % (tetID, closestTet)) #print("nodes = ", closestTet.nodes) return closest_tet, closest_tet.ID
def get_moments(self, Cp): qinf, qinf_unit = self.qInf pinf, pinf_unit = self.pInf sref, _sref_unit = self.Sref lref, _lref_unit = self.Lref xref, _xref_unit = self.xref force_scale, force_scale_unit = self.force_scale moment_scale, moment_scale_unit = self.moment_scale moment_center = array([xref, 0., 0.]) sum_forces = array([0., 0., 0.]) sum_moments = array([0., 0., 0.]) for (key, cp) in self.Cps.items(): # centroidal based Cp area = self.areas[key] centroid = self.centroids[key] normal = self.normals[key] p = cp * qinf + pinf F = area * normal * p # negative sign is b/c the normals are flipped... r = moment_center - centroid if any(isnan(r)): msg = 'r=%s moment_center=%s centroid=%s' % (r, moment_center, centroid) raise RuntimeError(msg) if any(isnan(F)): msg = 'area=%s normal=%s p=%s' % (area, normal, p) raise RuntimeError(msg) sum_forces += F sum_moments += cross(r, F) log.info("pInf=%s [%s]; qInf=%s [%s]" % (pinf, pinf_unit, qinf, qinf_unit)) log.info("force_scale=%s %s" % (force_scale, force_scale_unit)) log.info("moment_scale=%s %s" % (moment_scale, moment_scale_unit)) log.info("sumForcesCFD [%s] = %s" % (force_scale_unit, list_print(sum_forces * force_scale))) log.info("sumMomentsCFD [%s] = %s" % (moment_scale_unit, list_print(sum_moments * moment_scale))) Cf = sum_forces / (sref * qinf) Cm = sum_moments / (sref * qinf * lref) log.info("Cf = %s" % list_print(Cf)) log.info("Cm = %s" % list_print(Cm)) return (sum_forces * force_scale, sum_moments * moment_scale)
def get_moments(self, Cp): qinf, qinf_unit = self.qInf pinf, pinf_unit = self.pInf sref, _sref_unit = self.Sref lref, _lref_unit = self.Lref xref, _xref_unit = self.xref force_scale, force_scale_unit = self.force_scale moment_scale, moment_scale_unit = self.moment_scale moment_center = array([xref, 0., 0.]) sum_forces = array([0., 0., 0.]) sum_moments = array([0., 0., 0.]) for (key, cp) in self.Cps.items(): # centroidal based Cp area = self.areas[key] centroid = self.centroids[key] normal = self.normals[key] p = cp * qinf + pinf F = area * normal * p # negative sign is b/c the normals are flipped... r = moment_center - centroid if any(isnan(r)): msg = 'r=%s moment_center=%s centroid=%s' % (r, moment_center, centroid) raise RuntimeError(msg) if any(isnan(F)): msg = 'area=%s normal=%s p=%s' % (area, normal, p) raise RuntimeError(msg) sum_forces += F sum_moments += cross(r, F) log.info("pInf=%s [%s]; qInf=%s [%s]" % (pinf, pinf_unit, qinf, qinf_unit)) log.info("force_scale=%s %s" % (force_scale, force_scale_unit)) log.info("moment_scale=%s %s" % (moment_scale, moment_scale_unit)) log.info("sumForcesCFD [%s] = %s" % ( force_scale_unit, list_print(sum_forces * force_scale))) log.info("sumMomentsCFD [%s] = %s" % ( moment_scale_unit, list_print(sum_moments * moment_scale))) Cf = sum_forces / (sref * qinf) Cm = sum_moments / (sref * qinf * lref) log.info("Cf = %s" % list_print(Cf)) log.info("Cm = %s" % list_print(Cm)) return (sum_forces * force_scale, sum_moments * moment_scale)
def map_deflection(self, A, d1, d2, d3, d4, i, aero_node, dType="x"): """ see mapDeflections... based on the posiition matrix, finds the ith deflection component Then we ratios the new deflection diMax and compares it to the nearby points to 'test'. """ di = array([d1[i], d2[i], d3[i], d4[i]]) diMax = max(npabs(di)) # L1 norm log.info("d%s = %s" % (dType, list_print(di))) abcd = solve(A, di) # ui = abcd*aero_node # element-wise multiplication...faster, # cant make it work; tried dot & transpose too... (a, b, c, d) = abcd ui = a + b * aero_node[0] + c * aero_node[1] + d * aero_node[2] is_ranged = is_list_ranged(0.0, abcd, 1.0) log.info("is_ranged=%s u%sRatio=%g - a=%g b=%g c=%g d=%g" % (is_ranged, dType, npabs(ui / diMax), a, b, c, d)) return ui
def map_deflection(self, A, d1, d2, d3, d4, i, aero_node, dType='x'): """ see mapDeflections... based on the posiition matrix, finds the ith deflection component Then we ratios the new deflection diMax and compares it to the nearby points to 'test'. """ di = array([d1[i], d2[i], d3[i], d4[i]]) diMax = max(npabs(di)) # L1 norm log.info("d%s = %s" % (dType, list_print(di))) abcd = solve(A, di) #ui = abcd*aero_node # element-wise multiplication...faster, # cant make it work; tried dot & transpose too... (a, b, c, d) = abcd ui = a + b*aero_node[0] + c*aero_node[1] + d*aero_node[2] is_ranged = is_list_ranged(0., abcd, 1.) log.info('is_ranged=%s u%sRatio=%g - a=%g b=%g c=%g d=%g' %( is_ranged, dType, npabs(ui/diMax), a, b, c, d)) return ui
def distribute_unit_load(self, aero_eid, pierced_elements, npiercings): """ distribute unit loads to nearby nodes pierced_elements is a list of piercings piercing = [structural_eid,P,u,v] or [structural_eid] where structural_eid - the structural element ID P - point p was pierced u - u coordinate v - v coordinate if npiercings==0, all the nearby nodes will recieve load """ aero_model = self.aero_model structural_model = self.structural_model #print("pierced_elements = ", pierced_elements) node_ids = [] if npiercings == 0: #assert len(npiercings)==1,'fix me...' #print("npiercings=0 distributing load to closest nodes...u=%g v=%g" %(-1,-1)) log.debug("npiercings=0 distributing load to closest nodes...") structural_eid = None for structural_eid in pierced_elements: node_ids += structural_model.get_element_node_ids( structural_eid) #print("nIDs1 = ", node_ids) node_ids = list(set(node_ids)) log.debug("nIDs2 = %s" % node_ids) aero_centroid = aero_model.Centroid(aero_eid) nodes = structural_model.getNodeIDLocations(node_ids) #print("nodes = ", nodes) weights = self.get_weights(aero_centroid, nodes) distribution = self.create_distribution(node_ids, weights) log.debug("element aEID=%s sEID=%s weights=%s" % (aero_eid, structural_eid, list_print(weights))) #print("distribution = ", distribution) #print("nIDs = ", node_ids) #print("weights = ", weights) #print("nodes = ", nodes) #print("npiercings = ", npiercings) else: log.info("mapping load to actual element...") nclose = 3 # number of elements to map to close_elements = pierced_elements[:nclose] set_close_nodes = set([]) for close_element in reversed(close_elements): log.info("close_element = %s" % close_element) #structural_eid, pIntersect, u1, v1, sdist structural_eid, P, u, v, sdist = close_element # TODO: bug here...??? #close_point = close_element[1] #close_element = structural_eid close_point = P # get list of nearby structural nodes set_element_nodes = set( structural_model.get_element_node_ids(structural_eid)) set_close_nodes = set_close_nodes.union(set_element_nodes) # setup for weighted average node_ids = list(set_close_nodes) structural_nodes = structural_model.getNodeIDLocations(node_ids) weights = self.get_weights(close_point, structural_nodes) distribution = self.create_distribution(node_ids, weights) log.info("element aEID=%s sEID=%s weights=%s" % (aero_eid, structural_eid, list_print(weights))) log.info("-------------------------\n") sys.stdout.flush() return distribution
def pierce_elements(self, aero_centroid, aero_eid, pSource, normal): r""" Pierces *1* element with a ray casted from the centroid/pSource in the direction of the normal vector of an aerodynamic triangle A 1 \/ \ / * \ 2---\-3 \ B *P = A+(B-A)*t """ #direction = -1. # TODO: direction of normal...? (structural_elements, structural_distances ) = self.centroid_tree.get_close_element_ids(aero_centroid) log.info("aCentroid = %s" % aero_centroid) log.info("sElements = %s" % structural_elements) log.info("sDists = %s" % list_print(structural_distances)) #(nearbySElements, nearbyDistances) = structural_elements pierced_elements = [] for structural_eid, sDist in zip(structural_elements, structural_distances): #print("aEID=%s sEID=%s" % (aero_eid, structural_eid)) struc = self.structural_model.get_element_properties( structural_eid) structural_area, structural_normal, structural_centroid = struc sNodes = self.structural_model.get_element_nodes(structural_eid) nnodes = len(sNodes) pEnd = pSource + normal * 10. #pEnd2 = pSource - normal * 10. if nnodes == 3: # TODO: is this enough of a breakdown? sA, sB, sC = sNodes #pEnd = pSource+normal*10. tuv = pierce_plane_vector(sA, sB, sC, pSource, pEnd, pierced_elements) #tuv2 = pierce_plane_vector(sA, sB, sC, pSource, pEnd2, pierced_elements) elif nnodes == 4: sA, sB, sC, sD = sNodes tuv = pierce_plane_vector(sA, sB, sC, pSource, pEnd, pierced_elements) #tuv2 = pierce_plane_vector(sA, sB, sC, pSource, pEnd2, pierced_elements) #self.pierceTriangle(sA, sB, sC, sCentroid, sNormal, pierced_elements) #self.pierceTriangle(sA, sC, sD, sCentroid, sNormal, pierced_elements) else: raise RuntimeError('invalid element; nNodes=%s' % nnodes) t1, u1, v1 = tuv #t2, u2, v2 = tuv2 is_inside_bool = False #if is_inside(u1, v1) or is_inside(u2, v2): if is_inside(u1, v1): is_inside_bool = True #pIntersect = pSource + (pEnd - pSource) * t1 pIntersect = pEnd * t1 + pSource * (1 - t1) #P = A + (B - A) * t tuv = pierce_plane_vector(sA, sB, sC, pSource, pIntersect, pierced_elements) #print("t,u,v=", tuv) pierced_elements.append( [structural_eid, pIntersect, u1, v1, sDist]) #t = min(t1, t2) #print("t1=%6.3g t2=%6.3g" % (t1, t2)) #if is_inside_bool: #print("*t[%s]=%6.3g u1=%6.3g v1=%6.3g u2=%6.3g v2=%6.3g" %( #structural_eid,t,u1,v1,u2,v2)) #else: #print(" t[%s]=%6.3g u1=%6.3g v1=%6.3g u2=%6.3g v2=%6.3g" %( #structural_eid,t,u1,v1,u2,v2)) #if is_inside_bool: #print("*t[%s]=%6.3g u1=%6.3g v1=%6.3g d=%g" %( #structural_eid,t1,u1,v1,sDist)) #else: #print(" t[%s]=%6.3g u1=%6.3g v1=%6.3g d=%g" %( #structural_eid,t1,u1,v1,sDist)) log.info("avgDist = %g" % mean(structural_distances)) (pierced_elements, npiercings) = self.fix_piercings(structural_elements, pierced_elements) distribution = self.distribute_unit_load(aero_eid, pierced_elements, npiercings) return distribution
def map_loads(self): """ Loops thru the unitLoad mapping_matrix and multiplies by the total force F on each panel to calculate the PLOAD that will be printed to the output file. Also, performs a sum of Forces & Moments to verify the aero loads. """ log.info("---starting map_loads---") pinf, pinf_unit = self.pInf qinf, qinf_unit = self.qInf sref, sref_unit = self.Sref lref, lref_unit = self.Lref xref, xref_unit = self.xref force_scale, force_scale_unit = self.force_scale moment_scale, moment_scale_unit = self.moment_scale log.info("self.load_case = %s" % self.load_case) self.load_cases = { self.load_case: {}, } #self.loadCases = {self.load_case={}, } moment_center = array([xref, 0., 0.]) sum_forces = array([0., 0., 0.]) sum_moments = array([0., 0., 0.]) sys.stdout.flush() for aero_eid, distribution in iteritems(self.mapping_matrix): #print("aero_eid = ", aero_eid) #print("***distribution = ", distribution) sum_load = 0. area = self.aero_model.Area(aero_eid) normal = self.aero_model.Normal(aero_eid) Cp = self.aero_model.Cp(aero_eid) #print("Cp = ", Cp) #print("area[%s]=%s" % (aero_eid, area)) p = self.get_pressure(Cp) centroid = self.aero_model.Centroid(aero_eid) r = moment_center - centroid F = area * p Fn = F * normal sum_moments += cross(r, Fn) sum_forces += Fn for structural_nid, percent_load in sorted( iteritems(distribution)): sum_load += percent_load Fxyz = Fn * percent_load # negative sign is to be consistent with nastran self.add_force(structural_nid, Fxyz) #print("Fxyz = ",Fxyz) #print("type(structuralModel) = ", type(self.structuralModel)) #comment = 'percent_load=%.2f' % percent_load #self.structuralModel.write_load(bdf_file, self.loadCase, structural_nid, # Fxyz[0], Fxyz[1], Fxyz[2], comment) #msg = '$ End of aEID=%s sumLoad=%s p=%s area=%s F=%s normal=%s\n' % ( #aEID, sumLoad, p, area, F, normal) #bdf_file.write(msg) with open(self.bdffile, 'wb') as bdf_file: #self.build_mapping_matrix() self.write_loads(bdf_file) # short version of writing loads... log.info("pInf=%g [%s]; qInf=%g [%s]" % (pinf, pinf_unit, qinf, qinf_unit)) log.info("sumForcesFEM [%s] = %s" % ( force_scale_unit, list_print(sum_forces * force_scale), )) # divided by 12 to have moments in lb-ft log.info("sumMomentsFEM [%s] = %s" % ( moment_scale_unit, list_print(sum_moments * moment_scale), )) Cf = sum_forces / (sref * qinf) log.info("Cf = %s" % list_print(Cf)) Cm = sum_moments / (sref * qinf * lref) # multiply by 12 to nondimensionalize ??? maybe 144... log.info("Cm = %s" % list_print(Cm)) #bdf_file.write('$***********\n') log.info("wrote loads to %r" % self.bdffile) log.info("---finished map_loads---")
def distribute_unit_load(self, aero_eid, pierced_elements, npiercings): """ distribute unit loads to nearby nodes pierced_elements is a list of piercings piercing = [structural_eid,P,u,v] or [structural_eid] where structural_eid - the structural element ID P - point p was pierced u - u coordinate v - v coordinate if npiercings==0, all the nearby nodes will recieve load """ aero_model = self.aero_model structural_model = self.structural_model #print("pierced_elements = ", pierced_elements) node_ids = [] if npiercings == 0: #assert len(npiercings)==1,'fix me...' #print("npiercings=0 distributing load to closest nodes...u=%g v=%g" %(-1,-1)) log.debug("npiercings=0 distributing load to closest nodes...") structural_eid = None for structural_eid in pierced_elements: node_ids += structural_model.get_element_node_ids(structural_eid) #print("nIDs1 = ", node_ids) node_ids = list(set(node_ids)) log.debug("nIDs2 = %s" % node_ids) aero_centroid = aero_model.Centroid(aero_eid) nodes = structural_model.getNodeIDLocations(node_ids) #print("nodes = ", nodes) weights = self.get_weights(aero_centroid, nodes) distribution = self.create_distribution(node_ids, weights) log.debug("element aEID=%s sEID=%s weights=%s" % ( aero_eid, structural_eid, list_print(weights))) #print("distribution = ", distribution) #print("nIDs = ", node_ids) #print("weights = ", weights) #print("nodes = ", nodes) #print("npiercings = ", npiercings) else: log.info("mapping load to actual element...") nclose = 3 # number of elements to map to close_elements = pierced_elements[:nclose] set_close_nodes = set([]) for close_element in reversed(close_elements): log.info("close_element = %s" % close_element) #structural_eid, pIntersect, u1, v1, sdist structural_eid, P, u, v, sdist = close_element # TODO: bug here...??? #close_point = close_element[1] #close_element = structural_eid close_point = P # get list of nearby structural nodes set_element_nodes = set(structural_model.get_element_node_ids(structural_eid)) set_close_nodes = set_close_nodes.union(set_element_nodes) # setup for weighted average node_ids = list(set_close_nodes) structural_nodes = structural_model.getNodeIDLocations(node_ids) weights = self.get_weights(close_point, structural_nodes) distribution = self.create_distribution(node_ids, weights) log.info("element aEID=%s sEID=%s weights=%s" % ( aero_eid, structural_eid, list_print(weights))) log.info("-------------------------\n") sys.stdout.flush() return distribution
def pierce_elements(self, aero_centroid, aero_eid, pSource, normal): r""" Pierces *1* element with a ray casted from the centroid/pSource in the direction of the normal vector of an aerodynamic triangle A 1 \/ \ / * \ 2---\-3 \ B *P = A+(B-A)*t """ #direction = -1. # TODO: direction of normal...? (structural_elements, structural_distances) = self.centroid_tree.get_close_element_ids( aero_centroid) log.info("aCentroid = %s" % aero_centroid) log.info("sElements = %s" % structural_elements) log.info("sDists = %s" % list_print(structural_distances)) #(nearbySElements, nearbyDistances) = structural_elements pierced_elements = [] for structural_eid, sDist in zip(structural_elements, structural_distances): #print("aEID=%s sEID=%s" % (aero_eid, structural_eid)) struc = self.structural_model.get_element_properties(structural_eid) structural_area, structural_normal, structural_centroid = struc sNodes = self.structural_model.get_element_nodes(structural_eid) nnodes = len(sNodes) pEnd = pSource + normal * 10. #pEnd2 = pSource - normal * 10. if nnodes == 3: # TODO: is this enough of a breakdown? sA, sB, sC = sNodes #pEnd = pSource+normal*10. tuv = pierce_plane_vector(sA, sB, sC, pSource, pEnd, pierced_elements) #tuv2 = pierce_plane_vector(sA, sB, sC, pSource, pEnd2, pierced_elements) elif nnodes == 4: sA, sB, sC, sD = sNodes tuv = pierce_plane_vector(sA, sB, sC, pSource, pEnd, pierced_elements) #tuv2 = pierce_plane_vector(sA, sB, sC, pSource, pEnd2, pierced_elements) #self.pierceTriangle(sA, sB, sC, sCentroid, sNormal, pierced_elements) #self.pierceTriangle(sA, sC, sD, sCentroid, sNormal, pierced_elements) else: raise RuntimeError('invalid element; nNodes=%s' % nnodes) t1, u1, v1 = tuv #t2, u2, v2 = tuv2 is_inside_bool = False #if is_inside(u1, v1) or is_inside(u2, v2): if is_inside(u1, v1): is_inside_bool = True #pIntersect = pSource + (pEnd - pSource) * t1 pIntersect = pEnd * t1 +pSource * (1 - t1) #P = A + (B - A) * t tuv = pierce_plane_vector(sA, sB, sC, pSource, pIntersect, pierced_elements) #print("t,u,v=", tuv) pierced_elements.append([structural_eid, pIntersect, u1, v1, sDist]) #t = min(t1, t2) #print("t1=%6.3g t2=%6.3g" % (t1, t2)) #if is_inside_bool: #print("*t[%s]=%6.3g u1=%6.3g v1=%6.3g u2=%6.3g v2=%6.3g" %( #structural_eid,t,u1,v1,u2,v2)) #else: #print(" t[%s]=%6.3g u1=%6.3g v1=%6.3g u2=%6.3g v2=%6.3g" %( #structural_eid,t,u1,v1,u2,v2)) #if is_inside_bool: #print("*t[%s]=%6.3g u1=%6.3g v1=%6.3g d=%g" %( #structural_eid,t1,u1,v1,sDist)) #else: #print(" t[%s]=%6.3g u1=%6.3g v1=%6.3g d=%g" %( #structural_eid,t1,u1,v1,sDist)) log.info("avgDist = %g" % mean(structural_distances)) (pierced_elements, npiercings) = self.fix_piercings(structural_elements, pierced_elements) distribution = self.distribute_unit_load(aero_eid, pierced_elements, npiercings) return distribution
def map_loads(self): """ Loops thru the unitLoad mapping_matrix and multiplies by the total force F on each panel to calculate the PLOAD that will be printed to the output file. Also, performs a sum of Forces & Moments to verify the aero loads. """ log.info("---starting map_loads---") pinf, pinf_unit = self.pInf qinf, qinf_unit = self.qInf sref, sref_unit = self.Sref lref, lref_unit = self.Lref xref, xref_unit = self.xref force_scale, force_scale_unit = self.force_scale moment_scale, moment_scale_unit = self.moment_scale log.info("self.load_case = %s" % self.load_case) self.load_cases = { self.load_case : {}, } #self.loadCases = {self.load_case={}, } moment_center = array([xref, 0., 0.]) sum_forces = array([0., 0., 0.]) sum_moments = array([0., 0., 0.]) sys.stdout.flush() for aero_eid, distribution in iteritems(self.mapping_matrix): #print("aero_eid = ", aero_eid) #print("***distribution = ", distribution) sum_load = 0. area = self.aero_model.Area(aero_eid) normal = self.aero_model.Normal(aero_eid) Cp = self.aero_model.Cp(aero_eid) #print("Cp = ", Cp) #print("area[%s]=%s" % (aero_eid, area)) p = self.get_pressure(Cp) centroid = self.aero_model.Centroid(aero_eid) r = moment_center - centroid F = area * p Fn = F * normal sum_moments += cross(r, Fn) sum_forces += Fn for structural_nid, percent_load in sorted(iteritems(distribution)): sum_load += percent_load Fxyz = Fn * percent_load # negative sign is to be consistent with nastran self.add_force(structural_nid, Fxyz) #print("Fxyz = ",Fxyz) #print("type(structuralModel) = ", type(self.structuralModel)) #comment = 'percent_load=%.2f' % percent_load #self.structuralModel.write_load(bdf_file, self.loadCase, structural_nid, # Fxyz[0], Fxyz[1], Fxyz[2], comment) #msg = '$ End of aEID=%s sumLoad=%s p=%s area=%s F=%s normal=%s\n' % ( #aEID, sumLoad, p, area, F, normal) #bdf_file.write(msg) with open(self.bdffile, 'wb') as bdf_file: #self.build_mapping_matrix() self.write_loads(bdf_file) # short version of writing loads... log.info("pInf=%g [%s]; qInf=%g [%s]" % ( pinf, pinf_unit, qinf, qinf_unit)) log.info("sumForcesFEM [%s] = %s" % ( force_scale_unit, list_print(sum_forces * force_scale), )) # divided by 12 to have moments in lb-ft log.info("sumMomentsFEM [%s] = %s" % ( moment_scale_unit, list_print(sum_moments * moment_scale), )) Cf = sum_forces / (sref * qinf) log.info("Cf = %s" % list_print(Cf)) Cm = sum_moments / (sref * qinf * lref) # multiply by 12 to nondimensionalize ??? maybe 144... log.info("Cm = %s" % list_print(Cm)) #bdf_file.write('$***********\n') log.info("wrote loads to %r" % self.bdffile) log.info("---finished map_loads---")
def map_deflections(self, proper_tets=None): """ Loops thru all the aero nodes, finds the tet it's in, interpolates on the deflections at the nodes and maps the deflection to the aero node """ if proper_tets is None: proper_tets = {} sys.stdout.flush() #reader = f06Reader(self.structuralOutfile) #d = reader.readDeflections() aeroNodes = self.aeroNodes #tets = self.tets d = self.deflectionReader tets = self.tets #tets = self.buildTetrahedralization() #aeroNodes = [array([0.0,0.,0.])] aeroNodes2 = [] tet = tets[1] log.info("-" * 80) #print("type(aeroNodes)=%s" % type(aeroNodes)) for i, aero_node in iteritems(aeroNodes): if aero_node[1] < 0: log.info('skipping aero_node=%s bc y<0.' % i) continue log.info("aero_node[%s] = %s" % (i, list_print(aero_node))) #print("aero_node = ",aero_node) #continue if i in proper_tets: tet = tets[proper_tets[i]] else: tet, ID2 = self.find_closest_tet(aero_node, tet) #(isInternal, localVol) = closeTet.isInternalNode(aero_node) #assert isInternal==True #print("isInternal? = %s" % isInternal) #print("***tet = %s" % (tet)) (n0, n1, n2, n3) = tet.nodes ID = tet.ID deflectionsTet = d.get_deflections(ID, n0, n1, n2, n3) aeroNode2 = tet.map_deflections(deflectionsTet, aero_node) log.info("aeroNode2 = %s" % (list_print(aeroNode2))) proper_tets[i] = ID aeroNodes2.append(aeroNode2) #for tet in tets: # should select in certain order based on centroids # if tet.isInternalNode(aero_node): # n0,n1,n2,n3 = tet.nodes # # deflectionsTet = [d[n0], d[n1], d[n2], d[n3]] # aeroNode2 = tet.mapDeflections(deflectionsTet, aero_node) #break # uncomment to run one aero_node log.info("-" * 80) sys.stdout.flush() #return aeroNode2 #for key, value in proper_tets.items(): # print("point_id=%s -> tetID=%s" % (key, value)) sys.stdout.flush() return aeroNodes2, proper_tets
def find_closest_tet(self, m, closest_tet=None): """ Finds the closest tet. Has the potential to fail, but until then, skipping. Solution to failure: brute force method. m = aeroNode tets = """ tets = self.tets if closest_tet is None: closest_tet = tets[1] #startingTet = tets[1] #closest_tet = self.findClosestTet_recursion(m, startingTet, tets) #print("found tet = ", closest_tet.ID) #v1 = array([1.,0.,0.]) #tet, tet_id = self.bruteForce(m, tets) #return tet log.info("starting tet = %s" % (closest_tet)) tet_id = closest_tet.ID excluded = [] log.info("working on point = %s" % (list_print(m))) counter = 0 counterMax = 100 broken = False is_internal, local_vol = closest_tet.is_internal_node(m) if is_internal: log.info("***already Internal") while is_internal is False: log.info("excluding ID=%s" % tet_id) excluded.append(tet_id) new_tet, min_value = self.find_closer_tet(m, closest_tet, tets, excluded) closest_tet = copy.deepcopy(new_tet) tet_id = closest_tet.ID #print("excluded = ", len(excluded)) counter += 1 if counter == counterMax: break if tet_id in excluded: log.info("ERROR***ID=%s was already excluded...excluded=%s" % (tet_id, excluded)) broken = True break else: pass #print("ID=%s dist=%s" % (tet_id, minValue)) is_internal, local_vol = closest_tet.is_internal_node(m) if broken: closest_tet, tet_id = self.brute_force(m, tets, excluded) else: log.info("*findClosestTet worked!!!") #print("*tet[%s]=%s" % (tetID, closestTet)) #print("nodes = ", closestTet.nodes) return closest_tet, closest_tet.ID
def map_deflections(self, proper_tets=None): """ Loops thru all the aero nodes, finds the tet it's in, interpolates on the deflections at the nodes and maps the deflection to the aero node """ if proper_tets is None: proper_tets = {} sys.stdout.flush() #reader = f06Reader(self.structuralOutfile) #d = reader.readDeflections() aeroNodes = self.aeroNodes #tets = self.tets d = self.deflectionReader tets = self.tets #tets = self.buildTetrahedralization() #aeroNodes = [array([0.0,0.,0.])] aeroNodes2 = [] tet = tets[1] log.info("-" * 80) #print("type(aeroNodes)=%s" % type(aeroNodes)) for i, aero_node in iteritems(aeroNodes): if aero_node[1] < 0: log.info('skipping aero_node=%s bc y<0.' % i) continue log.info("aero_node[%s] = %s" % (i, list_print(aero_node))) #print("aero_node = ",aero_node) #continue if i in proper_tets: tet = tets[proper_tets[i]] else: tet, ID2 = self.find_closest_tet(aero_node, tet) #(isInternal, localVol) = closeTet.isInternalNode(aero_node) #assert isInternal==True #print("isInternal? = %s" % isInternal) #print("***tet = %s" % (tet)) (n0, n1, n2, n3) = tet.nodes ID = tet.ID deflectionsTet = d.get_deflections(ID, n0, n1, n2, n3) aeroNode2 = tet.map_deflections(deflectionsTet, aero_node) log.info("aeroNode2 = %s" % (list_print(aeroNode2))) proper_tets[i] = ID aeroNodes2.append(aeroNode2) #for tet in tets: # should select in certain order based on centroids # if tet.isInternalNode(aero_node): # n0,n1,n2,n3 = tet.nodes # # deflectionsTet = [d[n0], d[n1], d[n2], d[n3]] # aeroNode2 = tet.mapDeflections(deflectionsTet, aero_node) #break # uncomment to run one aero_node log.info("-" * 80) sys.stdout.flush() #return aeroNode2 #for key, value in proper_tets.items(): # print("point_id=%s -> tetID=%s" % (key, value)) sys.stdout.flush() return aeroNodes2, proper_tets