Ejemplo n.º 1
0
    def generate_dvgeo_dvcon_c172(self):
        meshfile = os.path.join(self.base_path, '../inputFiles/c172.stl')
        ffdfile = os.path.join(self.base_path, '../inputFiles/c172.xyz')
        testmesh = mesh.Mesh.from_file(meshfile)
        # test mesh dim 0 is triangle index
        # dim 1 is each vertex of the triangle
        # dim 2 is x, y, z dimension

        # create a DVGeo object with a few local thickness variables
        DVGeo = DVGeometry(ffdfile)
        nRefAxPts = DVGeo.addRefAxis("wing", xFraction=0.25, alignIndex="k")
        self.nTwist = nRefAxPts - 1
        def twist(val, geo):
            for i in range(1, nRefAxPts):
                geo.rot_z["wing"].coef[i] = val[i - 1]
        DVGeo.addGeoDVGlobal(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1)
        DVGeo.addGeoDVLocal("local", lower=-0.5, upper=0.5, axis="y", scale=1)

        # create a DVConstraints object for the wing
        DVCon =DVConstraints()
        DVCon.setDVGeo(DVGeo)
        p0 = testmesh.vectors[:,0,:] / 1000
        v1 = testmesh.vectors[:,1,:] / 1000 - p0
        v2 = testmesh.vectors[:,2,:] / 1000 - p0
        DVCon.setSurface([p0, v1, v2])

        return DVGeo, DVCon
Ejemplo n.º 2
0
    def test_spanwise_dvs(self, train=False, refDeriv=False):
        refFile = os.path.join(self.base_path,
                               "ref/test_Cylinder_spanwise_dvs.ref")

        with BaseRegTest(refFile, train=train) as handler:
            handler.root_print("Test 1: Basic FFD, global DVs")
            radius = 1.0
            height = 10.0

            DVCon = DVConstraints()
            surf = self.make_cylinder_mesh(radius, height)
            DVCon.setSurface(surf)
            # DVCon.writeSurfaceTecplot('cylinder_surface.dat')

            ffd_name = os.path.join(self.base_path,
                                    "../inputFiles/cylinder_ffd.xyz")
            self.make_ffd(ffd_name, radius, height)
            DVGeo = DVGeometry(ffd_name)

            DVGeo.addSpanwiseLocalDV("shape",
                                     "i",
                                     lower=-0.5,
                                     upper=0.5,
                                     axis="y",
                                     scale=1.0)

            size = DVGeo._getNDVSpanwiseLocal()
            DVCon.setDVGeo(DVGeo)

            leList = [[0, 0, 0], [-radius / 2, 0, height]]
            xAxis = [-1, 0, 0]
            yAxis = [0, 1, 0]
            DVCon.addLERadiusConstraints(leList,
                                         nSpan=5,
                                         axis=yAxis,
                                         chordDir=xAxis,
                                         scaled=False)
            # DVCon.writeTecplot('cylinder_constraints.dat')

            funcs = {}
            DVCon.evalFunctions(funcs)
            print(funcs)
            handler.root_add_dict("funcs1", funcs, rtol=1e-6, atol=1e-6)

            np.random.seed(0)
            DVGeo.setDesignVars({"shape": (np.random.rand(size) - 0.5)})

            funcs = {}
            DVCon.evalFunctions(funcs)
            handler.root_add_dict("funcs2", funcs, rtol=1e-6, atol=1e-6)
            print(funcs)

            funcsSens = {}
            DVCon.evalFunctionsSens(funcsSens)
            print(funcsSens)
            handler.root_add_dict("funcsSens", funcsSens, rtol=1e-6, atol=1e-6)
            print(funcsSens)
Ejemplo n.º 3
0
    def test_1(self, train=False, refDeriv=False):
        refFile = os.path.join(self.base_path, 'ref/test_Cylinder_01.ref')

        with BaseRegTest(refFile, train=train) as handler:
            handler.root_print("Test 1: Basic FFD, global DVs")
            radius = 1.0
            height = 10.0

            DVCon = DVConstraints()
            surf = self.make_cylinder_mesh(radius, height)
            DVCon.setSurface(surf)
            # DVCon.writeSurfaceTecplot('cylinder_surface.dat')

            ffd_name = os.path.join(self.base_path,
                                    '../inputFiles/cylinder_ffd.xyz')
            self.make_ffd(ffd_name, radius, height)
            DVGeo = DVGeometry(ffd_name)
            nAxPts = DVGeo.addRefAxis('thru',
                                      xFraction=0.5,
                                      alignIndex='i',
                                      raySize=1.0)

            def scale_circle(val, geo):
                for i in range(nAxPts):
                    geo.scale['thru'].coef[i] = val[0]

            DVGeo.addGeoDVGlobal('scale_circle', func=scale_circle, value=[1])
            DVCon.setDVGeo(DVGeo)

            leList = [[0, 0, 0], [-radius / 2, 0, height]]
            xAxis = [-1, 0, 0]
            yAxis = [0, 1, 0]
            DVCon.addLERadiusConstraints(leList,
                                         nSpan=5,
                                         axis=yAxis,
                                         chordDir=xAxis,
                                         scaled=False)
            # DVCon.writeTecplot('cylinder_constraints.dat')

            funcs = {}
            DVCon.evalFunctions(funcs)
            print(funcs)
            handler.root_add_dict('funcs1', funcs, rtol=1e-6, atol=1e-6)

            DVGeo.setDesignVars({'scale_circle': 0.5})

            funcs = {}
            DVCon.evalFunctions(funcs)
            handler.root_add_dict('funcs2', funcs, rtol=1e-6, atol=1e-6)
            print(funcs)

            funcsSens = {}
            DVCon.evalFunctionsSens(funcsSens)
            print(funcsSens)
            handler.root_add_dict('funcsSens', funcsSens, rtol=1e-6, atol=1e-6)
            print(funcsSens)
Ejemplo n.º 4
0
    def setup(self):

        # create the DVGeo object that does the computations
        if self.options["ffd_file"] is not None:
            # we are doing an FFD-based DVGeo
            ffd_file = self.options["ffd_file"]
            self.DVGeo = DVGeometry(ffd_file)
        if self.options["vsp_file"] is not None:
            # we are doing a VSP based DVGeo
            vsp_file = self.options["vsp_file"]
            vsp_options = self.options["vsp_options"]
            self.DVGeo = DVGeometryVSP(vsp_file, comm=self.comm, **vsp_options)

        self.DVCon = DVConstraints()
        self.DVCon.setDVGeo(self.DVGeo)
        self.omPtSetList = []
Ejemplo n.º 5
0
    def test_spanwise_dvs(self, train=False, refDeriv=False):
        """
        Test spanwise_dvs
        """
        # refFile = os.path.join(self.base_path,'ref/test_DVGeometry_spanwise_dvs.ref')
        # with BaseRegTest(refFile, train=train) as handler:
        #     handler.root_print("Test spanwise local variables writing function")

        meshfile = os.path.join(self.base_path, "../../input_files/c172.stl")
        ffdfile = os.path.join(self.base_path, "../../input_files/c172.xyz")
        testmesh = mesh.Mesh.from_file(meshfile)
        # test mesh dim 0 is triangle index
        # dim 1 is each vertex of the triangle
        # dim 2 is x, y, z dimension

        # create a DVGeo object with a few local thickness variables
        DVGeo = DVGeometry(ffdfile)
        DVGeo.addSpanwiseLocalDV("shape", "i", lower=-0.5, upper=0.5, axis="y", scale=1.0)

        # create a DVConstraints object for the wing
        DVCon = DVConstraints()
        DVCon.setDVGeo(DVGeo)
        p0 = testmesh.vectors[:, 0, :] / 1000
        v1 = testmesh.vectors[:, 1, :] / 1000 - p0
        v2 = testmesh.vectors[:, 2, :] / 1000 - p0
        DVCon.setSurface([p0, v1, v2])

        leList = [[0.7, 0.0, 0.1], [0.7, 0.0, 2.4]]
        teList = [[0.9, 0.0, 0.1], [0.9, 0.0, 2.4]]

        nSpan = 10
        nChord = 10
        name = "thickness_con"
        DVCon.addThicknessConstraints2D(leList, teList, nSpan, nChord, name=name)

        size = DVGeo._getNDVSpanwiseLocal()

        np.random.seed(0)
        DVGeo.setDesignVars({"shape": (np.random.rand(size) - 0.5)})

        funcs = {}
        DVCon.evalFunctions(funcs)
        # print(funcs)

        for i in range(nChord):
            for j in range(nSpan - 1):
                np.testing.assert_allclose(funcs[name][i * nChord + j + 1], funcs[name][i * nChord + j], rtol=2e-15)
Ejemplo n.º 6
0
    def test_13b(self, train=False, refDeriv=False):
        refFile = os.path.join(self.base_path,'ref/test_DVConstraints_13b.ref')
        with BaseRegTest(refFile, train=train) as handler:
            handler.root_print("Test 13: PlanarityConstraint, rectangular box")
            ffdfile = os.path.join(self.base_path, '../inputFiles/2x1x8_rectangle.xyz')
            DVGeo = DVGeometry(ffdfile)
            DVGeo.addGeoDVLocal("local", lower=-0.5, upper=0.5, axis="y", scale=1)

            # create a DVConstraints object with a simple plane consisting of 2 triangles
            DVCon =DVConstraints()
            DVCon.setDVGeo(DVGeo)

            p0 = np.zeros(shape=(2,3))
            p1 = np.zeros(shape=(2,3))
            p2 = np.zeros(shape=(2,3))

            vertex1 = np.array([0.5, -0.25, 0.0])
            vertex2 = np.array([0.5, -0.25, 4.0])
            vertex3 = np.array([-0.5, -0.25, 0.0])
            vertex4 = np.array([-0.5, -0.25, 4.0])

            p0[:,:] = vertex1
            p2[:,:] = vertex4
            p1[0,:] = vertex2
            p1[1,:] = vertex3

            v1 = p1 - p0
            v2 = p2 - p0
            DVCon.setSurface([p0, v1, v2])

            DVCon.addPlanarityConstraint(origin=[0.,-0.25,2.0], planeAxis=[0.,1.,0.])

            funcs, funcsSens = self.generic_test_base(DVGeo, DVCon, handler, checkDerivs=False)

            # this should be coplanar and the planarity constraint shoudl be zero
            handler.assert_allclose(funcs['DVCon1_planarity_constraints_0'], np.zeros(1), 
                                    name='planarity', rtol=1e-7, atol=1e-7)
Ejemplo n.º 7
0
                  func=twist,
                  lower=-10,
                  upper=10,
                  scale=0.01)

# Set up local design variables
DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1)

# Add DVGeo object to CFD solver
CFDSolver.setDVGeo(DVGeo)
# rst dvgeo (end)
# ======================================================================
#         DVConstraint Setup, and Thickness and Volume Constraints
# ======================================================================
# rst dvconVolThick (beg)
DVCon = DVConstraints()
DVCon.setDVGeo(DVGeo)

# Only ADflow has the getTriangulatedSurface Function
DVCon.setSurface(CFDSolver.getTriangulatedMeshSurface())

# Volume constraints
leList = [[0.01, 0, 0.001], [7.51, 0, 13.99]]
teList = [[4.99, 0, 0.001], [8.99, 0, 13.99]]
DVCon.addVolumeConstraint(leList,
                          teList,
                          nSpan=20,
                          nChord=20,
                          lower=1.0,
                          scaled=True)
Ejemplo n.º 8
0
DVGeo = DVGeometry(FFDFile)  # DVGeo = DVGeometry_FFD(FFDFile)
DVGeo.addGeoDVLocal("shape", lower=-0.05, upper=0.05, axis="y", scale=1.0)

span = 1.0
pos = np.array([0.5]) * span
CFDSolver.addSlices("z", pos, sliceType="absolute")

# Add DVGeo object to CFD solver
CFDSolver.setDVGeo(DVGeo)
# rst dvgeo (end)
# ======================================================================
#         DVConstraint Setup
# ======================================================================
# rst dvcon (beg)
DVCon = DVConstraints()  # DVCon = DVConstraints_FFD_data()
DVCon.setDVGeo(DVGeo)

# Only ADflow has the getTriangulatedSurface Function
DVCon.setSurface(CFDSolver.getTriangulatedMeshSurface())

# Le/Te constraints
lIndex = DVGeo.getLocalIndex(0)
indSetA = []
indSetB = []
# print('lIndex.shape[0]',lIndex.shape[0])
for k in range(0, 1):
    indSetA.append(lIndex[0, 0, k])  # all DV for upper and lower should be same but different sign
    indSetB.append(lIndex[0, 1, k])
for k in range(0, 1):
    indSetA.append(lIndex[-1, 0, k])
Ejemplo n.º 9
0
def createFittedWingFFD(surf, surfFormat, outFile, leList, teList, nSpan,
                        nChord, absMargins, relMargins, liftIndex):
    """
    Generates a wing FFD with chordwise points that follow the airfoil geometry.

    Parameters
    ----------
    surf : pyGeo object or list or str
        The surface around which the FFD will be created.
        See the documentation for :meth:`pygeo.DVConstraints.setSurface` for details.

    surfFormat : str
        The surface format.
        See the documentation for :meth:`pygeo.DVConstraints.setSurface` for details.

    outFile : str
        Name of output file written in PLOT3D format.

    leList : list or array
        List or array of points (of size Nx3 where N is at least 2) defining the 'leading edge'.

    teList : list or array
        Same as leList but for the trailing edge.

    nSpan : int or list of int
        Number of spanwise sections in the FFD.
        Use a list of length N-1 to specify the number for each segment defined by leList and teList
        and to precisely match intermediate locations.

    nChord : int
        Number of chordwise points in the FFD.

    absMargins : list of float
        List with 3 items specifying the absolute margins in the [chordwise, spanwise, thickness] directions.
        This is useful for areas where the relative margin is too small, such as the trailing edge or wing tip.
        The total margin is the sum of the absolute and relative margins.

    relMargins : list of float
        List with 3 items specifying the relative margins in the [chordwise, spanwise, thickness] directions.
        Relative margins are applied as a fraction of local chord, wing span, and local thickness.
        The total margin is the sum of the absolute and relative margins.

    liftIndex : int
        Index specifying which direction lift is in (same as the ADflow option).
        Either 2 for the y-axis or 3 for the z-axis.
        This is used to determine the wing's spanwise direction.

    Examples
    --------
    >>> CFDSolver = ADFLOW(options=aeroOptions)
    >>> surf = CFDSolver.getTriangulatedMeshSurface()
    >>> surfFormat = "point-vector"
    >>> outFile = "wing_ffd.xyz"
    >>> nSpan = [4, 4]
    >>> nChord = 8
    >>> relMargins = [0.01, 0.001, 0.01]
    >>> absMargins = [0.05, 0.001, 0.05]
    >>> liftIndex = 3
    >>> createFittedWingFFD(surf, surfFormat, outFile, leList, teList, nSpan, nChord, absMargins, relMargins, liftIndex)

    """

    # Import inside this function to avoid circular imports
    from pygeo import DVConstraints

    # Set the triangulated surface in DVCon
    DVCon = DVConstraints()
    DVCon.setSurface(surf, surfFormat=surfFormat)

    # Get the surface intersections; surfCoords has dimensions [nSpanTotal, nChord, 2, 3]
    surfCoords = DVCon._generateIntersections(leList,
                                              teList,
                                              nSpan,
                                              nChord,
                                              surfaceName="default")

    nSpanTotal = np.sum(nSpan)

    # Initialize FFD coordinates to the surface coordinates
    FFDCoords = surfCoords.copy()

    # Swap axes to get the FFD coordinates into PLOT3D ordering [x, y, z, 3]
    FFDCoords = np.swapaxes(FFDCoords, 0, 1)  # [nChord, nSpanTotal, 2, 3]
    if liftIndex == 2:
        # Swap axes again so that z is the spanwise direction instead of y
        FFDCoords = np.swapaxes(FFDCoords, 1, 2)  # [nChord, 2, nSpanTotal, 3]

    # Assign coordinates and dimensions in each direction

    # x is always the chordwise direction
    leadingEdge = FFDCoords[0, :, :, 0]
    trailingEdge = FFDCoords[-1, :, :, 0]
    Nx = nChord

    # y and z depend on the liftIndex
    if liftIndex == 2:
        root = FFDCoords[:, :, 0, 2]
        tip = FFDCoords[:, :, -1, 2]

        upperSurface = FFDCoords[:, 0, :, 1]
        lowerSurface = FFDCoords[:, 1, :, 1]

        Ny = 2
        Nz = nSpanTotal
    elif liftIndex == 3:
        root = FFDCoords[:, 0, :, 1]
        tip = FFDCoords[:, -1, :, 1]

        upperSurface = FFDCoords[:, :, 1, 2]
        lowerSurface = FFDCoords[:, :, 0, 2]

        Ny = nSpanTotal
        Nz = 2
    else:
        raise ValueError("liftIndex must be 2 (for y-axis) or 3 (for z-axis)")

    # Add margins to FFD coordinates
    chordLength = trailingEdge - leadingEdge
    leadingEdge -= chordLength * relMargins[0] + absMargins[0]
    trailingEdge += chordLength * relMargins[0] + absMargins[0]

    span = np.max(tip - root)
    root -= span * relMargins[1] + absMargins[1]
    tip += span * relMargins[1] + absMargins[1]

    thickness = upperSurface - lowerSurface
    upperSurface += thickness * relMargins[2] + absMargins[2]
    lowerSurface -= thickness * relMargins[2] + absMargins[2]

    # Write FFD file
    f = open(outFile, "w")
    f.write("1\n")
    f.write(f"{Nx} {Ny} {Nz}\n")
    for ell in range(3):
        for k in range(Nz):
            for j in range(Ny):
                for i in range(Nx):
                    f.write("%.15f " % (FFDCoords[i, j, k, ell]))
                f.write("\n")
    f.close()
Ejemplo n.º 10
0
    def initialize(self):
        # Need to modify this dictionary when we change the SA constants
        #import pdb; pdb.set_trace()
        #sys.stdout = open(os.devnull, "w")
        self.aoptions = aeroOptions
        self.woptions = warpOptions
        self.ooptions = optOptions
        self.uoptions = uqOptions

        self.Pr = 0.
        self.P = self.uoptions['P']
        self.NS0 = self.uoptions['NS0']
        # Generate FFD and DVs
        if rank == 0:
            rank0dvg = pf.createFFD()
        else:
            rank0dvg = None
        self.DVGeo = comm.bcast(rank0dvg, root=0)

        # starting flat mesh
        meshname = self.aoptions['gridFile']
        gridFile = meshname

        # flow characteristics
        alpha = 0.0
        mach = self.ooptions['mach']  #0.95
        Re = self.ooptions['Re']  #50000
        Re_L = 1.0
        temp = 540
        arearef = 2.0
        chordref = 1.0

        # Spalart Allmaras model constants, to be changed in UQ (4 for now)
        saconstsm = [0.41, 0.1355, 0.622, 0.66666666667]
        self.saconstsb = [7.1, 0.3, 2.0, 1.0, 2.0, 1.2, 0.5, 2.0]
        self.saconsts = saconstsm + self.saconstsb
        self.aoptions['SAConsts'] = self.saconsts
        #self.gridSol = f'{meshname}_{saconstsm}_sol'
        solname = self.ooptions['prob_name']
        self.gridSol = f'{solname}_sol'

        # Get a set of UQ sample points (LHS)
        #if self.ooptions['run_once']:
        #    self.sample = self.uoptions['dist']
        #else

        # Scatter samples, multi-point parallelism
        if self.uoptions['MCTimeBudget']:
            self.aps = []
            self.solvers = []
            self.meshes = []
            self.current_samples = self.NS0
            if rank == 0:
                rank0sam = plate_sa_lhs.genLHS(s=self.current_samples)
            else:
                rank0sam = None
            self.sample = comm.bcast(rank0sam, root=0)
            self.cases = divide_cases(self.NS0, size)
            # Scatter samples on each level, multi-point parallelism
            self.samplep = self.sample[self.cases[rank]]
            self.nsp = len(self.cases[rank])

            # Create solvers for the preliminary data
            for i in range(self.nsp):
                namestr = self.gridSol + "_" + str(self.cases[rank][i])

                # create meshes
                self.meshes.append(
                    USMesh(options=self.woptions, comm=MPI.COMM_SELF))

                # create aeroproblems
                self.aps.append(
                    AeroProblem(name=namestr,
                                alpha=alpha,
                                mach=mach,
                                reynolds=Re,
                                reynoldsLength=Re_L,
                                T=temp,
                                areaRef=arearef,
                                chordRef=chordref,
                                evalFuncs=['cd']))
                time.sleep(0.1)  # this solves a few problems for some reason
                # create solvers
                self.solvers.append(
                    ADFLOW(options=self.aoptions, comm=MPI.COMM_SELF))

                saconstsm = self.samplep[i].tolist()
                self.saconsts = saconstsm + self.saconstsb
                self.solvers[i].setOption('SAConsts', self.saconsts)
                self.solvers[i].setDVGeo(self.DVGeo)
                self.solvers[i].setMesh(self.meshes[i])
                print("what up %i", str(rank))
                coords = self.solvers[i].getSurfaceCoordinates(
                    groupName=self.solvers[i].allWallsGroup)
                self.solvers[i].DVGeo.addPointSet(coords, 'coords')

            # start looping over mesh levels
            sumt = 0.
            sumtp = 0.
            Et = 0.
            funcs = {}
            a_init = self.DVGeo.getValues()
            a_init['pnts'][:] = self.ooptions['DVInit']
            dvdict = {'pnts': a_init['pnts']}
            for i in range(self.nsp):
                saconstsm = self.samplep[i].tolist()
                self.saconsts = saconstsm + self.saconstsb
                self.solvers[i].setOption('SAConsts', self.saconsts)
                self.solvers[i].DVGeo.setDesignVars(dvdict)
                self.aps[i].setDesignVars(dvdict)
                pc0 = time.process_time()
                self.solvers[i](self.aps[i])
                self.solvers[i].evalFunctions(self.aps[i], funcs)
                pc1 = time.process_time()
                astr = self.gridSol + "_" + str(self.cases[rank][i]) + "_cd"
                sumtp += (pc1 - pc0)

            sumt = comm.allreduce(sumtp)
            Et = sumt / self.NS0
            self.NS = math.ceil(self.P / Et)
            self.Pr = self.NS * Et
        else:
            self.NS = self.uoptions['NS']

        #import pdb; pdb.set_trace()

        if rank == 0:
            rank0sam = plate_sa_lhs.genLHS(s=self.NS)
        else:
            rank0sam = None
        self.sample = comm.bcast(rank0sam, root=0)

        self.cases = divide_cases(self.NS, size)
        self.nsp = len(self.cases[rank])  #int(ns/size) # samples per processor
        #import pdb; pdb.set_trace()
        self.samplep = self.sample[self.cases[
            rank]]  #self.sample[(rank*self.nsp):(rank*self.nsp+(self.nsp))] #shouldn't really need to "scatter" per se
        #import pdb; pdb.set_trace()
        #assert len(self.samplep) == self.nsp

        # Actually create solvers (and aeroproblems?) (and mesh?) now
        self.aps = []
        self.solvers = []
        self.meshes = []

        #self.mesh = USMesh(options=self.woptions, comm=MPI.COMM_SELF)
        for i in range(self.nsp):
            namestr = self.gridSol + "_" + str(self.cases[rank][i])

            # create meshes
            self.meshes.append(
                USMesh(options=self.woptions, comm=MPI.COMM_SELF))

            # create aeroproblems
            self.aps.append(
                AeroProblem(name=namestr,
                            alpha=alpha,
                            mach=mach,
                            reynolds=Re,
                            reynoldsLength=Re_L,
                            T=temp,
                            areaRef=arearef,
                            chordRef=chordref,
                            evalFuncs=['cd']))
            time.sleep(0.1)  # this solves a few problems for some reason
            # create solvers
            self.solvers.append(
                ADFLOW(options=self.aoptions, comm=MPI.COMM_SELF))
            # if not self.ooptions['run_once']:
            # saconstsm = self.samplep[i].tolist()
            # else:
            saconstsm = self.samplep[i].tolist()
            self.saconsts = saconstsm + self.saconstsb
            self.solvers[i].setOption('SAConsts', self.saconsts)
            self.solvers[i].setDVGeo(self.DVGeo)
            self.solvers[i].setMesh(self.meshes[i])
            print("what up %i", str(rank))
            coords = self.solvers[i].getSurfaceCoordinates(
                groupName=self.solvers[i].allWallsGroup)
            self.solvers[i].DVGeo.addPointSet(coords, 'coords')

        # Set constraints, should only need one of those solvers, the meshes are all the same
        self.DVCon = DVConstraints()
        self.DVCon2 = DVConstraints()
        self.DVCon.setDVGeo(self.solvers[0].DVGeo.getFlattenedChildren()[1])
        self.DVCon2.setDVGeo(self.solvers[0].DVGeo)

        self.DVCon.setSurface(self.solvers[0].getTriangulatedMeshSurface(
            groupName='allSurfaces'))
        # set extra group for surface area condition
        self.DVCon2.setSurface(self.solvers[0].getTriangulatedMeshSurface(),
                               name='wall')

        # DV should be same into page (not doing anything right now)
        #import pdb; pdb.set_trace()
        lIndex = self.solvers[0].DVGeo.getFlattenedChildren()[1].getLocalIndex(
            0)
        indSetA = []
        indSetB = []
        nXc = optOptions['NX']
        self.NC = math.trunc(
            ((1.0 - self.ooptions['DVFraction']) * self.ooptions['NX']))
        ind = [
            int(nXc / 2) - int(self.NC / 2),
            int(nXc / 2) + int(self.NC / 2)
        ]
        for i in range(ind[0], ind[1]):
            indSetA.append(lIndex[i, 0, 1])
            indSetB.append(lIndex[i, 1, 1])
        # for i in range(lIndex.shape[0]):
        #     indSetA.append(lIndex[i, 0, 1])
        #     indSetB.append(lIndex[i, 1, 1])
        self.DVCon.addLinearConstraintsShape(indSetA,
                                             indSetB,
                                             factorA=1.0,
                                             factorB=-1.0,
                                             lower=0,
                                             upper=0,
                                             name='eqs')

        # Thickness constraints (one for each active DV)
        #import pdb; pdb.set_trace()

        # Maximum thickness of the domain, translates to minimum thickness of bump
        ub = 1.0 - self.ooptions['DCMinThick']
        tcf = self.ooptions['DCThickFrac']
        ra = self.ooptions['bumpBounds']
        lim = self.ooptions['DCMinArea']
        span = numpy.linspace(0, 1, nXc)
        xc = span * (ra[1] - ra[0]) + ra[0]
        #ind = range(int(nXc/2) - int(self.NC/2), int(nXc/2) + int(self.NC/2)))
        ind = [
            int(nXc / 2) - int(tcf * self.NC / 2),
            int(nXc / 2) + int(tcf * self.NC / 2)
        ]
        ptList = numpy.zeros([2, 3])
        ptList[:, 0] = xc[ind]
        ptList[:, 1] = 0.5
        ptList[:, 2] = 0.5

        if self.ooptions['use_area_con']:
            self.DVCon2.addSurfaceAreaConstraint(lower=lim,
                                                 upper=10.,
                                                 name='sas',
                                                 surfaceName='wall')
        else:
            self.DVCon2.addThicknessConstraints1D(ptList,
                                                  self.NC, [0, 0, 1],
                                                  lower=0.5,
                                                  upper=ub,
                                                  name='tcs')

        print("excuse me")
        dummy = rank
        dsum = comm.allgather(dummy)

        sys.stdout = sys.__stdout__
Ejemplo n.º 11
0
    def initialize(self):
        # Need to modify this dictionary when we change the SA constants
        #import pdb; pdb.set_trace()
        #sys.stdout = open(os.devnull, "w")
        self.aoptions = aeroOptions
        self.woptions = warpOptions
        self.ooptions = optOptions
        self.uoptions = uqOptions

        self.Pr = 0.
        # Generate FFD and DVs
        if rank == 0:
            rank0dvg = pf.createFFD()
        else:
            rank0dvg = None
        self.DVGeo = comm.bcast(rank0dvg, root=0)

        # Get a full list of every mesh name we have, assume they are ordered properly by level
        self.meshnames = self.uoptions['gridFileLevels']
        self.Lmax = len(self.meshnames)  #as many levels as we have meshes
        self.mord = [*range(self.Lmax)]
        self.mord.reverse()

        if self.Lmax < 3:
            raise ValueError('Not enough meshes available, ' + self.Lmax +
                             ' < 3')

        # Spalart Allmaras model constants, to be changed in UQ (4 for now)
        saconstsm = [0.41, 0.1355, 0.622, 0.66666666667]
        self.saconstsb = [7.1, 0.3, 2.0, 1.0, 2.0, 1.2, 0.5, 2.0]
        self.saconsts = saconstsm + self.saconstsb
        self.aoptions['SAConsts'] = self.saconsts
        #self.gridSol = f'{meshname}_{saconstsm}_sol'
        solname = self.ooptions['prob_name']
        self.gridSol = f'{solname}_sol'

        self.cases = []
        #self.nsp = []   #keep track per level
        self.samplep = []
        self.naddedtot = []
        for i in range(self.Lmax):
            self.naddedtot.append(0)

        self.aps = []
        self.solvers = []
        self.meshes = []

        self.NS0 = self.uoptions['NS0']
        self.current_samples = self.NS0 * self.Lmax
        self.N1 = None
        self.a1 = None
        self.P = self.uoptions['P']
        ##########
        # call distribute samples here?
        if not self.uoptions['use-predetermined-samples']:
            self.MFMC()
        else:
            self.N1 = self.uoptions['predet-N1']
            self.a1 = self.uoptions['predet-a1']

        self.dist_samples()

        ##########

        # Set constraints, should only need one of those solvers, the meshes are all the same
        if rank == 0:
            self.DVCon = DVConstraints()
            self.DVCon2 = DVConstraints()
            self.DVCon.setDVGeo(
                self.solvers[0][0].DVGeo.getFlattenedChildren()[1])
            self.DVCon2.setDVGeo(self.solvers[0][0].DVGeo)

            self.DVCon.setSurface(
                self.solvers[0][0].getTriangulatedMeshSurface(
                    groupName='allSurfaces'))
            # set extra group for surface area condition
            self.DVCon2.setSurface(
                self.solvers[0][0].getTriangulatedMeshSurface(), name='wall')

            # DV should be same into page (not doing anything right now)
            #import pdb; pdb.set_trace()
            lIndex = self.solvers[0][0].DVGeo.getFlattenedChildren(
            )[1].getLocalIndex(0)
            indSetA = []
            indSetB = []
            nXc = optOptions['NX']
            self.NC = math.trunc(
                ((1.0 - self.ooptions['DVFraction']) * self.ooptions['NX']))
            ind = [
                int(nXc / 2) - int(self.NC / 2),
                int(nXc / 2) + int(self.NC / 2)
            ]
            for i in range(ind[0], ind[1]):
                indSetA.append(lIndex[i, 0, 1])
                indSetB.append(lIndex[i, 1, 1])
            # for i in range(lIndex.shape[0]):
            #     indSetA.append(lIndex[i, 0, 1])
            #     indSetB.append(lIndex[i, 1, 1])
            self.DVCon.addLinearConstraintsShape(indSetA,
                                                 indSetB,
                                                 factorA=1.0,
                                                 factorB=-1.0,
                                                 lower=0,
                                                 upper=0,
                                                 name='eqs')

            # Thickness constraints (one for each active DV)
            #import pdb; pdb.set_trace()

            # Maximum thickness of the domain, translates to minimum thickness of bump
            ub = 1.0 - self.ooptions['DCMinThick']
            tcf = self.ooptions['DCThickFrac']
            ra = self.ooptions['bumpBounds']
            lim = self.ooptions['DCMinArea']
            span = numpy.linspace(0, 1, nXc)
            xc = span * (ra[1] - ra[0]) + ra[0]
            #ind = range(int(nXc/2) - int(self.NC/2), int(nXc/2) + int(self.NC/2)))
            ind = [
                int(nXc / 2) - int(tcf * self.NC / 2),
                int(nXc / 2) + int(tcf * self.NC / 2)
            ]
            ptList = numpy.zeros([2, 3])
            ptList[:, 0] = xc[ind]
            ptList[:, 1] = 0.5
            ptList[:, 2] = 0.5

            if self.ooptions['use_area_con']:
                self.DVCon2.addSurfaceAreaConstraint(lower=lim,
                                                     upper=10.,
                                                     name='sas',
                                                     surfaceName='wall')
            else:
                self.DVCon2.addThicknessConstraints1D(ptList,
                                                      self.NC, [0, 0, 1],
                                                      lower=0.5,
                                                      upper=ub,
                                                      name='tcs')

        dummy = rank
        dsum = comm.allgather(dummy)

        sys.stdout = sys.__stdout__
Ejemplo n.º 12
0
    def test_triangulatedSurface_intersected_2DVGeos(self, train=False, refDeriv=False):
        refFile = os.path.join(self.base_path, "ref/test_DVConstraints_triangulatedSurface_intersected_2DVGeos.ref")
        with BaseRegTest(refFile, train=train) as handler:
            meshFile = os.path.join(self.base_path, "../../input_files/bwb.stl")
            objFile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl")
            ffdFile = os.path.join(self.base_path, "../../input_files/bwb.xyz")
            testMesh = mesh.Mesh.from_file(meshFile)
            testObj = mesh.Mesh.from_file(objFile)
            # test mesh dim 0 is triangle index
            # dim 1 is each vertex of the triangle
            # dim 2 is x, y, z dimension

            # create a DVGeo object with a few local thickness variables
            DVGeo1 = DVGeometry(ffdFile)
            nRefAxPts = DVGeo1.addRefAxis("wing", xFraction=0.25, alignIndex="k")
            self.nTwist = nRefAxPts - 1

            def twist(val, geo):
                for i in range(1, nRefAxPts):
                    geo.rot_z["wing"].coef[i] = val[i - 1]

            DVGeo1.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1)
            DVGeo1.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1)

            # create a DVGeo object with a few local thickness variables
            DVGeo2 = DVGeometry(ffdFile, name="blobdvgeo")
            DVGeo2.addLocalDV("local_2", lower=-0.5, upper=0.5, axis="y", scale=1)

            # check that DVGeos with duplicate var names are not allowed
            DVGeo3 = DVGeometry(ffdFile)
            DVGeo3.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1)

            # create a DVConstraints object for the wing
            DVCon = DVConstraints()
            DVCon.setDVGeo(DVGeo1)
            DVCon.setDVGeo(DVGeo2, name="second")
            with self.assertRaises(ValueError):
                DVCon.setDVGeo(DVGeo3, name="third")

            p0 = testMesh.vectors[:, 0, :]
            v1 = testMesh.vectors[:, 1, :] - p0
            v2 = testMesh.vectors[:, 2, :] - p0
            DVCon.setSurface([p0, v1, v2], addToDVGeo=True)
            p0b = testObj.vectors[:, 0, :]
            v1b = testObj.vectors[:, 1, :] - p0b
            v2b = testObj.vectors[:, 2, :] - p0b
            p0b = p0b + np.array([0.0, 0.3, 0.0])
            DVCon.setSurface([p0b, v1b, v2b], name="blob", addToDVGeo=True, DVGeoName="second")

            DVCon.addTriangulatedSurfaceConstraint("default", "default", "blob", "second", rho=10.0, addToPyOpt=True)

            funcs = {}
            DVCon.evalFunctions(funcs, includeLinear=True)
            handler.root_add_dict("funcs_base", funcs, rtol=1e-6, atol=1e-6)
            funcsSens = {}
            DVCon.evalFunctionsSens(funcsSens, includeLinear=True)
            # regress the derivatives
            handler.root_add_dict("derivs_base", funcsSens, rtol=1e-6, atol=1e-6)

            # FD check DVGeo1
            funcsSensFD = evalFunctionsSensFD(DVGeo1, DVCon, fdstep=1e-3)
            at_least_one_var = False
            for outkey in funcs.keys():
                for inkey in DVGeo1.getValues().keys():
                    analytic = funcsSens[outkey][inkey]
                    fd = funcsSensFD[outkey][inkey]
                    handler.assert_allclose(analytic, fd, name="finite_diff_check", rtol=1e-3, atol=1e-3)
                    # make sure there are actually checks happening
                    self.assertTrue(np.abs(np.sum(fd)) > 1e-10)
                    at_least_one_var = True
            self.assertTrue(at_least_one_var)

            # FD check DVGeo2
            funcsSensFD = evalFunctionsSensFD(DVGeo2, DVCon, fdstep=1e-3)
            at_least_one_var = False
            for outkey in funcs.keys():
                for inkey in DVGeo2.getValues().keys():
                    analytic = funcsSens[outkey][inkey]
                    fd = funcsSensFD[outkey][inkey]
                    handler.assert_allclose(analytic, fd, name="finite_diff_check", rtol=1e-3, atol=1e-3)
                    self.assertTrue(np.abs(np.sum(fd)) > 1e-10)
                    at_least_one_var = True
            self.assertTrue(at_least_one_var)
Ejemplo n.º 13
0
    def generate_dvgeo_dvcon(self, geometry, addToDVGeo=False, intersected=False):
        """
        This function creates the DVGeometry and DVConstraints objects for each geometry used in this class.

        The C172 wing represents a typical use case with twist and shape variables.

        The rectangular box is primarily used to test unscaled constraint function
        values against known values for thickness, volume, and surface area.

        The BWB is used for the triangulated surface and volume constraint tests.

        The RAE 2822 wing is used for the curvature constraint test.
        """

        if geometry == "c172":
            meshFile = os.path.join(self.base_path, "../../input_files/c172.stl")
            ffdFile = os.path.join(self.base_path, "../../input_files/c172.xyz")
            xFraction = 0.25
            meshScale = 1e-3
        elif geometry == "box":
            meshFile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.stl")
            ffdFile = os.path.join(self.base_path, "../../input_files/2x1x8_rectangle.xyz")
            xFraction = 0.5
            meshScale = 1
        elif geometry == "bwb":
            meshFile = os.path.join(self.base_path, "../../input_files/bwb.stl")
            ffdFile = os.path.join(self.base_path, "../../input_files/bwb.xyz")
            xFraction = 0.25
            meshScale = 1
        elif geometry == "rae2822":
            ffdFile = os.path.join(self.base_path, "../../input_files/deform_geometry_ffd.xyz")
            xFraction = 0.25

        DVGeo = DVGeometry(ffdFile, child=self.child)
        DVCon = DVConstraints()
        nRefAxPts = DVGeo.addRefAxis("wing", xFraction=xFraction, alignIndex="k")
        self.nTwist = nRefAxPts - 1

        if self.child:
            parentFFD = os.path.join(self.base_path, "../../input_files/parent.xyz")
            self.parentDVGeo = DVGeometry(parentFFD)
            self.parentDVGeo.addChild(DVGeo)
            DVCon.setDVGeo(self.parentDVGeo)
        else:
            DVCon.setDVGeo(DVGeo)

        # Add design variables
        def twist(val, geo):
            for i in range(1, nRefAxPts):
                geo.rot_z["wing"].coef[i] = val[i - 1]

        DVGeo.addGlobalDV(dvName="twist", value=[0] * self.nTwist, func=twist, lower=-10, upper=10, scale=1)
        DVGeo.addLocalDV("local", lower=-0.5, upper=0.5, axis="y", scale=1)

        # RAE 2822 does not have a DVCon surface so we just return
        if geometry == "rae2822":
            return DVGeo, DVCon

        # Get the mesh from the STL
        testMesh = mesh.Mesh.from_file(meshFile)
        # dim 0 is triangle index
        # dim 1 is each vertex of the triangle
        # dim 2 is x, y, z dimension

        p0 = testMesh.vectors[:, 0, :] * meshScale
        v1 = testMesh.vectors[:, 1, :] * meshScale - p0
        v2 = testMesh.vectors[:, 2, :] * meshScale - p0
        DVCon.setSurface([p0, v1, v2], addToDVGeo=addToDVGeo)

        # Add the blob surface for the BWB
        if geometry == "bwb":
            objFile = os.path.join(self.base_path, "../../input_files/blob_bwb_wing.stl")
            testObj = mesh.Mesh.from_file(objFile)
            p0b = testObj.vectors[:, 0, :]
            v1b = testObj.vectors[:, 1, :] - p0b
            v2b = testObj.vectors[:, 2, :] - p0b
            if intersected:
                p0b = p0b + np.array([0.0, 0.3, 0.0])
            DVCon.setSurface([p0b, v1b, v2b], name="blob")

        return DVGeo, DVCon
Ejemplo n.º 14
0
                          upper=0.05,
                          axis='y',
                          scale=10)

DVGeo_back.addGeoDVLocal('local_back',
                         lower=-0.05,
                         upper=0.05,
                         axis='y',
                         scale=10)

# Add DVGeo object to CFD solver
CFDSolver.setDVGeo(DVGeo_GLOBAL)

#rst dvs

DVCon = DVConstraints(name='con')
DVCon.setDVGeo(DVGeo_GLOBAL)

# Only ADflow has the getTriangulatedSurface Function
DVCon.setSurface(CFDSolver.getTriangulatedMeshSurface())

# Volume constraints
# For the front wing
leList_front = [[0.01, 0, 0.001], [0.01, 0, 0.639]]
teList_front = [[0.239, 0, 0.001], [0.239, 0, 0.639]]
DVCon.addVolumeConstraint(leList_front, teList_front, 20, 20, lower=1.0)

# For the back wing
delta_x = 1.
delta_y = 0.5
Ejemplo n.º 15
0
    def initialize(self):
        # Need to modify this dictionary when we change the SA constants
        sys.stdout = open(os.devnull, "w")
        self.aoptions = aeroOptions
        self.woptions = warpOptions
        self.ooptions = optOptions

        # Generate FFD and DVs
        self.DVGeo = pf.createFFD()

        # starting flat mesh
        meshname = self.aoptions['gridFile']
        gridFile = meshname
        
        # flow characteristics
        alpha = 0.0
        mach = self.ooptions['mach']#0.95
        Re = self.ooptions['Re']#50000
        Re_L = 1.0
        temp = 540
        arearef = 2.0
        chordref = 1.0

        # Spalart Allmaras model constants, to be changed in UQ
        saconstsm = [0.41, 0.1355, 0.622, 0.66666666667, 7.1, 0.3, 2.0]
        self.saconsts = saconstsm + [1.0, 2.0, 1.2, 0.5, 2.0]
        self.aoptions['SAConsts'] = self.saconsts
        #self.gridSol = f'{meshname}_{saconstsm}_sol'
        solname = self.ooptions['prob_name']
        self.gridSol = f'{solname}_sol'

        # Aerodynamic problem description
        self.ap = AeroProblem(name=self.gridSol, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=temp, areaRef=arearef, chordRef=chordref, 
        evalFuncs=['cd'])

        # Create solver
        self.CFDSolver = ADFLOW(options=self.aoptions, comm=MPI.COMM_WORLD)
        self.CFDSolver.setDVGeo(self.DVGeo)

        # Set up mesh warping
        self.mesh = USMesh(options=self.woptions, comm=MPI.COMM_WORLD)
        self.CFDSolver.setMesh(self.mesh)

        # Try setting the DVGeo coordinates here
        coords = self.CFDSolver.getSurfaceCoordinates(groupName=self.CFDSolver.allWallsGroup)
        self.CFDSolver.DVGeo.addPointSet(coords, 'coords')
        self.CFDSolver.DVGeo.getFlattenedChildren()[1].writePlot3d("ffdp_opt_def.xyz")


        # Set constraints
        self.DVCon = DVConstraints()
        self.DVCon2 = DVConstraints()
        self.DVCon.setDVGeo(self.CFDSolver.DVGeo.getFlattenedChildren()[1])
        self.DVCon2.setDVGeo(self.CFDSolver.DVGeo)

        self.DVCon.setSurface(self.CFDSolver.getTriangulatedMeshSurface(groupName='allSurfaces'))
        # set extra group for surface area condition
        self.DVCon2.setSurface(self.CFDSolver.getTriangulatedMeshSurface(), name='wall')

        # DV should be same into page (not doing anything right now)
        #import pdb; pdb.set_trace()
        lIndex = self.CFDSolver.DVGeo.getFlattenedChildren()[1].getLocalIndex(0)
        indSetA = []
        indSetB = []
        nXc = optOptions['NX']
        self.NC = math.trunc(((1.0 - self.ooptions['DVFraction'])*self.ooptions['NX']))
        ind = [int(nXc/2) - int(self.NC/2), int(nXc/2) + int(self.NC/2)]
        for i in range(ind[0], ind[1]):
            indSetA.append(lIndex[i, 0, 1])
            indSetB.append(lIndex[i, 1, 1])
        # for i in range(lIndex.shape[0]):
        #     indSetA.append(lIndex[i, 0, 1])
        #     indSetB.append(lIndex[i, 1, 1])
        self.DVCon.addLinearConstraintsShape(indSetA, indSetB, factorA=1.0, factorB=-1.0, lower=0, upper=0, name='eqs')

        # Thickness constraints (one for each active DV)
        #import pdb; pdb.set_trace()

        # Maximum thickness of the domain, translates to minimum thickness of bump
        ub = 1.0 - self.ooptions['DCMinThick']
        tcf = self.ooptions['DCThickFrac']
        ra = self.ooptions['bumpBounds']
        lim = self.ooptions['DCMinArea']
        span = numpy.linspace(0, 1, nXc)
        xc = span * (ra[1] - ra[0]) + ra[0]
        #ind = range(int(nXc/2) - int(self.NC/2), int(nXc/2) + int(self.NC/2)))
        ind = [int(nXc/2) - int(tcf*self.NC/2), int(nXc/2) + int(tcf*self.NC/2)]
        ptList = numpy.zeros([2, 3])
        ptList[:,0] = xc[ind]
        ptList[:,1] = 0.5
        ptList[:,2] = 0.5

        if self.ooptions['use_area_con']:
            self.DVCon2.addSurfaceAreaConstraint(lower=lim, upper=10., name='sas', surfaceName='wall')
        else:
            self.DVCon2.addThicknessConstraints1D(ptList, self.NC, [0,0,1], lower=0.5, upper=ub, name='tcs')

        sys.stdout = sys.__stdout__