Пример #1
0
class TestSolve(reg_test_classes.RegTest):
    """
    Tests that ADflow can change the dvs to achieve the target cl to the given tolerance.

    Compares the norm of the residuals, norm of states, and the functionals.

    based on the old regression test 10

    """

    N_PROCS = 2
    ref_file = "solve_cl.json"

    def setUp(self):
        super().setUp()
        gridFile = os.path.join(
            baseDir, "../../input_files/mdo_tutorial_euler_scalar_jst.cgns")
        options = copy.copy(adflowDefOpts)
        options["outputdirectory"] = os.path.join(baseDir,
                                                  options["outputdirectory"])
        options.update({
            "gridfile": gridFile,
            "solutionprecision": "double",
            "gridprecision": "double",
            "mgcycle": "2w",
            "ncyclescoarse": 250,
            "ncycles": 500,
            "usenksolver": True,
            "nkswitchtol": 1e-2,
            "l2convergence": 1e-14,
            "l2convergencecoarse": 1e-2,
        })

        # Setup aeroproblem
        self.ap = copy.copy(ap_tutorial_wing)

        # Create the solver
        self.CFDSolver = ADFLOW(options=options, debug=False)

    def test_solve(self):

        self.CFDSolver.solveCL(self.ap,
                               0.475,
                               alpha0=1.20,
                               delta=0.025,
                               tol=1e-4,
                               autoReset=False)
        self.assert_solution_failure()
        funcs = {}
        self.CFDSolver.evalFunctions(self.ap, funcs, evalFuncs=["cl"])
        self.handler.root_add_val("CL-CL*",
                                  funcs["mdo_tutorial_cl"] - 0.475,
                                  rtol=1e-4,
                                  atol=1e-4)
Пример #2
0
}

# Create solver
CFDSolver = ADFLOW(options=aeroOptions)

# Add features
#CFDSolver.addLiftDistribution(150, 'z')
#CFDSolver.addSlices('z', numpy.linspace(0.1, 14, 10))

name = 'Re{}_M{}_AoA{}_{}'.format(reynolds, mach, alpha, level)
ap = AeroProblem(name=name,
                 alpha=alpha,
                 mach=mach,
                 reynolds=reynolds,
                 reynoldsLength=0.64607,
                 T=T,
                 areaRef=0.75296,
                 chordRef=0.64607,
                 evalFuncs=['cl', 'cd', 'cmz'])

# Solve the flow
CFDSolver(ap)

# Evaluate functions
funcs = {}
CFDSolver.evalFunctions(ap, funcs)

if MPI.COMM_WORLD.rank == 0:
    print("CL: {}, CD: {}, CM: {}".format(funcs[name + '_cl'],
                                          funcs[name + '_cd'],
                                          -funcs[name + '_cmz']))
Пример #3
0
class PlateComponent(om.ExplicitComponent):
    """Deterministic Bump Flow Problem"""
    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__

    def setup(self):
        #initialize shape and set deformation points as inputs
        a_init = self.CFDSolver.DVGeo.getValues()
        a_init['pnts'][:] = self.ooptions['DVInit']
        # mult = numpy.linspace(1.0,1.5,num=int(0.5*len(a_init['pnts'])))
        # mult = numpy.concatenate((mult, mult))
        # a_init['pnts'] = numpy.multiply(mult, a_init['pnts'])
        #if self.ooptions['run_once']:
        #    a_init['pnts'] = self.ooptions['ro_shape']
        self.add_input('a', a_init['pnts'], desc="Bump Shape Control Points")
        #self.add_input('a', 0.2, desc="Bump Shape Control Points")

        if self.ooptions['use_area_con']:
            self.add_output('SA', 1.0, desc='Surface Area Constraint')
        else:
            self.add_output('TC', numpy.zeros(self.NC), desc='Thickness Constraints')
        self.add_output('Cd', 0.0, desc="Drag Coefficient")
        self.add_output('EQ', numpy.zeros(int(len(a_init['pnts'])/2)), desc="Control Point Symmetry")


    
    def setup_partials(self):
        self.declare_partials('Cd','a', method='exact')
        if self.ooptions['use_area_con']:
            self.declare_partials('SA','a', method='exact')
        else:
            self.declare_partials('TC','a', method='exact')
        self.declare_partials('EQ','a', method='exact')
    
    def compute(self, inputs, outputs):
        # run the bump shape model

        # move the mesh
        #import pdb; pdb.set_trace()
        dvdict = {'pnts':inputs['a']}
        self.CFDSolver.DVGeo.setDesignVars(dvdict)
        self.ap.setDesignVars(dvdict)

        #self.CFDSolver.DVGeo.update("coords")

        # Solve and evaluate functions
        funcs = {}
        self.CFDSolver(self.ap)
        self.DVCon.evalFunctions(funcs, includeLinear=True)
        self.DVCon2.evalFunctions(funcs, includeLinear=True)
        self.CFDSolver.evalFunctions(self.ap, funcs)

        str = self.gridSol + '_cd'
        outputs['Cd'] = funcs[str]
        if self.ooptions['use_area_con']:
            outputs['SA'] = funcs['sas']
        else:
            outputs['TC'] = funcs['tcs']
        
        outputs['EQ'] = funcs['eqs']

        #outputs['Cd'] = inputs['a']*inputs['a']

    def compute_partials(self, inputs, J):

        # move the mesh
        #import pdb; pdb.set_trace()
        dvdict = {'pnts':inputs['a']}
        self.CFDSolver.DVGeo.setDesignVars(dvdict)
        self.ap.setDesignVars(dvdict)
        #self.CFDSolver.DVGeo.update("coords")
 
 
        funcSens = {}
        #self.CFDSolver(self.ap) #ASSUME WE ALREADY COMPUTED THE SOLUTION
        self.DVCon.evalFunctionsSens(funcSens, includeLinear=True)
        self.DVCon2.evalFunctionsSens(funcSens, includeLinear=True)
        self.CFDSolver.evalFunctionsSens(self.ap, funcSens, ['cd'])
 
        str = self.gridSol + '_cd'
        J['Cd','a'] = funcSens[str]['pnts']
        if self.ooptions['use_area_con']:
            J['SA','a'] = funcSens['sas']['pnts']
        else:
            J['TC','a'] = funcSens['tcs']['pnts']
        J['EQ','a'] = funcSens['eqs']['pnts']