#! /usr/bin/env python from PyFoam.Applications.PlotRunner import PlotRunner PlotRunner()
def run3dHillBase(template0, AR, z0, us, caseType): # loading other parameters from dictionary file inputDict = ParsedParameterFile("testZ0InfluenceDict") h = inputDict["simParams"]["h"] yM = inputDict["simParams"]["yM"] # SHM parameters cell = inputDict["SHMParams"]["cellSize"]["cell"] Href = inputDict["SHMParams"]["domainSize"]["domZ"] zz = inputDict["SHMParams"]["pointInDomain"]["zz"] # case definitions Martinez2DBump ks = 19.58 * z0 # [m] Martinez 2011 k = inputDict["kEpsParams"]["k"] Cmu = inputDict["kEpsParams"]["Cmu"] # yp/ks = 0.02 = x/ks hSample = inputDict["sampleParams"]["hSample"] procnr = multiprocessing.cpu_count() caseStr = "_z0_" + str(z0) target = "runs/" + template0 + caseStr x0, y0, phi = inputDict["SHMParams"]["centerOfDomain"]["x0"], inputDict["SHMParams"]["centerOfDomain"]["x0"], \ inputDict["SHMParams"]["flowOrigin"]["deg"]*pi/180 H = h a = h*AR #-------------------------------------------------------------------------------------- # cloning case #-------------------------------------------------------------------------------------- orig = SolutionDirectory(template0, archive=None, paraviewLink=False) work = orig.cloneCase(target) #-------------------------------------------------------------------------------------- # changing inlet profile - - - - according to Martinez 2010 #-------------------------------------------------------------------------------------- # change inlet profile Uref = Utop = us/k*math.log(Href/z0) # calculating turbulentKE TKE = us*us/math.sqrt(Cmu) # 1: changing ABLConditions bmName = path.join(work.initialDir(),"include/ABLConditions") template = TemplateFile(bmName+".template") template.writeToFile(bmName,{'us':us,'Uref':Uref,'Href':Href,'z0':z0,'xDirection':sin(phi),'yDirection':cos(phi)}) # 2: changing initialConditions bmName = path.join(work.initialDir(),"include/initialConditions") template = TemplateFile(bmName+".template") template.writeToFile(bmName,{'TKE':TKE}) # 3: changing initial and boundary conditions for new z0 # changing ks in nut, inside nutRoughWallFunction nutFile = ParsedParameterFile(path.join(work.initialDir(),"nut")) nutFile["boundaryField"]["ground"]["Ks"].setUniform(ks) nutFile["boundaryField"]["terrain_.*"]["Ks"].setUniform(ks) nutFile.writeFile() #-------------------------------------------------------------------------------------- # changing sample file #-------------------------------------------------------------------------------------- # 2: changing initialConditions bmName = path.join(work.systemDir(),"sampleDict") template = TemplateFile(bmName+".template") if AR>100:# flat terrain h=0 template.writeToFile(bmName,{'hillTopY':0,'sampleHeightAbovePlain':50,'sampleHeightAboveHill':50,'inletX':3500}) else: template.writeToFile(bmName,{'hillTopY':h,'sampleHeightAbovePlain':50,'sampleHeightAboveHill':h+50,'inletX':h*AR*4*0.9}) # if SHM - create mesh if caseType.find("SHM")>0: phi = phi - pi/180 * 90 #-------------------------------------------------------------------------------------- # creating blockMeshDict #-------------------------------------------------------------------------------------- l, d = a*inputDict["SHMParams"]["domainSize"]["fX"], a*inputDict["SHMParams"]["domainSize"]["fY"] x1 = x0 - (l/2*sin(phi) + d/2*cos(phi)) y1 = y0 - (l/2*cos(phi) - d/2*sin(phi)) x2 = x0 - (l/2*sin(phi) - d/2*cos(phi)) y2 = y0 - (l/2*cos(phi) + d/2*sin(phi)) x3 = x0 + (l/2*sin(phi) + d/2*cos(phi)) y3 = y0 + (l/2*cos(phi) - d/2*sin(phi)) x4 = x0 + (l/2*sin(phi) - d/2*cos(phi)) y4 = y0 + (l/2*cos(phi) + d/2*sin(phi)) n = floor(d/(cell*inputDict["SHMParams"]["cellSize"]["cellYfactor"])) m = floor(l/(cell*inputDict["SHMParams"]["cellSize"]["cellYfactor"])) q = floor((Href+450)/cell) # -450 is the minimum of the blockMeshDict.template - since that is slightly lower then the lowest point on the planet bmName = path.join(work.constantDir(),"polyMesh/blockMeshDict") template = TemplateFile(bmName+".template") template.writeToFile(bmName,{'X0':x1,'X1':x2,'X2':x3,'X3':x4,'Y0':y1,'Y1':y2,'Y2':y3,'Y3':y4,'Z0':Href,'n':int(n),'m':int(m),'q':int(q)}) #-------------------------------------------------------------------------------------- # running blockMesh #-------------------------------------------------------------------------------------- blockRun = BasicRunner(argv=["blockMesh",'-case',work.name],silent=True,server=False,logname="blockMesh") print "Running blockMesh" blockRun.start() if not blockRun.runOK(): error("there was an error with blockMesh") #-------------------------------------------------------------------------------------- # running SHM #-------------------------------------------------------------------------------------- print "calculating SHM parameters" # calculating refinement box positions l1, l2, h1, h2 = 2*a, 1.3*a, 4*H, 2*H # refinement rulls - Martinez 2011 refBox1_minx, refBox1_miny, refBox1_minz = x0 - l1*(sin(phi)+cos(phi)), y0 - l1*(cos(phi)-sin(phi)), 0 #enlarging to take acount of the rotation angle refBox1_maxx, refBox1_maxy, refBox1_maxz = x0 + l1*(sin(phi)+cos(phi)), y0 + l1*(cos(phi)-sin(phi)), h1 #enlarging to take acount of the rotation angle refBox2_minx, refBox2_miny, refBox2_minz = x0 - l2*(sin(phi)+cos(phi)), y0 - l2*(cos(phi)-sin(phi)), 0 #enlarging to take acount of the rotation angle refBox2_maxx, refBox2_maxy, refBox2_maxz = x0 + l2*(sin(phi)+cos(phi)), y0 + l2*(cos(phi)-sin(phi)),h2 #enlarging to take acount of the rotation angle # changing cnappyHexMeshDict - with parsedParameterFile SHMDict = ParsedParameterFile(path.join(work.systemDir(),"snappyHexMeshDict")) SHMDict["geometry"]["refinementBox1"]["min"] = "("+str(refBox1_minx)+" "+str(refBox1_miny)+" "+str(refBox1_minz)+")" SHMDict["geometry"]["refinementBox1"]["max"] = "("+str(refBox1_maxx)+" "+str(refBox1_maxy)+" "+str(refBox1_maxz)+")" SHMDict["geometry"]["refinementBox2"]["min"] = "("+str(refBox2_minx)+" "+str(refBox2_miny)+" "+str(refBox2_minz)+")" SHMDict["geometry"]["refinementBox2"]["max"] = "("+str(refBox2_maxx)+" "+str(refBox2_maxy)+" "+str(refBox2_maxz)+")" SHMDict["castellatedMeshControls"]["locationInMesh"] = "("+str(x0)+" "+str(y0)+" "+str(zz)+")" levelRef = inputDict["SHMParams"]["cellSize"]["levelRef"] SHMDict["castellatedMeshControls"]["refinementSurfaces"]["terrain"]["level"] = "("+str(levelRef)+" "+str(levelRef)+")" r = inputDict["SHMParams"]["cellSize"]["r"] SHMDict["addLayersControls"]["expansionRatio"] = r fLayerRatio = inputDict["SHMParams"]["cellSize"]["fLayerRatio"] SHMDict["addLayersControls"]["finalLayerThickness"] = fLayerRatio # calculating finalLayerRatio for getting zp_z0 = inputDict["SHMParams"]["cellSize"]["zp_z0"] firstLayerSize = 2*zp_z0*z0 L = math.log(fLayerRatio/firstLayerSize*cell/2**levelRef)/math.log(r)+1 SHMDict["addLayersControls"]["layers"]["terrain_solid"]["nSurfaceLayers"] = int(round(L)) SHMDict.writeFile() """ # changing snappyHexMeshDict - with template file snapName = path.join(work.systemDir(),"snappyHexMeshDict") template = TemplateFile(snapName+".template") template.writeToFile(snapName,{ 'refBox1_minx':refBox1_minx,'refBox1_miny':refBox1_miny,'refBox1_minz':refBox1_minz, 'refBox1_maxx':refBox1_maxx,'refBox1_maxy':refBox1_maxy,'refBox1_maxz':refBox1_maxz, 'refBox2_minx':refBox2_minx,'refBox2_miny':refBox2_miny,'refBox2_minz':refBox2_minz, 'refBox2_maxx':refBox2_maxx,'refBox2_maxy':refBox2_maxy,'refBox2_maxz':refBox2_maxz, 'locInMesh_x':x0,'locInMesh_y':y0,'locInMesh_z':zz}) """ # TODO - add parallel runs! SHMrun = BasicRunner(argv=["snappyHexMesh",'-overwrite','-case',work.name],server=False,logname="SHM") print "Running SHM" SHMrun.start() # mapping fields - From earlier result if exists if caseType.find("mapFields")>0: #TODO - fix mapping issue. mucho importante! #copying results from other z0 converged runs setName = glob.glob(target + 'Crude/sets/*') lastRun = range(len(setName)) for num in range(len(setName)): lastRun[num] = int(setName[num][setName[num].rfind("/")+1:]) sourceTimeArg = str(max(lastRun)) mapRun = BasicRunner(argv=['mapFields -consistent -sourceTime ' + sourceTimeArg + ' -case ' + work.name + ' ' + target + "Crude"],silent=True,server=False,logname='mapLog') mapRun.start() # parallel rule #print "Mesh has " + str(cells) + " cells" #if cells>100000: parallel=1 #else: parallel=0 parallel = 1 cluster = 1 if parallel: #-------------------------------------------------------------------------------------- # decomposing #-------------------------------------------------------------------------------------- # removing U.template from 0/ directory subprocess.call("rm " + bmName + ".template ",shell=True) arg = " -case " + work.name decomposeRun = BasicRunner(argv=["decomposePar -force" + arg],silent=True,server=False,logname="decompose") decomposeRun.start() #-------------------------------------------------------------------------------------- # running #-------------------------------------------------------------------------------------- machine = LAMMachine(nr=procnr) # run case PlotRunner(args=["--proc=%d"%procnr,"--progress","--no-continuity","--hardcopy", "--non-persist", "simpleFoam","-case",work.name]) #-------------------------------------------------------------------------------------- # reconstruct #------------------------------------------------------------------------- reconstructRun = BasicRunner(argv=["reconstructPar -latestTime" + arg],silent=True,server=False,logname="reconstructLog") reconstructRun.start() else: #-------------------------------------------------------------------------------------- # running #-------------------------------------------------------------------------------------- PlotRunner(args=["--progress","simpleFoam","-case",work.name]) # sample results dirNameList = glob.glob(target + "*") dirNameList.sort() for dirName in dirNameList: # sampling arg = " -case " + dirName + "/" sampleRun = BasicRunner(argv=["sample -latestTime" + arg],silent=True,server=False,logname="sampleLog") sampleRun.start() #finding the most converged run. setName = glob.glob(dirName + '/sets/*') lastRun = range(len(setName)) for num in range(len(setName)): lastRun[num] = int(setName[num][setName[num].rfind("/")+1:]) m = max(lastRun) p = lastRun.index(m) data_y = genfromtxt(setName[p] + '/line_y_U.xy',delimiter=' ') y, Ux_y, Uy_y = data_y[:,0], data_y[:,1], data_y[:,2] if AR<100: # if terrain isn't flat #TODO find the height of the hill - the exact one! because of truncation errors etc - #just follow the line measurements and look for the first place above 0 h = min(data_y[:,0]) y = y-h # normalizing data to height of hill-top above ground return y,Ux_y,Uy_y
def run((i, d)): target, args = d['target'], d['args'] time.sleep(i * 2) print "got %s" % repr(args) return PlotRunner(args=args)
import sys case = "/home/weibin/test" from PyFoam.Applications.Decomposer import Decomposer from PyFoam.Applications.Runner import Runner from PyFoam.Applications.PlotRunner import PlotRunner PlotRunner(args=["--progress", "Decomposer", "proc", 2, "-case", case]) PlotRunner(args=["--clear", "blockMesh", "-case", case]) Runner(args=["--progress", "icoFoam", "-case", case])
logname="SHM") print "Running SHM" SHMrun.start() sys.exit(6) #-------------------------------------------------------------------------------------- # running decomposePar #-------------------------------------------------------------------------------------- #-------------------------------------------------------------------------------------- # running SimpleFoam #-------------------------------------------------------------------------------------- machine = LAMMachine(nr=procnr) # run case PlotRunner(args=[ "--proc=%d" % procnr, "--with-all", "--progress", "simpleFoam", "-case", work.name ]) #PlotRunner(args=["simpleFoam","-parallel","- proc =% d " % procnr, "-case",work.name]) print "work.name = ", work.name Runner(args=["reconstructPar", "-latestTime", "-case", work.name]) # plotting if plotMartinez: import plotMartinez2DBump plotMartinez2DBump.main(target, hSample) plt.show() elif plotAll: import plot2dHill plot2dHill.main(target, "U phi k TI") plt.show()
def run2dHillBase(template0, target0, hillName, AR, r, x, Ls, L, L1, H, x0, z0, us, yM, h, caseType): # case definitions Martinez2DBump ks = 19.58 * z0 # [m] Martinez 2011 k = 0.4 Cmu = 0.03 # Castro 96 Htop = Href = H # [m] # yp/ks = 0.02 = x/ks funky = 0 plotMartinez = 1 hSample = 10 fac = 10 # currecting calculation of number of cells and Rx factor to get a smooth transition # from the inner refined cell and the outer less refined cells of the blockMesh Mesh procnr = 8 caseStr = "_AR_" + str(AR) + "_z0_" + str(z0) if caseType == "Crude": caseStr = caseStr + "Crude" target = target0 + caseStr orig = SolutionDirectory(template0, archive=None, paraviewLink=False) #-------------------------------------------------------------------------------------- # cloaning case #-------------------------------------------------------------------------------------- work = orig.cloneCase(target) #-------------------------------------------------------------------------------------- # creating mesh #-------------------------------------------------------------------------------------- y0 = 2 * x * z0 # setting first cell according to Martinez 2011 p. 25 ny = int(round( math.log(H / y0 * (r - 1) + 1) / math.log(r))) # number of cells in the y direction of the hill block Ry = r**(ny - 1.) nx = int(L / x0 - 1) rx = max(r, 1.1) ns = int( round(math.log((Ls - L) / x0 * (rx - 1) / rx**fac + 1) / math.log(rx)) ) # number of cells in the x direction of the hill block Rx = rx**(ns - 1) # changing blockMeshDict - from template file if AR == 1000: # if flat terrain bmName = path.join(work.constantDir(), "polyMesh/blockMeshDict") template = TemplateFile(bmName + "_flat_3cell.template") else: bmName = path.join(work.constantDir(), "polyMesh/blockMeshDict") template = TemplateFile(bmName + "_3cell.template") template.writeToFile( bmName, { 'H': H, 'ny': ny, 'Ry': Ry, 'nx': nx, 'L': L, 'L1': L1, 'Ls': Ls, 'Rx': Rx, 'Rx_one_over': 1 / Rx, 'ns': ns }) # writing ground shape (hill, or whatever you want - equation in function writeGroundShape.py) # sample file is changed as well - for sampling h=10 meters above ground sampleName = path.join(work.systemDir(), "sampleDict.template") write2dShape(bmName, H, L, sampleName, hSample, hillName, AR) # changing Y line limits bmName = path.join(work.systemDir(), "sampleDict") template = TemplateFile(bmName + ".template") if AR == 1000: # if flat terrain template.writeToFile(bmName, {'hillTopY': 0, 'maxY': yM * 10}) else: template.writeToFile(bmName, {'hillTopY': h, 'maxY': yM * 10 + h}) # running blockMesh blockRun = BasicRunner(argv=["blockMesh", '-case', work.name], silent=True, server=False, logname="blockMesh") blockRun.start() if not blockRun.runOK(): error("there was an error with blockMesh") #-------------------------------------------------------------------------------------- # changing inlet profile - - - - according to Martinez 2010 #-------------------------------------------------------------------------------------- # change inlet profile Uref = Utop = us / k * math.log(Href / z0) # calculating turbulentKE TKE = us * us / math.sqrt(Cmu) # 1: changing ABLConditions bmName = path.join(work.initialDir(), "include/ABLConditions") template = TemplateFile(bmName + ".template") template.writeToFile(bmName, { 'us': us, 'Uref': Uref, 'Href': Href, 'z0': z0 }) # 2: changing initialConditions bmName = path.join(work.initialDir(), "include/initialConditions") template = TemplateFile(bmName + ".template") template.writeToFile(bmName, {'TKE': TKE}) if funky: # 3: changing U (inserting variables into groovyBC for inlet profile) bmName = path.join(work.initialDir(), "U") template = TemplateFile(bmName + ".template") template.writeToFile(bmName, { 'us': us, 'z0': z0, 'K': k, 'Utop': Utop }) # 4: changing k (inserting variables into groovyBC for inlet profile) bmName = path.join(work.initialDir(), "k") template = TemplateFile(bmName + ".template") template.writeToFile(bmName, { 'us': us, 'z0': z0, 'K': k, 'Utop': Utop, 'Cmu': Cmu }) # 5: changing epsilon (inserting variables into groovyBC for inlet profile) bmName = path.join(work.initialDir(), "epsilon") template = TemplateFile(bmName + ".template") template.writeToFile(bmName, { 'us': us, 'z0': z0, 'K': k, 'Utop': Utop, 'Cmu': Cmu }) # 6: changing initial and boundary conditions for new z0 # changing ks in nut, inside nutRoughWallFunction nutFile = ParsedParameterFile(path.join(work.initialDir(), "nut")) nutFile["boundaryField"]["ground"]["Ks"].setUniform(ks) nutFile.writeFile() # 7: changing convergence criterion for Crude runs if caseType == "Crude": fvSolutionFile = ParsedParameterFile( path.join(work.systemDir(), "fvSolution")) fvSolutionFile["SIMPLE"]["residualControl"]["p"] = 1e-4 fvSolutionFile["SIMPLE"]["residualControl"]["U"] = 1e-4 fvSolutionFile.writeFile() # mapping fields - From earlier result if exists if caseType == "mapFields": #finding the most converged run. assuming the "crude" run had the same dirName with "Crude" attached setName = glob.glob(target + 'Crude/sets/*') lastRun = range(len(setName)) for num in range(len(setName)): lastRun[num] = int(setName[num][setName[num].rfind("/") + 1:]) sourceTimeArg = str(max(lastRun)) mapRun = BasicRunner(argv=[ 'mapFields -consistent -sourceTime ' + sourceTimeArg + ' -case ' + work.name + ' ' + target + "Crude" ], silent=True, server=False, logname='mapLog') mapRun.start() # parallel rule cells = nx * (ny + 2 * ns) print "Mesh has " + str(cells) + " cells" if cells > 20000: parallel = 1 else: parallel = 0 if parallel: #-------------------------------------------------------------------------------------- # decomposing #-------------------------------------------------------------------------------------- # removing U.template from 0/ directory subprocess.call("rm " + bmName + ".template ", shell=True) arg = " -case " + work.name decomposeRun = BasicRunner(argv=["decomposePar -force" + arg], silent=True, server=False, logname="decompose") decomposeRun.start() #-------------------------------------------------------------------------------------- # running #-------------------------------------------------------------------------------------- machine = LAMMachine(nr=procnr) # run case PlotRunner(args=[ "--proc=%d" % procnr, "--progress", "simpleFoam", "-case", work.name ]) #-------------------------------------------------------------------------------------- # reconstruct #------------------------------------------------------------------------- reconstructRun = BasicRunner(argv=["reconstructPar -latestTime" + arg], silent=True, server=False, logname="reconstructLog") reconstructRun.start() else: #-------------------------------------------------------------------------------------- # running #-------------------------------------------------------------------------------------- PlotRunner(args=["--progress", "simpleFoam", "-case", work.name]) # sample results dirNameList = glob.glob(target + "*") dirNameList.sort() for dirName in dirNameList: # sampling arg = " -case " + dirName + "/" sampleRun = BasicRunner(argv=["sample -latestTime" + arg], silent=True, server=False, logname="sampleLog") sampleRun.start() #finding the most converged run. setName = glob.glob(dirName + '/sets/*') lastRun = range(len(setName)) for num in range(len(setName)): lastRun[num] = int(setName[num][setName[num].rfind("/") + 1:]) m = max(lastRun) p = lastRun.index(m) data_y = genfromtxt(setName[p] + '/line_y_U.xy', delimiter=' ') y, Ux_y, Uy_y = data_y[:, 0], data_y[:, 1], data_y[:, 2] if AR < 1000: # if terrain isn't flat y = y - h # normalizing data to height of hill-top above ground return y, Ux_y, Uy_y
print "Decomposing" Decomposer(args=["--progress", work.name, 2]) CaseReport(args=["--decomposition", work.name]) # running machine = LAMMachine(nr=2) # laminar case for better first guess (rarely converges for 2D case with simpleFoam) print "running laminar case" turb = ParsedParameterFile(path.join(work.name, 'constant/RASProperties')) turb["turbulence"] = "off" turb.writeFile() dic = ParsedParameterFile(path.join(work.name, 'system/controlDict')) dic["stopAt"] = "endTime" dic["endTime"] = 750 dic.writeFile() PlotRunner(args=["--proc=2", "simpleFoam", "-case", work.name]) # turbulent turned on print "turning turbulence on" turb["turbulence"] = "on" turb.writeFile() dic["endTime"] = 4000 dic.writeFile() PlotRunner(args=["--proc=2", "simpleFoam", "-case", work.name]) # if it hasn't converged in 4000 steps - just use the result you have. # post processing Runner(args=["reconstructPar", "-case", work.name]) # sampling (assuming sampleDict is edited seperately) os.system("sample") # plotting plot_z0.main(template)