# NK Solver Parameters 'useNKSolver': True, 'nkswitchtol': 1e-6, # Termination Criteria 'L2Convergence': 1e-10, 'L2ConvergenceCoarse': 1e-2, 'nCycles': 10000, # Adjoint Parameters 'adjointL2Convergence': 1e-10, } # Create solver CFDSolver = ADFLOW(options=aeroOptions, comm=comm) # Save the lift distribution for the front wing CFDSolver.addLiftDistribution(200, 'z', groupName='wing_front') # Save the lift distribution for the back wing CFDSolver.addLiftDistribution(200, 'z', groupName='wing_back') # Save the total lift distribution CFDSolver.addLiftDistribution(200, 'z') ap = AeroProblem(name='fc', mach=0.3, altitude=1000, areaRef=0.64 * 0.24 * 2, alpha=3., chordRef=0.24, evalFuncs=['cl', 'cd'])
'outerPreconIts': 3, 'NKSubSpaceSize': 400, 'NKASMOverlap': 4, 'NKPCILUFill': 4, 'NKJacobianLag': 5, 'nkswitchtol': 1e-6, 'nkouterpreconits': 3, 'NKInnerPreConIts': 3, 'writeSurfaceSolution': False, 'writeVolumeSolution': False, 'frozenTurbulence': False, 'restartADjoint': False, } # Create solver CFDSolver = ADFLOW(options=aeroOptions, comm=comm) CFDSolver.addLiftDistribution(200, 'z') #rst adflow (end) # ====================================================================== # Set up flow conditions with AeroProblem # ====================================================================== #rst aeroproblem (beg) ap = AeroProblem(name='fc', alpha=alpha, mach=mach, altitude=alt, areaRef=1.0, chordRef=1.0, evalFuncs=['cl', 'cd']) # Add angle of attack variable ap.addDV('alpha', value=alpha, lower=0, upper=10.0, scale=1.0)
'ANKCoupledSwitchTol': 1e-5, 'ANKConstCFLStep': 0.4, 'ANKCFLLimit': 1000000000.0, 'L2Convergence': 1e-13, # Output 'volumeVariables': ['eddy', 'eddyratio', 'dist'] } # Aerodynamic problem description ap = AeroProblem(name=gridSol, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=temp, areaRef=arearef, chordRef=chordref, evalFuncs=['cd']) # Create solver CFDSolver = ADFLOW(options=aeroOptions) # Solve and evaluate functions funcs = {} CFDSolver(ap) CFDSolver.evalFunctions(ap, funcs) # Print the evaluated functions if MPI.COMM_WORLD.rank == 0: print(funcs)
# Solver Parameters "smoother": "dadi", "MGCycle": "sg", # ANK Solver Parameters "useANKSolver": True, # NK Solver Parameters "useNKSolver": True, "nkswitchtol": 1e-4, # Termination Criteria "L2Convergence": 1e-6, "L2ConvergenceCoarse": 1e-2, "nCycles": 1000, } # rst Start ADflow # Create solver CFDSolver = ADFLOW(options=aeroOptions) # Add features CFDSolver.addLiftDistribution(150, "z") CFDSolver.addSlices("z", np.linspace(0.1, 14, 10)) # rst Create AeroProblem ap = AeroProblem(name="wing", mach=0.8, altitude=10000, alpha=1.5, areaRef=45.5, chordRef=3.25, evalFuncs=["cl", "cd"]) # rst Run ADflow # Solve
if not args.outfile: # Construct a default pth = os.path.dirname(args.grid) nme = os.path.basename(args.grid) outName = "lbAnalysis_{0}_{1}.log".format( os.path.splitext(nme)[0], args.mgCycle) outName = os.path.join(pth, outName) # Define problem aeroOptions = { "gridFile": args.grid, "mgcycle": args.mgCycle, "partitionOnly": True } CFDSolver = ADFLOW(options=aeroOptions) # Write results loadImbalance = [] faceImbalance = [] fd = open(outName, "w") fd.write(72 * "=" + "\n") fd.write("Load imbalance analysis for mesh {0}\n\n".format(args.grid)) fd.write("Multigrid cycle set to {0}\n\n".format(args.mgCycle)) for i in rge: lIb, fIb = CFDSolver.checkPartitioning(i) loadImbalance.append(lIb) faceImbalance.append(fIb) fd.write(
def setUp(self): super().setUp() self.ap = copy.copy(ap_conic_conv_nozzle) options = copy.copy(adflowDefOpts) options.update(self.options) # Setup aeroproblem planeFile = os.path.join( baseDir, "../../inputFiles/integration_plane_viscous.fmt") options = copy.copy(adflowDefOpts) options.update(self.options) # Setup aeroproblem self.ap.evalFuncs.extend([ "mdot_plane", "mavgptot_plane", "aavgptot_plane", "mavgttot_plane", "mavgps_plane", "aavgps_plane" ]) # Create the solver self.CFDSolver = ADFLOW(options=options, debug=False) self.CFDSolver.addIntegrationSurface(planeFile, "viscous_plane") self.CFDSolver.finalizeUserIntegrationSurfaces() self.CFDSolver.addFamilyGroup("upstream", ["inlet"]) self.CFDSolver.addFamilyGroup("downstream", ["outlet"]) self.CFDSolver.addFamilyGroup("all_flow", ["inlet", "outlet"]) self.CFDSolver.addFamilyGroup("output_fam", ["all_flow", "allWalls"]) self.CFDSolver.addFunction("mdot", "upstream", name="mdot_up") self.CFDSolver.addFunction("mdot", "downstream", name="mdot_down") self.CFDSolver.addFunction("mdot", "viscous_plane", name="mdot_plane") self.CFDSolver.addFunction("mavgptot", "downstream", name="mavgptot_down") self.CFDSolver.addFunction("mavgptot", "upstream", name="mavgptot_up") self.CFDSolver.addFunction("mavgptot", "viscous_plane", name="mavgptot_plane") self.CFDSolver.addFunction("aavgptot", "downstream", name="aavgptot_down") self.CFDSolver.addFunction("aavgptot", "upstream", name="aavgptot_up") self.CFDSolver.addFunction("aavgptot", "viscous_plane", name="aavgptot_plane") self.CFDSolver.addFunction("mavgttot", "downstream", name="mavgttot_down") self.CFDSolver.addFunction("mavgttot", "upstream", name="mavgttot_up") self.CFDSolver.addFunction("mavgttot", "viscous_plane", name="mavgttot_plane") self.CFDSolver.addFunction("mavgps", "downstream", name="mavgps_down") self.CFDSolver.addFunction("mavgps", "upstream", name="mavgps_up") self.CFDSolver.addFunction("mavgps", "viscous_plane", name="mavgps_plane") self.CFDSolver.addFunction("aavgps", "downstream", name="aavgps_down") self.CFDSolver.addFunction("aavgps", "upstream", name="aavgps_up") self.CFDSolver.addFunction("aavgps", "viscous_plane", name="aavgps_plane")
class TestSolveIntegrationPlane(reg_test_classes.RegTest): """ Tests that ADflow can converge the wing from the mdo tutorial using the euler equation to the required accuracy as meassure by the norm of the residuals, and states, and the accuracy of the functions based on the old regression test Test 9: MDO tutorial -- Euler -- Solution Test """ N_PROCS = 2 options = { "gridfile": os.path.join(baseDir, "../../inputFiles/conic_conv_nozzle_mb.cgns"), "outputdirectory": os.path.join(baseDir, "../output_files"), # Physics Parameters "equationType": "euler", "smoother": "dadi", "nsubiter": 3, "CFL": 4.0, "CFLCoarse": 1.25, "MGCycle": "3w", "MGStartLevel": -1, "nCyclesCoarse": 250, "nCycles": 1000, "nkcfl0": 1e10, "monitorvariables": ["cpu", "resrho", "cl", "cd"], "volumevariables": ["blank"], "surfacevariables": ["mach", "cp", "vx", "vy", "vz", "blank"], "useNKSolver": True, "nkswitchtol": 0.01, "nkadpc": True, "nkjacobianlag": 5, "nkouterpreconits": 3, "nkinnerpreconits": 2, # Convergence Parameters "L2Convergence": 1e-10, "L2ConvergenceCoarse": 1e-2, "adjointl2convergence": 1e-6, "forcesAsTractions": True, "debugzipper": True, "nearwalldist": 0.001, # 'nkls':'none', "solutionprecision": "double", "adjointsubspacesize": 200, "outerpreconits": 3, "zipperSurfaceFamily": "output_fam", "flowtype": "internal", } ref_file = "solve_conic_mb.json" def setUp(self): super().setUp() self.ap = copy.copy(ap_conic_conv_nozzle) options = copy.copy(adflowDefOpts) options.update(self.options) # Setup aeroproblem planeFile = os.path.join( baseDir, "../../inputFiles/integration_plane_viscous.fmt") options = copy.copy(adflowDefOpts) options.update(self.options) # Setup aeroproblem self.ap.evalFuncs.extend([ "mdot_plane", "mavgptot_plane", "aavgptot_plane", "mavgttot_plane", "mavgps_plane", "aavgps_plane" ]) # Create the solver self.CFDSolver = ADFLOW(options=options, debug=False) self.CFDSolver.addIntegrationSurface(planeFile, "viscous_plane") self.CFDSolver.finalizeUserIntegrationSurfaces() self.CFDSolver.addFamilyGroup("upstream", ["inlet"]) self.CFDSolver.addFamilyGroup("downstream", ["outlet"]) self.CFDSolver.addFamilyGroup("all_flow", ["inlet", "outlet"]) self.CFDSolver.addFamilyGroup("output_fam", ["all_flow", "allWalls"]) self.CFDSolver.addFunction("mdot", "upstream", name="mdot_up") self.CFDSolver.addFunction("mdot", "downstream", name="mdot_down") self.CFDSolver.addFunction("mdot", "viscous_plane", name="mdot_plane") self.CFDSolver.addFunction("mavgptot", "downstream", name="mavgptot_down") self.CFDSolver.addFunction("mavgptot", "upstream", name="mavgptot_up") self.CFDSolver.addFunction("mavgptot", "viscous_plane", name="mavgptot_plane") self.CFDSolver.addFunction("aavgptot", "downstream", name="aavgptot_down") self.CFDSolver.addFunction("aavgptot", "upstream", name="aavgptot_up") self.CFDSolver.addFunction("aavgptot", "viscous_plane", name="aavgptot_plane") self.CFDSolver.addFunction("mavgttot", "downstream", name="mavgttot_down") self.CFDSolver.addFunction("mavgttot", "upstream", name="mavgttot_up") self.CFDSolver.addFunction("mavgttot", "viscous_plane", name="mavgttot_plane") self.CFDSolver.addFunction("mavgps", "downstream", name="mavgps_down") self.CFDSolver.addFunction("mavgps", "upstream", name="mavgps_up") self.CFDSolver.addFunction("mavgps", "viscous_plane", name="mavgps_plane") self.CFDSolver.addFunction("aavgps", "downstream", name="aavgps_down") self.CFDSolver.addFunction("aavgps", "upstream", name="aavgps_up") self.CFDSolver.addFunction("aavgps", "viscous_plane", name="aavgps_plane") def test_solve(self): # do the solve self.CFDSolver(self.ap) # check its accuracy utils.assert_functions_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-9) utils.assert_states_allclose(self.handler, self.CFDSolver, tol=1e-10) utils.assert_residuals_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10)
# ANK Solver Parameters 'useANKSolver': True, 'ankswitchtol': 1e-1, # NK Solver Parameters 'useNKSolver': True, 'nkswitchtol': 1e-4, # Termination Criteria 'L2Convergence': 1e-6, 'L2ConvergenceCoarse': 1e-2, 'nCycles': 1000, } #rst Start ADflow # Create solver CFDSolver = ADFLOW(options=aeroOptions) # Add features CFDSolver.addLiftDistribution(150, 'z') CFDSolver.addSlices('z', numpy.linspace(0.1, 14, 10)) #rst Create AeroProblem ap = AeroProblem(name='wing', mach=0.8, altitude=10000, alpha=1.5, areaRef=45.5, chordRef=3.25, evalFuncs=['cl', 'cd']) #rst Create polar arrays
def setup_cb(comm): solver = ADFLOW(options=options, comm=comm, debug=True) solver.addIntegrationSurface('../inputFiles/integration_plane_viscous.fmt', 'viscous_plane') solver.finalizeUserIntegrationSurfaces() solver.addFamilyGroup('upstream', ['inlet']) solver.addFamilyGroup('downstream', ['outlet']) solver.addFamilyGroup('all_flow', ['inlet', 'outlet']) solver.addFamilyGroup('output_fam', ['all_flow', 'allWalls']) solver.addFunction('mdot', 'upstream', name="mdot_up") solver.addFunction('mdot', 'downstream', name="mdot_down") solver.addFunction('mdot', 'viscous_plane', name="mdot_plane") solver.addFunction('mavgptot', 'downstream', name="mavgptot_down") solver.addFunction('mavgptot', 'upstream', name="mavgptot_up") solver.addFunction('mavgptot', 'viscous_plane', name="mavgptot_plane") solver.addFunction('aavgptot', 'downstream', name="aavgptot_down") solver.addFunction('aavgptot', 'upstream', name="aavgptot_up") solver.addFunction('aavgptot', 'viscous_plane', name="aavgptot_plane") solver.addFunction('mavgttot', 'downstream', name="mavgttot_down") solver.addFunction('mavgttot', 'upstream', name="mavgttot_up") solver.addFunction('mavgttot', 'viscous_plane', name="mavgttot_plane") solver.addFunction('mavgps', 'downstream', name="mavgps_down") solver.addFunction('mavgps', 'upstream', name="mavgps_up") solver.addFunction('mavgps', 'viscous_plane', name="mavgps_plane") solver.addFunction('aavgps', 'downstream', name="aavgps_down") solver.addFunction('aavgps', 'upstream', name="aavgps_up") solver.addFunction('aavgps', 'viscous_plane', name="aavgps_plane") solver.setOption('ncycles', 1000) return solver, None, None, None
aeroOptions = { # Common Parameters "gridFile": gridFile, "outputDirectory": "./", "MGCycle": "sg", "volumeVariables": ["blank"], "surfaceVariables": ["blank"], # Physics Parameters "equationType": "RANS", # Debugging parameters "debugZipper": False, "useZipperMesh": False, # number of times to run IHC cycle "nRefine": 10, # number of flooding iterations per IHC cycle. # the default value of -1 just lets the algorithm run until flooded cells stop changing "nFloodIter": -1, "nearWallDist": 0.1, "oversetPriority": oversetpriority, } # Create solver CFDSolver = ADFLOW(options=aeroOptions, debug=False) # Uncoment this if just want to check flooding CFDSolver.setAeroProblem(ap) name = ".".join(gridFile.split(".")[0:-1]) CFDSolver.writeVolumeSolutionFile(name + "_IHC.cgns", writeGrid=True) # rst end
'nkswitchtol':1e-6, # Termination Criteria 'L2Convergence':1e-6, 'nCycles':10000, # Zipper mesh option 'debugzipper':False, 'usezippermesh':True, 'nrefine':10, # number of times to run IHC cycle 'nearwalldist':0.1, 'oversetpriority':oversetpriority } # Create solver CFDSolver = ADFLOW(options=aeroOptions) #rst end_options # Save the lift distribution for the front wing CFDSolver.addLiftDistribution(200, 'z', groupName='wing_front') # Save the lift distribution for the back wing CFDSolver.addLiftDistribution(200, 'z', groupName='wing_back') # Save the total lift distribution CFDSolver.addLiftDistribution(200, 'z') #rst end_dist ap = AeroProblem(name='fc', mach=0.3, altitude=1000, areaRef=0.64*0.24*2, alpha=3., chordRef=0.24, evalFuncs = ['cl', 'cd']) CFDSolver(ap)
class TestJacVecBWDFast(reg_test_classes.RegTest): """ Tests that given a flow state the state jacobian vector products are accurate. """ N_PROCS = 2 def setUp(self): if not hasattr(self, "name"): # return immediately when the setup method is being called on the based class and NOT the # classes created using parametrized # this will happen when testing, but will hopefully be fixed down the line return super().setUp() options = copy.copy(adflowDefOpts) options["outputdirectory"] = os.path.join(baseDir, options["outputdirectory"]) options.update(self.options) # Create the solver self.CFDSolver = ADFLOW(options=copy.deepcopy(options), debug=True) self.ap = copy.deepcopy(self.aero_prob) # add the default dvs to the problem for dv in defaultAeroDVs: self.ap.addDV(dv) # propagates the values from the restart file throughout the code self.CFDSolver.getResidual(self.ap) # ------------------- Derivative routine checks ---------------------------- def test_BWD(self): # dwBar = self.CFDSolver.getStatePerturbation(314) wBar = self.CFDSolver.computeJacobianVectorProductBwd( resBar=dwBar, wDeriv=True, ) wBarfast = self.CFDSolver.computeJacobianVectorProductBwdFast( resBar=dwBar) np.testing.assert_allclose(wBar, wBarfast, atol=1e-16, err_msg="w wrt res") def test_repeated_calls(self): dwBar = self.CFDSolver.getStatePerturbation(314) wBarfast1 = self.CFDSolver.computeJacobianVectorProductBwdFast( resBar=dwBar) wBarfast2 = self.CFDSolver.computeJacobianVectorProductBwdFast( resBar=dwBar) np.testing.assert_allclose(wBarfast1, wBarfast2, atol=1e-16, err_msg="w wrt res double call")
def MLMC(self): # Use an MLMC algorithm to determine an optimal sample distribution between existing mesh levels # We do this once before optimization, then compute statistics with the same set of samples at every iteration # start with initial samples # Get a set of UQ sample points (LHS), enough for each level at the start #sys.stdout = open(os.devnull, "w") # flow characteristics alpha = 0.0 mach = self.ooptions['mach'] #0.95 Re = self.ooptions['Re'] #50000 Re_L = 1.0 tempR = 540 arearef = 2.0 chordref = 1.0 a_init = self.DVGeo.getValues() a_init['pnts'][:] = self.ooptions['DVInit'] self.current_samples = self.NS0 * self.Lmax if rank == 0: rank0sam = plate_sa_lhs.genLHS(s=self.current_samples) else: rank0sam = None self.sample = comm.bcast(rank0sam, root=0) # Scatter samples on each level, multi-point parallelism for i in range(self.Lmax): self.cases.append(divide_cases(self.NS0, size)) for j in range(len(self.cases[i])): for k in range(len(self.cases[i][j])): self.cases[i][j][k] += i * self.NS0 #self.nsp.append(len(self.cases[i][rank]))#int(ns/size) # samples per processor self.samplep.append(self.sample[self.cases[i][rank]]) #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() # for i in range(self.Lmax): # assert len(self.samplep[i]) == self.nsp[i] # Actually create solvers (and aeroproblems?) (and mesh?) now nslp = [] nslt = [] for k in range(self.Lmax): alist = [] slist = [] mlist = [] alist2 = [] slist2 = [] mlist2 = [] nslp.append(len(self.cases[k][rank])) nslt.append(sum([len(self.cases[k][x]) for x in range(size)])) for i in range(nslp[k]): namestr = self.gridSol + "_" + str(self.cases[k][rank][i]) # create meshes leveloptions = self.woptions leveloptions['gridFile'] = self.meshnames[k] mlist.append(USMesh(options=leveloptions, comm=MPI.COMM_SELF)) # create aeroproblems aloptions = self.aoptions aloptions['gridFile'] = self.meshnames[k] alist.append( AeroProblem(name=namestr, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=tempR, areaRef=arearef, chordRef=chordref, evalFuncs=['cd'])) time.sleep(0.1) # this solves a few problems for some reason # create solvers slist.append(ADFLOW(options=aloptions, comm=MPI.COMM_SELF)) # if not self.ooptions['run_once']: # saconstsm = self.samplep[i].tolist() # else: saconstsm = self.samplep[k][i].tolist() self.saconsts = saconstsm + self.saconstsb slist[i].setOption('SAConsts', self.saconsts) slist[i].setDVGeo(self.DVGeo) slist[i].setMesh(mlist[i]) coords = slist[i].getSurfaceCoordinates( groupName=slist[i].allWallsGroup) slist[i].DVGeo.addPointSet(coords, 'coords') if k > 0: #create additional solvers at higher levels for the estimators # create meshes namestr = self.gridSol + "_" + str( self.cases[k][rank][i]) + "_m" leveloptions = self.woptions leveloptions['gridFile'] = self.meshnames[k - 1] mlist2.append( USMesh(options=leveloptions, comm=MPI.COMM_SELF)) # create aeroproblems aloptions = self.aoptions aloptions['gridFile'] = self.meshnames[k - 1] alist2.append( AeroProblem(name=namestr, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=tempR, areaRef=arearef, chordRef=chordref, evalFuncs=['cd'])) time.sleep( 0.1) # this solves a few problems for some reason # create solvers slist2.append(ADFLOW(options=aloptions, comm=MPI.COMM_SELF)) slist2[i].setOption('SAConsts', self.saconsts) slist2[i].setDVGeo(self.DVGeo) slist2[i].setMesh(mlist2[i]) coords = slist[i].getSurfaceCoordinates( groupName=slist2[i].allWallsGroup) slist2[i].DVGeo.addPointSet(coords, 'coords') self.aps.append(alist) self.solvers.append(slist) self.meshes.append(mlist) if k > 0: self.aps[k] += alist2 self.solvers[k] += slist2 self.meshes[k] += mlist2 #import pdb; pdb.set_trace() # start looping over mesh levels L = 0 M = 4.0 #0.5 #refinement factor? converged = 0 eps = self.uoptions['vartol'] sum1 = [] mus = [] sump = [] musp = [] sumpm = [] muspm = [] summ = [] musm = [] E = [] V = [] N1 = [] while ~converged & L < self.Lmax: # compute start up samples to estimate variance dvdict = {'pnts': a_init['pnts']} funcs = {} nslp = [] nslt = [] for k in range(self.Lmax): nslp.append(len(self.cases[k][rank])) nslt.append(sum([len(self.cases[k][x]) for x in range(size)])) sump.append(0.) musp.append(numpy.zeros(nslp[L])) sumpm.append(0.) muspm.append(numpy.zeros(nslp[L])) for i in range(nslp[L]): # just do this again in case saconstsm = self.samplep[L][i].tolist() self.saconsts = saconstsm + self.saconstsb self.solvers[L][i].setOption('SAConsts', self.saconsts) self.solvers[L][i].DVGeo.setDesignVars(dvdict) self.aps[L][i].setDesignVars(dvdict) self.solvers[L][i](self.aps[L][i]) self.solvers[L][i].evalFunctions(self.aps[L][i], funcs) astr = self.gridSol + "_" + str(self.cases[L][rank][i]) + "_cd" musp[L][i] = funcs[astr] sump[L] += funcs[astr] #import pdb; pdb.set_trace() if L > 0: self.solvers[L][i + nslp[L]].setOption( 'SAConsts', self.saconsts) self.solvers[L][i + nslp[L]].DVGeo.setDesignVars(dvdict) self.aps[L][i + nslp[L]].setDesignVars(dvdict) self.solvers[L][i + nslp[L]](self.aps[L][i + nslp[L]]) self.solvers[L][i + nslp[L]].evalFunctions( self.aps[L][i + nslp[L]], funcs) astr = self.gridSol + "_" + str( self.cases[L][rank][i]) + "_m_cd" muspm[L][i] = -funcs[astr] sumpm[L] += -funcs[astr] # compute mean and variance estimate from start up samples sum1.append(comm.allreduce(sump[L])) mus.append(comm.allgather(musp[L])) summ.append(comm.allreduce(sumpm[L])) musm.append(comm.allgather(muspm[L])) #import pdb; pdb.set_trace() # mean at each level E = numpy.zeros(L + 1) for l in range(L + 1): E[l] = (sum1[l] + summ[l]) / nslt[l] # variance at each level V = numpy.zeros(L + 1) for l in range(L + 1): sum2 = 0. for i in range(len(mus[l])): #range(size): for j in range(len(mus[l][i])): #range(self.nsp): if l > 0: sum2 += ((mus[l][i][j] + musm[l][i][j]) - E[l])**2 else: sum2 += (mus[l][i][j] - E[l])**2 V[l] = sum2 / nslt[l] #import pdb; pdb.set_trace() # now determine the optimal number of samples at each level N1.append(0.) worksum = 0 for l in range(L + 1): worksum += numpy.sqrt(V[l] * (M**l)) for l in range(L + 1): nlf = 2 * numpy.sqrt(V[l] / (M**l)) * worksum / (eps * eps) nlfm = max(nslt[l], math.ceil(nlf)) N1[l] = nlfm # now compute and generate additional samples at each level # first partition samples NEVERMIND (just do it once at each level, no need to repeat) # create the extra number of solvers at each (the current) level # need to loop everything from here on for l in range(L + 1): alist = self.aps[l][0:nslp[l]] slist = self.solvers[l][0:nslp[l]] mlist = self.meshes[l][0:nslp[l]] if l > 0: alist2 = self.aps[l][nslp[l]:] slist2 = self.solvers[l][nslp[l]:] mlist2 = self.meshes[l][nslp[l]:] self.naddedtot[l] = N1[l] - nslt[l] self.current_samples += self.naddedtot[l] #import pdb; pdb.set_trace() if rank == 0: rank0sam = plate_sa_lhs.genLHS(s=self.current_samples) else: rank0sam = None self.sample = comm.bcast(rank0sam, root=0) if self.naddedtot[l] > 0: temp = divide_cases(self.naddedtot[l], size) for i in range(len(temp)): for j in range(len(temp[i])): temp[i][j] += self.current_samples - self.naddedtot[ l] #self.Lmax*self.NS0 + sum(self.naddedtot[0:L]) else: temp = [] if len(temp): for ns in range(size): self.cases[l][ns] += temp[ns] #append nslpnew = len(self.cases[l][rank]) nsltnew = sum([len(self.cases[l][x]) for x in range(size)]) #self.nsp[L] = len(self.cases[L][rank]) #int(ns/size) # samples per processor self.samplep[l] = self.sample[self.cases[l][rank]] for i in range(nslp[l], nslpnew): #need it to be just the extra cases #import pdb; pdb.set_trace() namestr = self.gridSol + "_" + str(self.cases[l][rank][i]) # create meshes leveloptions = self.woptions leveloptions['gridFile'] = self.meshnames[l] mlist.append( USMesh(options=leveloptions, comm=MPI.COMM_SELF)) # create aeroproblems aloptions = self.aoptions aloptions['gridFile'] = self.meshnames[l] alist.append( AeroProblem(name=namestr, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=tempR, areaRef=arearef, chordRef=chordref, evalFuncs=['cd'])) time.sleep( 0.1) # this solves a few problems for some reason # create solvers slist.append(ADFLOW(options=aloptions, comm=MPI.COMM_SELF)) saconstsm = self.samplep[l][i].tolist() self.saconsts = saconstsm + self.saconstsb slist[i].setOption('SAConsts', self.saconsts) slist[i].setDVGeo(self.DVGeo) slist[i].setMesh(mlist[i]) coords = slist[i].getSurfaceCoordinates( groupName=slist[i].allWallsGroup) slist[i].DVGeo.addPointSet(coords, 'coords') time.sleep(0.1) if l > 0: #create additional solvers at higher levels for the estimators # create meshes #import pdb; pdb.set_trace() namestr = self.gridSol + "_" + str( self.cases[l][rank][i]) + "_m" leveloptions = self.woptions leveloptions['gridFile'] = self.meshnames[l - 1] mlist2.append( USMesh(options=leveloptions, comm=MPI.COMM_SELF)) # create aeroproblems aloptions = self.aoptions aloptions['gridFile'] = self.meshnames[l - 1] alist2.append( AeroProblem(name=namestr, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=tempR, areaRef=arearef, chordRef=chordref, evalFuncs=['cd'])) time.sleep( 0.1) # this solves a few problems for some reason # create solvers slist2.append( ADFLOW(options=aloptions, comm=MPI.COMM_SELF)) slist2[i].setOption('SAConsts', self.saconsts) slist2[i].setDVGeo(self.DVGeo) slist2[i].setMesh(mlist2[i]) coords = slist[i].getSurfaceCoordinates( groupName=slist2[i].allWallsGroup) slist2[i].DVGeo.addPointSet(coords, 'coords') nslp[l] = nslpnew nslt[l] = nsltnew self.aps[l] = alist self.solvers[l] = slist self.meshes[l] = mlist if l > 0: self.aps[l] += alist2 self.solvers[l] += slist2 self.meshes[l] += mlist2 # compute remaining samples sump[l] = 0 sumpm[l] = 0 musp[l] = numpy.zeros(nslp[l]) muspm[l] = numpy.zeros(nslp[l]) for i in range(nslp[l]): # just do this again in case saconstsm = self.samplep[l][i].tolist() self.saconsts = saconstsm + self.saconstsb self.solvers[l][i].setOption('SAConsts', self.saconsts) self.solvers[l][i].DVGeo.setDesignVars(dvdict) self.aps[l][i].setDesignVars(dvdict) self.solvers[l][i](self.aps[l][i]) self.solvers[l][i].evalFunctions(self.aps[l][i], funcs) astr = self.gridSol + "_" + str( self.cases[l][rank][i]) + "_cd" musp[l][i] = funcs[astr] sump[l] += funcs[astr] #import pdb; pdb.set_trace() if l > 0: self.solvers[l][i + nslp[l]].setOption( 'SAConsts', self.saconsts) self.solvers[l][i + nslp[l]].DVGeo.setDesignVars(dvdict) self.aps[l][i + nslp[l]].setDesignVars(dvdict) self.solvers[l][i + nslp[l]](self.aps[l][i + nslp[l]]) self.solvers[l][i + nslp[l]].evalFunctions( self.aps[l][i + nslp[l]], funcs) astr = self.gridSol + "_" + str( self.cases[l][rank][i]) + "_m_cd" muspm[l][i] = -funcs[astr] sumpm[l] += -funcs[astr] # compute mean and variance estimate from all samples sum1[l] = comm.allreduce(sump[l]) mus[l] = comm.allgather(musp[l]) summ[l] = comm.allreduce(sumpm[l]) musm[l] = comm.allgather(muspm[l]) # mean at each level E[l] = (sum1[l] + summ[l]) / nslt[l] # variance at each level sum2 = 0. for i in range(len(mus[l])): #range(size): for j in range(len(mus[l][i])): #range(self.nsp): if l > 0: sum2 += ((mus[l][i][j] + musm[l][i][j]) - E[l])**2 else: sum2 += (mus[l][i][j] - E[l])**2 V[l] = sum2 / nslt[l] # if L == 1: # import pdb; pdb.set_trace() L += 1 #import pdb; pdb.set_trace() #sys.stdout = sys.__stdout__ if rank == 0: print("MLMC Completed, Samples per level: ", N1) self.N1 = N1
class TestJacVecFwdFD(reg_test_classes.RegTest): """ Tests that given a flow state the FWD jacobian vector products are agree with FD. """ N_PROCS = 2 def setUp(self): if not hasattr(self, "name"): # return immediately when the setup method is being called on the based class and NOT the # classes created using parametrized # this will happen when testing, but will hopefully be fixed down the line return super().setUp() options = copy.copy(adflowDefOpts) options["outputdirectory"] = os.path.join(baseDir, options["outputdirectory"]) options.update(self.options) # Create the solver self.CFDSolver = ADFLOW(options=copy.deepcopy(options), debug=True) self.ap = copy.deepcopy(self.aero_prob) # add the default dvs to the problem for dv in defaultAeroDVs: self.ap.addDV(dv) # propagates the values from the restart file throughout the code self.CFDSolver.getResidual(self.ap) # ------------------- Derivative routine checks ---------------------------- def test_wDot(self): # perturb each input and check that the outputs match the FD to with in reason wDot = self.CFDSolver.getStatePerturbation(321) resDot, funcsDot, fDot = self.CFDSolver.computeJacobianVectorProductFwd( wDot=wDot, residualDeriv=True, funcDeriv=True, fDeriv=True) resDot_FD, funcsDot_FD, fDot_FD = self.CFDSolver.computeJacobianVectorProductFwd( wDot=wDot, residualDeriv=True, funcDeriv=True, fDeriv=True, mode="FD", h=1e-8) np.testing.assert_allclose(resDot_FD, resDot, rtol=8e-4, err_msg="residual") for func in funcsDot: np.testing.assert_allclose(funcsDot_FD[func], funcsDot[func], rtol=1e-5, err_msg=func) np.testing.assert_allclose(fDot_FD, fDot, rtol=5e-4, err_msg="forces") def test_xVDot(self): # perturb each input and check that the outputs match the FD to with in reason xVDot = self.CFDSolver.getSpatialPerturbation(314) resDot, funcsDot, fDot = self.CFDSolver.computeJacobianVectorProductFwd( xVDot=xVDot, residualDeriv=True, funcDeriv=True, fDeriv=True) resDot_FD, funcsDot_FD, fDot_FD = self.CFDSolver.computeJacobianVectorProductFwd( xVDot=xVDot, residualDeriv=True, funcDeriv=True, fDeriv=True, mode="FD", h=1e-8) idx_max = np.argmax((resDot_FD - resDot) / resDot) print(resDot[idx_max], resDot_FD[idx_max]) np.testing.assert_allclose(resDot_FD, resDot, atol=5e-4, err_msg="residual") for func in funcsDot: np.testing.assert_allclose(funcsDot_FD[func], funcsDot[func], rtol=5e-6, err_msg=func) np.testing.assert_allclose(fDot_FD, fDot, rtol=5e-4, err_msg="forces") def test_xDvDot(self): # perturb each input and check that the outputs match the FD to with in reason step_size = { "alpha": 1e-4, "beta": 1e-5, "mach": 1e-5, "P": 1e-1, "T": 1e-4, "xRef": 1e-5, "yRef": 1e-5, "zRef": 1e-5, } for aeroDV in self.ap.DVs.values(): key = aeroDV.key xDvDot = {key: 1.0} resDot, funcsDot, fDot = self.CFDSolver.computeJacobianVectorProductFwd( xDvDot=xDvDot, residualDeriv=True, funcDeriv=True, fDeriv=True) resDot_FD, funcsDot_FD, fDot_FD = self.CFDSolver.computeJacobianVectorProductFwd( xDvDot=xDvDot, residualDeriv=True, funcDeriv=True, fDeriv=True, mode="FD", h=step_size[key]) # the tolerances here are loose becuase different ouputs have different optimal steps np.testing.assert_allclose(resDot_FD, resDot, atol=5e-5, err_msg=f"residual wrt {key}") for func in funcsDot: if np.abs(funcsDot[func]) <= 1e-16: np.testing.assert_allclose(funcsDot_FD[func], funcsDot[func], atol=5e-5, err_msg=f"{func} wrt {key}") else: np.testing.assert_allclose(funcsDot_FD[func], funcsDot[func], rtol=1e-3, err_msg=f"{func} wrt {key}") np.testing.assert_allclose(fDot_FD, fDot, atol=5e-7, err_msg=f"forces wrt {key}")
def dist_samples(self): # If we already have the number of samples, just create as many solvers as needed at each level # Just do this after running MLMC() anyway # flow characteristics alpha = 0.0 mach = self.ooptions['mach'] #0.95 Re = self.ooptions['Re'] #50000 Re_L = 1.0 tempR = 540 arearef = 2.0 chordref = 1.0 a_init = self.DVGeo.getValues() a_init['pnts'][:] = self.ooptions['DVInit'] self.current_samples = sum(self.N1) if rank == 0: rank0sam = plate_sa_lhs.genLHS(s=self.current_samples) else: rank0sam = None self.sample = comm.bcast(rank0sam, root=0) #import pdb; pdb.set_trace() # Scatter samples on each level, multi-point parallelism self.cases = [] self.samplep = [] for i in range(self.Lmax): self.cases.append(divide_cases(self.N1[i], size)) for j in range(len(self.cases[i])): for k in range(len(self.cases[i][j])): self.cases[i][j][k] += sum(self.N1[0:i]) #self.nsp.append(len(self.cases[i][rank]))#int(ns/size) # samples per processor self.samplep.append(self.sample[self.cases[i][rank]]) # Actually create solvers (and aeroproblems?) (and mesh?) now self.aps = [] self.solvers = [] self.meshes = [] nslp = [] nslt = [] for k in range(self.Lmax): alist = [] slist = [] mlist = [] nslp.append(len(self.cases[k][rank])) nslt.append(sum([len(self.cases[k][x]) for x in range(size)])) for i in range(nslp[k]): namestr = self.gridSol + "_" + str(self.cases[k][rank][i]) # create meshes leveloptions = self.woptions leveloptions['gridFile'] = self.meshnames[self.mord[k]] mlist.append(USMesh(options=leveloptions, comm=MPI.COMM_SELF)) # create aeroproblems aloptions = self.aoptions aloptions['gridFile'] = self.meshnames[self.mord[k]] alist.append( AeroProblem(name=namestr, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=tempR, areaRef=arearef, chordRef=chordref, evalFuncs=['cd'])) time.sleep(0.1) # this solves a few problems for some reason # create solvers slist.append(ADFLOW(options=aloptions, comm=MPI.COMM_SELF)) saconstsm = self.samplep[self.Lmax - 1][i].tolist() self.saconsts = saconstsm + self.saconstsb slist[i].setOption('SAConsts', self.saconsts) slist[i].setDVGeo(self.DVGeo) slist[i].setMesh(mlist[i]) coords = slist[i].getSurfaceCoordinates( groupName=slist[i].allWallsGroup) slist[i].DVGeo.addPointSet(coords, 'coords') self.aps.append(alist) self.solvers.append(slist) self.meshes.append(mlist)
"outerPreconIts": 3, "NKSubSpaceSize": 400, "NKASMOverlap": 4, "NKPCILUFill": 4, "NKJacobianLag": 5, "nkswitchtol": 1e-6, "nkouterpreconits": 3, "NKInnerPreConIts": 3, "writeSurfaceSolution": False, "writeVolumeSolution": False, "frozenTurbulence": False, "restartADjoint": False, } # Create solver CFDSolver = ADFLOW(options=aeroOptions, comm=comm) # rst adflow (end) # ====================================================================== # Set up flow conditions with AeroProblem # ====================================================================== # rst aeroproblem (beg) ap = AeroProblem(name="fc", alpha=alpha, mach=mach, altitude=alt, areaRef=1.0, chordRef=1.0, evalFuncs=["cl", "cd"]) # Add angle of attack variable ap.addDV("alpha", value=alpha, lower=0, upper=10.0, scale=1.0) # rst aeroproblem (end)
class TestAdjoint(test_objects.RegTest): """ Tests that sensitives calculated from solving an adjoint are correct. and jacobian vector products are accurate. based on old regression tests 12, and 14 """ N_PROCS = 2 options = None ap = None ref_file = None def setUp(self): if not hasattr(self, "name"): # return immediately when the setup method is being called on the based class and NOT the # classes created using parametrized # this will happen when training, but will hopefully be fixed down the line return super().setUp() options = copy.copy(adflowDefOpts) options["outputdirectory"] = os.path.join(baseDir, options["outputdirectory"]) options.update(self.options) self.ffdFile = os.path.join(baseDir, "../../inputFiles/mdo_tutorial_ffd.fmt") mesh_options = copy.copy(IDWarpDefOpts) mesh_options.update({"gridFile": options["gridfile"]}) self.ap = copy.deepcopy(self.aero_prob) # Setup aeroproblem self.ap.evalFuncs = self.evalFuncs # add the default dvs to the problem for dv in defaultAeroDVs: self.ap.addDV(dv) self.CFDSolver = ADFLOW(options=options, debug=True) self.CFDSolver.setMesh(USMesh(options=mesh_options)) self.CFDSolver.setDVGeo(setDVGeo(self.ffdFile, cmplx=False)) # propagates the values from the restart file throughout the code self.CFDSolver.getResidual(self.ap) def test_residuals(self): utils.assert_residuals_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10) def test_adjoint(self): utils.assert_adjoint_sens_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10)
class TestSolve(reg_test_classes.RegTest): """ Tests that ADflow can converge the wing from the mdo tutorial using the euler equation to the required accuracy as meassure by the norm of the residuals, and states, and the accuracy of the functions based on the old regression test 15 """ N_PROCS = 2 ref_file = "solve_rans_time_acc_naca0012.json" def setUp(self): super().setUp() gridFile = os.path.join(baseDir, "../../inputFiles/naca0012_rans-L2.cgns") f = 10.0 # [Hz] Forcing frequency of the flow period = 1.0 / f # [sec] nStepPerPeriod = 8 nPeriods = 1 nfineSteps = nStepPerPeriod * nPeriods dt = period / nStepPerPeriod # [s] The actual timestep options = copy.copy(adflowDefOpts) options.update({ "gridfile": gridFile, "outputdirectory": os.path.join(baseDir, "../output_files"), "writevolumesolution": False, "vis4": 0.025, "vis2": 0.5, "restrictionrelaxation": 0.5, "smoother": "DADI", "equationtype": "RANS", "equationmode": "unsteady", "timeIntegrationscheme": "BDF", "ntimestepsfine": nfineSteps, "deltat": dt, "nsubiterturb": 10, "nsubiter": 5, "useale": False, "usegridmotion": True, "cfl": 2.5, "cflcoarse": 1.2, "ncycles": 2000, "mgcycle": "3w", "mgstartlevel": 1, "monitorvariables": ["cpu", "resrho", "cl", "cd", "cmz"], "usenksolver": False, "l2convergence": 1e-6, "l2convergencecoarse": 1e-4, "qmode": True, "alphafollowing": False, "blockSplitting": True, "useblockettes": False, }) # Setup aeroproblem self.ap = copy.copy(ap_naca0012_time_acc) # Create the solver self.CFDSolver = ADFLOW(options=options, debug=False) self.CFDSolver.addSlices("z", [0.5]) def test_solve(self): # do the solve self.CFDSolver(self.ap) # check its accuracy utils.assert_functions_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-8)
class TestSolveOverset(reg_test_classes.RegTest): """ Tests that ADflow can converge the wing from the mdo tutorial using the euler equation to the required accuracy as meassure by the norm of the residuals, and states, and the accuracy of the functions based on the old regression test 17 and 18 """ N_PROCS = 2 options = { "gridfile": os.path.join(baseDir, "../../inputFiles/conic_conv_nozzle.cgns"), "outputdirectory": os.path.join(baseDir, "../output_files"), # Physics Parameters "equationType": "euler", "smoother": "dadi", "nsubiter": 3, "CFL": 4.0, "CFLCoarse": 1.25, "MGCycle": "sg", "MGStartLevel": -1, "nCyclesCoarse": 250, "nCycles": 1000, "nkcfl0": 1e10, "monitorvariables": ["cpu", "resrho", "cl", "cd"], "volumevariables": ["blank"], "surfacevariables": ["mach", "cp", "vx", "vy", "vz", "blank"], "useNKSolver": True, "nkswitchtol": 0.01, "nkadpc": True, "nkjacobianlag": 5, "nkouterpreconits": 3, "nkinnerpreconits": 2, # Convergence Parameters "L2Convergence": 1e-10, "L2ConvergenceCoarse": 1e-4, "adjointl2convergence": 1e-6, "forcesAsTractions": True, "debugzipper": True, "nearwalldist": 0.001, # 'nkls':'none', "solutionprecision": "double", "adjointsubspacesize": 200, "outerpreconits": 3, "zipperSurfaceFamily": "output_fam", "flowtype": "internal", "blocksplitting": True, } ap = copy.copy(ap_conic_conv_nozzle) ref_file = "solve_conic_overset.json" def setUp(self): super().setUp() options = copy.copy(adflowDefOpts) options.update(self.options) # Setup aeroproblem self.ap.setBCVar("Pressure", 79326.7, "downstream") self.ap.addDV("Pressure", family="downstream") self.ap.setBCVar("PressureStagnation", 100000.0, "upstream") self.ap.addDV("PressureStagnation", family="upstream") self.ap.setBCVar("TemperatureStagnation", 500.0, "upstream") self.ap.addDV("TemperatureStagnation", family="upstream") # Create the solver self.CFDSolver = ADFLOW(options=options, debug=False) self.CFDSolver.addFamilyGroup("upstream", ["inlet"]) self.CFDSolver.addFamilyGroup("downstream", ["outlet"]) self.CFDSolver.addFamilyGroup("all_flow", ["inlet", "outlet"]) self.CFDSolver.addFamilyGroup("output_fam", ["all_flow", "allWalls"]) self.CFDSolver.addFunction("mdot", "upstream", name="mdot_up") self.CFDSolver.addFunction("mdot", "downstream", name="mdot_down") self.CFDSolver.addFunction("mavgptot", "downstream", name="mavgptot_down") self.CFDSolver.addFunction("mavgptot", "upstream", name="mavgptot_up") self.CFDSolver.addFunction("aavgptot", "downstream", name="aavgptot_down") self.CFDSolver.addFunction("aavgptot", "upstream", name="aavgptot_up") self.CFDSolver.addFunction("mavgttot", "downstream", name="mavgttot_down") self.CFDSolver.addFunction("mavgttot", "upstream", name="mavgttot_up") self.CFDSolver.addFunction("mavgps", "downstream", name="mavgps_down") self.CFDSolver.addFunction("mavgps", "upstream", name="mavgps_up") self.CFDSolver.addFunction("aavgps", "downstream", name="aavgps_down") self.CFDSolver.addFunction("aavgps", "upstream", name="aavgps_up") def test_solve(self): # do the solve self.CFDSolver(self.ap) # check its accuracy utils.assert_functions_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-9) utils.assert_states_allclose(self.handler, self.CFDSolver, tol=1e-10) # Check the residual res = self.CFDSolver.getResidual(self.ap) totalR0 = self.CFDSolver.getFreeStreamResidual(self.ap) res /= totalR0 reducedSum = self.CFDSolver.comm.reduce(np.sum(res**2)) if self.CFDSolver.comm.rank == 0: self.assertLessEqual(np.sqrt(reducedSum), self.options["L2Convergence"])
def setUp(self): super().setUp() gridFile = os.path.join(baseDir, "../../inputFiles/naca0012_rans-L2.cgns") f = 10.0 # [Hz] Forcing frequency of the flow period = 1.0 / f # [sec] nStepPerPeriod = 8 nPeriods = 1 nfineSteps = nStepPerPeriod * nPeriods dt = period / nStepPerPeriod # [s] The actual timestep options = copy.copy(adflowDefOpts) options.update({ "gridfile": gridFile, "outputdirectory": os.path.join(baseDir, "../output_files"), "writevolumesolution": False, "vis4": 0.025, "vis2": 0.5, "restrictionrelaxation": 0.5, "smoother": "DADI", "equationtype": "RANS", "equationmode": "unsteady", "timeIntegrationscheme": "BDF", "ntimestepsfine": nfineSteps, "deltat": dt, "nsubiterturb": 10, "nsubiter": 5, "useale": False, "usegridmotion": True, "cfl": 2.5, "cflcoarse": 1.2, "ncycles": 2000, "mgcycle": "3w", "mgstartlevel": 1, "monitorvariables": ["cpu", "resrho", "cl", "cd", "cmz"], "usenksolver": False, "l2convergence": 1e-6, "l2convergencecoarse": 1e-4, "qmode": True, "alphafollowing": False, "blockSplitting": True, "useblockettes": False, }) # Setup aeroproblem self.ap = copy.copy(ap_naca0012_time_acc) # Create the solver self.CFDSolver = ADFLOW(options=options, debug=False) self.CFDSolver.addSlices("z", [0.5])
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__
# NK Solver Parameters 'useNKSolver': True, 'nkswitchtol': 1e-6, # Termination Criteria 'L2Convergence': 1e-10, 'L2ConvergenceCoarse': 1e-2, 'nCycles': 10000, # Adjoint Parameters 'adjointL2Convergence': 1e-10, } # Create solver CFDSolver = ADFLOW(options=aeroOptions, comm=comm) CFDSolver.addLiftDistribution(200, 'z') #rst adflow (end) # ====================================================================== # Set up flow conditions with AeroProblem # ====================================================================== #rst aeroproblem (beg) ap = AeroProblem(name='fc', alpha=1.5, mach=0.8, altitude=10000, areaRef=45.5, chordRef=3.25, evalFuncs=['cl', 'cd']) # Add angle of attack variable
class TestSolve(reg_test_classes.RegTest): """ Tests that ADflow can converge the wing from the mdo tutorial using the euler equation to the required accuracy as meassure by the norm of the residuals, and states, and the accuracy of the functions based on the old regresson test 16 """ N_PROCS = 2 ref_file = "solve_2D_conv_nozzle.json" options = { "gridfile": os.path.join(baseDir, "../../input_files/euler_conv_nozzle.cgns"), "solutionprecision": "double", "gridprecision": "double", "liftIndex": 2, "CFL": 3.0, "CFLCoarse": 1.5, "MGCycle": "2w", "MGStartLevel": 2, "nCyclesCoarse": 500, "nCycles": 2500, "monitorvariables": ["resrho", "cl", "cd", "yplus"], "nsubiterturb": 3, "useNKSolver": True, "NKSubSpaceSize": 60, "L2Convergence": 1e-14, "L2ConvergenceCoarse": 1e-2, "NKSwitchTol": 1e-2, "nkadpc": False, "vis4": 0.006, "vis2": 0.0, "blocksplitting": True, "solutionPrecision": "double", "flowtype": "internal", } ap = ap_2D_conv_nozzle def setUp(self): super().setUp() options = copy.copy(adflowDefOpts) options["outputdirectory"] = os.path.join(baseDir, options["outputdirectory"]) options.update(self.options) # Create the solver self.CFDSolver = ADFLOW(options=options, debug=False) self.CFDSolver.addFamilyGroup("upstream", ["INFLOW"]) self.CFDSolver.addFamilyGroup("downstream", ["OUTFLOW"]) self.CFDSolver.addFamilyGroup("all_flow", ["INFLOW", "OUTFLOW"]) self.CFDSolver.addFunction("mdot", "upstream", name="mdot_up") self.CFDSolver.addFunction("mdot", "downstream", name="mdot_down") self.CFDSolver.addFunction("mavgptot", "downstream", name="mavgptot_down") self.CFDSolver.addFunction("mavgptot", "upstream", name="mavgptot_up") self.CFDSolver.addFunction("aavgptot", "downstream", name="aavgptot_down") self.CFDSolver.addFunction("aavgptot", "upstream", name="aavgptot_up") self.CFDSolver.addFunction("mavgttot", "downstream", name="mavgttot_down") self.CFDSolver.addFunction("mavgttot", "upstream", name="mavgttot_up") self.CFDSolver.addFunction("mavgps", "downstream", name="mavgps_down") self.CFDSolver.addFunction("mavgps", "upstream", name="mavgps_up") self.CFDSolver.addFunction("aavgps", "downstream", name="aavgps_down") self.CFDSolver.addFunction("aavgps", "upstream", name="aavgps_up") self.CFDSolver.addFunction("mavgmn", "downstream", name="mavgmn_down") self.CFDSolver.addFunction("mavgmn", "upstream", name="mavgmn_up") self.CFDSolver.addFunction( "drag", "all_flow", name="thrust") # this naming makes it seem like wishful thinking self.CFDSolver.addFunction("dragpressure", "all_flow", name="thrust_pressure") self.CFDSolver.addFunction("dragviscous", "all_flow", name="thrust_viscous") self.CFDSolver.addFunction("dragmomentum", "all_flow", name="thrust_momentum") def test_solve(self): # do the solve self.CFDSolver(self.ap) # check its accuracy utils.assert_functions_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-9) utils.assert_states_allclose(self.handler, self.CFDSolver, tol=1e-10) utils.assert_residuals_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10)
def setup_cb(comm): # Create the solver CFDSolver = ADFLOW(options=options, debug=False) return CFDSolver, None, None, None
'blocksplitting': True }) # Setup aeroproblem, cfdsolver ap = AeroProblem(name='mdo_tutorial', alpha=1.8, mach=0.80, R=287.87, altitude=10000.0, areaRef=45.5, chordRef=3.25, evalFuncs=['cd', 'lift', 'cmz']) ap.addDV('alpha') ap.addDV('mach') ap.addDV('altitude') CFDSolver = ADFLOW(options=aeroOptions, debug=True) if not 'complex' in sys.argv: # Solve system CFDSolver(ap, writeSolution=False) funcs = {} CFDSolver.evalFunctions(ap, funcs) # Solve sensitivities funcsSens = {} CFDSolver.evalFunctionsSens(ap, funcsSens) # Write values and derivatives out: if MPI.COMM_WORLD.rank == 0: for key in ['cd', 'cmz', 'lift']: print('funcs[%s]:' % key) reg_write(funcs['mdo_tutorial_%s' % key], 1e-10, 1e-10)
def setup_cb(comm): solver = ADFLOW(options=options, comm=comm, debug=False) solver.addFamilyGroup('upstream',['INFLOW']) solver.addFamilyGroup('downstream',['OUTFLOW']) solver.addFamilyGroup('all_flow',['INFLOW', 'OUTFLOW']) solver.addFunction('mdot', 'upstream', name="mdot_up") solver.addFunction('mdot', 'downstream', name="mdot_down") solver.addFunction('mavgptot', 'downstream', name="mavgptot_down") solver.addFunction('mavgptot', 'upstream', name="mavgptot_up") solver.addFunction('aavgptot', 'downstream', name="aavgptot_down") solver.addFunction('aavgptot', 'upstream', name="aavgptot_up") solver.addFunction('mavgttot', 'downstream', name="mavgttot_down") solver.addFunction('mavgttot', 'upstream', name="mavgttot_up") solver.addFunction('mavgps', 'downstream', name="mavgps_down") solver.addFunction('mavgps', 'upstream', name="mavgps_up") solver.addFunction('aavgps', 'downstream', name="aavgps_down") solver.addFunction('aavgps', 'upstream', name="aavgps_up") solver.addFunction('mavgmn', 'downstream', name="mavgmn_down") solver.addFunction('mavgmn', 'upstream', name="mavgmn_up") solver.addFunction('drag', 'all_flow', name="thrust") # this naming makes it seem like wishful thinking solver.addFunction('dragpressure', 'all_flow', name="thrust_pressure") solver.addFunction('dragviscous', 'all_flow', name="thrust_viscous") solver.addFunction('dragmomentum', 'all_flow', name="thrust_momentum") return solver, None, None, None
class TestFunctionals(reg_test_classes.RegTest): """ Tests that given a flow state the residuals, function, forces/tractions, and jacobian vector products are accurate. """ N_PROCS = 2 def setUp(self): if not hasattr(self, "name"): # return immediately when the setup method is being called on the based class and NOT the # classes created using parametrized # this will happen when testing, but will hopefully be fixed down the line return super().setUp() options = copy.copy(adflowDefOpts) options["outputdirectory"] = os.path.join(baseDir, options["outputdirectory"]) options.update(self.options) # Create the solver self.CFDSolver = ADFLOW(options=copy.deepcopy(options), debug=True) self.ap = copy.deepcopy(self.aero_prob) # add the default dvs to the problem for dv in defaultAeroDVs: self.ap.addDV(dv) # propagates the values from the restart file throughout the code self.CFDSolver.getResidual(self.ap) def test_restart_read(self): utils.assert_problem_size_equal(self.handler, self.CFDSolver, tol=1e-10) utils.assert_states_allclose(self.handler, self.CFDSolver, tol=1e-10) def test_residuals(self): utils.assert_residuals_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10) def test_functions(self): utils.assert_functions_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-9) def test_forces_and_tractions(self): utils.assert_forces_allclose(self.handler, self.CFDSolver, tol=1e-10) utils.assert_tractions_allclose(self.handler, self.CFDSolver, tol=1e-10) # Reset the option self.CFDSolver.setOption("forcesAsTractions", True) # Make sure we can write the force file. forces_file = os.path.join(self.CFDSolver.getOption("outputdirectory"), "forces.txt") self.CFDSolver.writeForceFile(forces_file) # ------------------- Derivative routine checks ---------------------------- def test_jac_vec_prod_fwd(self): utils.assert_fwd_mode_allclose(self.handler, self.CFDSolver, self.ap, tol=5e-9) def test_jac_vec_prod_bwd(self): utils.assert_bwd_mode_allclose(self.handler, self.CFDSolver, self.ap, tol=1e-10) def test_dot_products(self): utils.assert_dot_products_allclose(self.handler, self.CFDSolver, tol=1e-10)
def MFMC(self): # Use an MFMC algorithm to determine optimal sample distribution and coefficients among mesh levels # We do this once before optimization, then compute statistics with the same set of samples and coeffs at every iteration # start with initial samples # Get a set of UQ sample points (LHS), enough for each level at the start #sys.stdout = open(os.devnull, "w") # flow characteristics alpha = 0.0 mach = self.ooptions['mach'] #0.95 Re = self.ooptions['Re'] #50000 Re_L = 1.0 tempR = 540 arearef = 2.0 chordref = 1.0 a_init = self.DVGeo.getValues() a_init['pnts'][:] = self.ooptions['DVInit'] self.current_samples = self.NS0 * self.Lmax if rank == 0: rank0sam = plate_sa_lhs.genLHS(s=self.current_samples) else: rank0sam = None self.sample = comm.bcast(rank0sam, root=0) N1 = [] a1 = numpy.zeros(self.Lmax) r1 = numpy.zeros(self.Lmax) # Scatter samples on each level, multi-point parallelism for i in range(self.Lmax): self.cases.append(divide_cases(self.NS0, size)) for j in range(len(self.cases[i])): for k in range(len(self.cases[i][j])): self.cases[i][j][k] += i * self.NS0 #self.nsp.append(len(self.cases[i][rank]))#int(ns/size) # samples per processor self.samplep.append(self.sample[self.cases[i][rank]]) #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() # for i in range(self.Lmax): # assert len(self.samplep[i]) == self.nsp[i] # Create solvers for the preliminary data nslp = [] nslt = [] for k in range(self.Lmax): alist = [] slist = [] mlist = [] nslp.append(len(self.cases[k][rank])) nslt.append(sum([len(self.cases[k][x]) for x in range(size)])) for i in range(nslp[k]): namestr = self.gridSol + "_" + str(self.cases[k][rank][i]) # create meshes leveloptions = self.woptions leveloptions['gridFile'] = self.meshnames[self.mord[k]] #import pdb; pdb.set_trace() mlist.append(USMesh(options=leveloptions, comm=MPI.COMM_SELF)) # create aeroproblems aloptions = self.aoptions aloptions['gridFile'] = self.meshnames[self.mord[k]] alist.append( AeroProblem(name=namestr, alpha=alpha, mach=mach, reynolds=Re, reynoldsLength=Re_L, T=tempR, areaRef=arearef, chordRef=chordref, evalFuncs=['cd'])) time.sleep(0.1) # this solves a few problems for some reason # create solvers slist.append(ADFLOW(options=aloptions, comm=MPI.COMM_SELF)) # if not self.ooptions['run_once']: # saconstsm = self.samplep[i].tolist() # else: saconstsm = self.samplep[0][i].tolist() self.saconsts = saconstsm + self.saconstsb slist[i].setOption('SAConsts', self.saconsts) slist[i].setDVGeo(self.DVGeo) slist[i].setMesh(mlist[i]) coords = slist[i].getSurfaceCoordinates( groupName=slist[i].allWallsGroup) slist[i].DVGeo.addPointSet(coords, 'coords') self.aps.append(alist) self.solvers.append(slist) self.meshes.append(mlist) # Solve the preliminary samples # start looping over mesh levels sumt = [] sumtp = [] nslp = [] nslt = [] sum1 = [] mus = [] sump = [] musp = [] sumpm = [] muspm = [] summ = [] musm = [] Et = numpy.zeros(self.Lmax) E = numpy.zeros(self.Lmax) V = numpy.zeros(self.Lmax) S = numpy.zeros(self.Lmax) N1 = [] for k in range(self.Lmax): nslp.append(len(self.cases[k][rank])) nslt.append(sum([len(self.cases[k][x]) for x in range(size)])) dvdict = {'pnts': a_init['pnts']} funcs = {} sumtp.append(0.0) sump.append(0.) musp.append(numpy.zeros(nslp[k])) sumpm.append(0.) muspm.append(numpy.zeros(nslp[k])) for i in range(nslp[k]): # just do this again in case saconstsm = self.samplep[0][i].tolist() self.saconsts = saconstsm + self.saconstsb self.solvers[k][i].setOption('SAConsts', self.saconsts) self.solvers[k][i].DVGeo.setDesignVars(dvdict) self.aps[k][i].setDesignVars(dvdict) pc0 = time.process_time() self.solvers[k][i](self.aps[k][i]) self.solvers[k][i].evalFunctions(self.aps[k][i], funcs) pc1 = time.process_time() astr = self.gridSol + "_" + str(self.cases[k][rank][i]) + "_cd" musp[k][i] = funcs[astr] sump[k] += funcs[astr] sumtp[k] += (pc1 - pc0) # compute mean and variance estimate from start up samples for k in range(self.Lmax): sumt.append(comm.allreduce(sumtp[k])) sum1.append(comm.allreduce(sump[k])) mus.append(comm.allgather(musp[k])) summ.append(comm.allreduce(sumpm[k])) musm.append(comm.allgather(muspm[k])) mus[k] = numpy.concatenate(mus[k][:]) musm[k] = numpy.concatenate(musm[k][:]) #import pdb; pdb.set_trace() # mean at each level Et[k] = sumt[k] / nslt[k] E[k] = (sum1[k]) / nslt[k] #+summ[k] sum2 = 0. for i in range(len(mus[k])): #loop over processors sum2 += (mus[k][i] - E[k])**2 V[k] = sum2 / nslt[k] S[k] = math.sqrt(V[k]) # compute correlation matrix and rearrange models if necessary ordered = False while not ordered: rho = numpy.corrcoef(mus) ordered = True # check if contradicted #tarr = rho[0,1:] for k in range(self.Lmax - 2): test = rho[0, 1 + k]**2 - rho[0, 2 + k]**2 if test < 0: ordered = False tarr = -rho[0, :]**2 if not ordered: sind = numpy.argsort(tarr) #import pdb; pdb.set_trace() self.mord[:] = [self.mord[i] for i in sind] E[:] = [E[i] for i in sind] Et[:] = [Et[i] for i in sind] V[:] = [V[i] for i in sind] S[:] = [S[i] for i in sind] mus[:] = [mus[i] for i in sind] # now compute N1 and a1 using sigma, rho, w, and p for k in range(self.Lmax): a1[k] = S[0] * rho[0, k] / S[k] if k == 0: r1[k] = 1 elif k == self.Lmax - 1: work = Et[0] * (rho[0, k]**2) work /= Et[k] * (1 - rho[0, 1]**2) r1[k] = math.sqrt(work) else: work = Et[0] * (rho[0, k - 1]**2 - rho[0, k]**2) work /= Et[k] * (1 - rho[0, 1]**2) r1[k] = math.sqrt(work) for k in range(self.Lmax): N1.append(0) nsf = self.P / numpy.dot(Et, r1) N1[0] = math.ceil(nsf) for k in range(self.Lmax): nsf = N1[0] * r1[k] N1[k] = math.ceil(nsf) # limit the number of samples on the last one to pass the sanity check, for debug sanity = numpy.dot(N1, Et) if sanity > 1.2 * self.P: N1n = (self.P - numpy.dot(N1[0:self.Lmax - 2], Et[0:self.Lmax - 2])) / Et[self.Lmax - 1] N1[self.Lmax - 1] = math.ceil(N1n) self.Pr = numpy.dot(N1, Et) self.N1 = N1 self.a1 = a1 #import pdb; pdb.set_trace() if rank == 0: print("MFMC Completed, Samples per level: ", N1)
True }) h = 1e-40 # Setup aeroproblem, cfdsolver ap = AeroProblem(name='mdo_tutorial', alpha=1.8, mach=0.80, R=287.87, altitude=10000.0, areaRef=45.5, chordRef=3.25, evalFuncs=['cl', 'cmz', 'drag']) ap.addDV('alpha') ap.addDV('mach') CFDSolver = ADFLOW(options=aeroOptions) if 'complex' in sys.argv: DVGeo = DVGeometry('../inputFiles/mdo_tutorial_ffd.fmt', complex=True) else: DVGeo = DVGeometry('../inputFiles/mdo_tutorial_ffd.fmt', complex=False) nTwist = 2 DVGeo.addRefAxis( 'wing', pyspline.Curve(x=numpy.linspace(5.0 / 4.0, 1.5 / 4.0 + 7.5, nTwist), y=numpy.zeros(nTwist), z=numpy.linspace(0, 14, nTwist), k=2)) def twist(val, geo):
def setUp(self): super().setUp() self.options = { "gridfile": os.path.join(baseDir, "../../input_files/actuator_test_pipe.cgns"), # the restart file was ran with thrust = 600 N and heat = 1e5 W "restartfile": os.path.join(baseDir, "../../input_files/actuator_test_pipe.cgns"), "writevolumesolution": False, "writesurfacesolution": False, "writetecplotsurfacesolution": False, "mgcycle": "sg", "ncycles": 1000, "useanksolver": True, "usenksolver": True, "anksecondordswitchtol": 1e-2, "nkswitchtol": 1e-4, "volumevariables": ["temp", "mach", "resrho"], "surfacevariables": ["temp", "vx", "vy", "vz", "p", "ptloss", "mach", "rho"], "equationType": "Euler", "l2convergence": 1e-13, "adjointl2convergence": 1e-13, } options = copy.copy(adflowDefOpts) options["outputdirectory"] = os.path.join(baseDir, options["outputdirectory"]) options.update(self.options) CFDSolver = ADFLOW(options=options) CFDSolver.addFunction("mdot", "inlet", name="mdot_in") CFDSolver.addFunction("mdot", "outlet", name="mdot_out") CFDSolver.addFunction("aavgptot", "outlet", name="aavgptot_out") CFDSolver.addFunction("aavgptot", "inlet", name="aavgptot_in") CFDSolver.addFunction("mavgttot", "outlet", name="mavgttot_out") CFDSolver.addFunction("mavgttot", "inlet", name="mavgttot_in") CFDSolver.addFunction("aavgps", "outlet", name="aavgps_out") CFDSolver.addFunction("aavgps", "inlet", name="aavgps_in") CFDSolver.addFunction("area", "inlet", name="area_in") CFDSolver.addFunction("area", "outlet", name="area_out") CFDSolver.addFunction("mavgvx", "inlet", name="mavgvx_in") CFDSolver.addFunction("mavgvx", "outlet", name="mavgvx_out") CFDSolver.addFunction("forcexpressure", "inlet", name="forcexpressure_in") CFDSolver.addFunction("forcexpressure", "outlet", name="forcexpressure_out") CFDSolver.addFunction("forcexmomentum", "inlet", name="forcexmomentum_in") CFDSolver.addFunction("forcexmomentum", "outlet", name="forcexmomentum_out") self.CFDSolver = CFDSolver # this is imported from reg_aeroproblems utility script self.ap = ap_actuator_pipe actuatorFile = os.path.join( baseDir, "../../input_files/actuator_test_disk.xyz") self.CFDSolver.addActuatorRegion( actuatorFile, np.array([0, 0, 0]), np.array([1, 0, 0]), "actuator_region", # we will set these individually in the tests below thrust=0.0, torque=0.0, heat=0.0, ) # add thrust and heat as AP DVs self.ap.setBCVar("Thrust", 0.0, "actuator_region") self.ap.addDV("Thrust", family="actuator_region", units="N", name="thrust") self.ap.setBCVar("Heat", 0.0, "actuator_region") self.ap.addDV("Heat", family="actuator_region", units="J/s", name="heat") # also add flowpower as an AZ function CFDSolver.addFunction("flowpower", "actuator_region", name="flowpower_az")