Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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
Example #5
0
    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
Example #6
0
    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
Example #7
0
    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
Example #8
0
    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---")
Example #9
0
    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
Example #10
0
    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
Example #11
0
    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---")
Example #12
0
    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
Example #13
0
    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
Example #14
0
    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