See More

#!/usr/bin/env python ## \file run.py # \brief turbulent premixed dump combustor simulation (PSI flame) # phi=0.5, methane-air, U=40 m/s # \version 8.1.0 "Harrier" # # SU2 Project Website: https://su2code.github.io # # The SU2 Project is maintained by the SU2 Foundation # (http://su2foundation.org) # # Copyright 2012-2024, SU2 Contributors (cf. AUTHORS.md) # # SU2 is free software; you can redistribute it and/or # modify it under the terms of the GNU Lesser General Public # License as published by the Free Software Foundation; either # version 2.1 of the License, or (at your option) any later version. # # SU2 is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public # License along with SU2. If not, see . import sys import pysu2 import numpy as np # with mpi: from mpi4py import MPI comm = MPI.COMM_WORLD rank = comm.Get_rank() # without mpi: # comm = 0 Tref = 298.15 # flame temperature of the methane-air mixture (phi=0.5, P=5) Tf = 1777 # unburnt temperature of the methane-air mixture (phi=0.5, P=5) Tu = 673.0 Pu = 5.0 phi = 0.5 # unburnt density at P=5 rho_u = 2.52 # unburnt thermal conductivity of methane-air (phi=0.5, P=5) k_u = 0.0523 # unburnt heat capacity of methane-air (phi=0.5, P=5) cp_u = 1350.0 # P = rho*R*T # 5 = 2.55 * R * 673 # R = 0.0029 # ################################################################## # # create a function for the initial progress variable c # # ################################################################## # def initC(coord): x = coord[0] #y = coord[1] #z = coord[2] # location where the flame should be flame_x = 0.012 if (x < flame_x): C = 0.0 else: C = 1.0 return C # ################################################################## # # loop over all vertices and set the species progress variable c # # ################################################################## # def SetInitialSpecies(SU2Driver): allCoords = SU2Driver.Coordinates() iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] for iPoint in range(SU2Driver.GetNumberNodes() - SU2Driver.GetNumberHaloNodes()): coord = allCoords.Get(iPoint) C = initC(coord) # now update the initial condition for the species SU2Driver.Solution(iSPECIESSOLVER).Set(iPoint,0,C) # ################################################################## # # Temperature is an algebraic function of c # ################################################################## # def update_temperature(SU2Driver, iPoint): # first, get the progress variable iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] # Note: returns a list C = SU2Driver.Solution(iSPECIESSOLVER)(iPoint,0) T = Tu*(1-C) + Tf*C #prim_indices = SU2Driver.GetPrimitiveIndices() #iTemp = prim_indices['TEMPERATURE'] #SU2Driver.Primitives().Set(iPoint,iTemp, T) iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] iENTH = 3 SU2Driver.Solution(iFLOWSOLVER).Set(iPoint,iENTH, cp_u*(T-Tref)) # ################################################################## # # Source term according to Zimont # ################################################################## # def zimont(SU2Driver, iPoint, nDim): iSSTSOLVER = SU2Driver.GetSolverIndices()['SST'] tke, dissipation = SU2Driver.Solution(iSSTSOLVER)(iPoint) iSPECIESSOLVER = SU2Driver.GetSolverIndices()['SPECIES'] # get the gradient of species_0 gradc = SU2Driver.Gradient(iSPECIESSOLVER)(iPoint,0) primindex = SU2Driver.GetPrimitiveIndices() iDENSITY = primindex.get("DENSITY") iMU = primindex.get("LAMINAR_VISCOSITY") # laminar burning velocity of methane-air at phi=0.5, P=5 Slu = 0.232 rho = SU2Driver.Primitives()(iPoint,iDENSITY) mu = SU2Driver.Primitives()(iPoint,iMU) nu=mu/rho # Turbulent Flamespeed Closure with Dinkelacker correction up = np.sqrt((2.0/3.0) * tke ) lt = (0.09**0.75) * (tke**1.5) / dissipation Re = up*lt/nu Le = 1.0 Ut = Slu * (1.0 + (0.46/Le) * np.power(Re,0.25) * np.power(up/Slu,0.3) * np.power(Pu,0.2) ) norm_gradc = 0.0 for idim in range(nDim): norm_gradc += gradc[idim]*gradc[idim] norm_gradc = np.sqrt(norm_gradc) Sc = rho_u * Ut * norm_gradc return Sc # ################################################################## # # Get the list of solver variable names # ################################################################## # def getsolvar(SU2Driver): primindex = SU2Driver.GetPrimitiveIndices() iFLOWSOLVER = SU2Driver.GetSolverIndices()['INC.FLOW'] nVars = SU2Driver.Solution(iFLOWSOLVER).Shape()[1] varindex = primindex.copy() for prim in varindex.copy(): if varindex[prim] >=nVars: del varindex[prim] varindex = dict(sorted(varindex.items(), key=lambda item: item[1])) return varindex # ################################################################## # # Main routine # ################################################################## # def main(): # Initialize the primal driver of SU2, this includes solver preprocessing. try: driver = pysu2.CSinglezoneDriver('psi.cfg', 1, comm) except TypeError as exception: print('A TypeError occured in pysu2.CSinglezoneDriver : ', exception) raise if rank == 0: print("\n------------------------------ Begin Solver -----------------------------") sys.stdout.flush() nDim = driver.GetNumberDimensions() # index to the flow solver # C.FLOW # INC.FLOW # HEAT # FLAMELET # SPECIES # SA # SST iFLOWSOLVER = driver.GetSolverIndices()['INC.FLOW'] iSPECIESSOLVER = driver.GetSolverIndices()['SPECIES'] iSSTSOLVER = driver.GetSolverIndices()['SST'] # all the indices and the map to the names of the primitives primindex = driver.GetPrimitiveIndices() nElem = driver.GetNumberElements() nVars = driver.Solution(iFLOWSOLVER).Shape()[1] nVarsSpecies = driver.Solution(iSPECIESSOLVER).Shape()[1] nVarsTurb = driver.Solution(iSSTSOLVER).Shape()[1] if rank == 0: print("Dimensions of the problem = ",nDim) print("index of flow solver = ",iFLOWSOLVER) print("index of turbulence solver = ",iSSTSOLVER) print("indices of primitives=",primindex) print("number of primitives:",len(primindex)) print("number of elements:",nElem) print("number of flow solver variables:",nVars) print("number of species solver variables:",nVarsSpecies) print("number of turbulence solver variables:",nVarsTurb) sys.stdout.flush() # ### Check if we do a restart or not. ### with open('psi.cfg') as f: if 'RESTART_SOL= YES' in f.read(): if rank == 0: print("restarting from file") else: # We can set an initial condition by calling this function: if rank == 0: print("Using user defined initial condition.") SetInitialSpecies(driver) # super important to actually push the commands. sys.stdout.flush() # run N iterations for inner_iter in range(2000): if (rank==0): print("python iteration ", inner_iter) driver.Preprocess(inner_iter) driver.Run() Source = driver.UserDefinedSource(iSPECIESSOLVER) # set the source term, per point for i_node in range(driver.GetNumberNodes() - driver.GetNumberHaloNodes()): # add source term: # default TFC of Zimont: rho*Sc = rho_u * U_t * grad(c) S = zimont(driver,i_node, nDim) Source.Set(i_node,0,S) # for the update of temperature, we need to update also the halo nodes for i_node in range(driver.GetNumberNodes()): # set the temperature to T = c*Tf + (1-c)*Tu update_temperature(driver, i_node) driver.Postprocess() driver.Update() # Monitor the solver and output solution to file if required. #driver.Monitor(inner_iter) # Output the solution to file driver.Output(inner_iter) # Finalize the solver and exit cleanly. driver.Finalize() if __name__ == '__main__': main()