def finletBCWriter( caseDir, #need to specify case directory a0=0.01, h0=0.001, mDot=1e-3, alpha=1, liqName='DC10', cellW=0.150, cellL=0.300, nCellsW=150, nCellsL=300): #IMPORT BLOCK======================================================= import os import math from dfluidData import dfluidData # #GET THE DATA======================================================= #=================================================================== # EDITABLE #=================================================================== g = 9.81 [sigma, rho, mu, theta0, thetaA, thetaR] = dfluidData(liqName) beta = float((theta0 + thetaA + thetaR) / 3) / 180 * math.pi #get initial contact angle in radians #=================================================================== # DO NOT EDIT #=================================================================== # recalculation for ND mesh - lenght is ND by inlet height L = 1 #h0 a0, h0, cellL, cellW = a0 / L, h0 / L, cellL / L, cellW / L # auxiliary variables - meshing nCellsIn = int( round(a0 / cellW * nCellsW) + round(a0 / cellW * nCellsW) % 2) nCellsWVec = [(nCellsW - nCellsIn) / 2, nCellsIn, (nCellsW - nCellsIn) / 2] hVec = [] uVec = [] #~ for i in range(0,nCellsIn/2): #~ hVec.append(a0**2 - (2*i*a0/nCellsIn)**2) #~ for i in range(nCellsIn/2+1,nCellsIn) #~ hVec.append(a0**2 - (2*i*a0/nCellsIn)**2) Bsqrt = a0 * math.sqrt(rho * g * math.cos(alpha) / sigma) A = a0 * math.tan(beta) / (Bsqrt * math.sinh(Bsqrt)) #~ yVec = [(2*a0*i/float(nCellsIn) - a0) for i in range(nCellsIn+1)] #~ print yVec print 'sqrt(B) = ' + repr(Bsqrt) #~ print A # calculate the inlet profile shape for i in range(nCellsIn + 1): dzeta = 2 * i / float(nCellsIn) - 1 hVec.append(A * (math.cosh(Bsqrt) - math.cosh(Bsqrt * dzeta))) #calculate the inlet profile cross section step = 2 * a0 / float(nCellsIn) cSec = 0 for i in range(len(hVec) - 1): cSec = cSec + hVec[i + 1] + hVec[i] cSec = cSec * step / 2 #calculate the inlet liquid velocity to sustain demanded mDot u0 = mDot / rho / cSec #~ for i in range(len(hVec)): #~ uVec.append([hVec[i]**2*rho*g/(2*mu),0,0]) #~ print uVec #======================================================================= #======================================================================= #CREATE FILE AND WRITE THE DATA IN====================================== idStr = 'inlet' # write everything to the file # Uf with open(caseDir + '0.org/wallFilmRegion/Uf', 'r') as file: # read a list of lines into data data = file.readlines() for i in range(len(data)): fInd = data[i].find(idStr) if fInd > -1: data[i:] = [] break with open(caseDir + '0.org/wallFilmRegion/Uf', 'w') as file: file.writelines(data) bMD = open(caseDir + '0.org/wallFilmRegion/Uf', 'a') #open file temporary file for writing #----------------------------------------------------------------------- # write data to file # -- case of dirichlet boundary #~ bMD.write('\tinlet \n\t{ \n') #~ bMD.write('\t\ttype\tfixedValue;\n') #~ bMD.write('\t\tvalue\tnonuniform List<vector> \n\t\t' + repr(nCellsIn) + '\n\t\t(\n') #~ for row in uVec: #~ bMD.write('\t\t\t ( ' + ' '.join(str(e) for e in row) + ' )\n') #~ bMD.write('\t\t); \n') #~ bMD.write('\t} \n\n') #~ bMD.write('}\n\n') # -- case of flowRateInletVelocity (could it be applied?) #~ bMD.write('\tinlet \n\t{ \n') #~ bMD.write('\t\ttype\tflowRateInletVelocity;\n') #~ bMD.write('\t\tmassFlowRate\tconstant\t' + repr(mDot) + ';\n') #~ bMD.write('\t\tvalue\t\tuniform (1 0 0);\n') #~ bMD.write('\t} \n\n') #~ bMD.write('}\n\n') # -- case of constant velocity bMD.write('\tinlet \n\t{ \n') bMD.write('\t\ttype\tfixedValue;\n') bMD.write('\t\tvalue\tuniform \t\t(%5.4e 0 0);\n' % u0) bMD.write('\t} \n\n') bMD.write('}\n\n') #----------------------------------------------------------------------- # footline bMD.write( '// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // \n\n' ) #----------------------------------------------------------------------- # close file bMD.close() # deltaf with open(caseDir + '0.org/wallFilmRegion/deltaf', 'r') as file: # read a list of lines into data data = file.readlines() for i in range(len(data)): fInd = data[i].find(idStr) if fInd > -1: data[i:] = [] break with open(caseDir + '0.org/wallFilmRegion/deltaf', 'w') as file: file.writelines(data) bMD = open(caseDir + '0.org/wallFilmRegion/deltaf', 'a') #open file temporary file for writing #----------------------------------------------------------------------- # write data to file bMD.write('\tinlet \n\t{ \n') bMD.write('\t\ttype\tfixedValue;\n') bMD.write('\t\tvalue\tnonuniform List<scalar> \n\t\t' + repr(nCellsIn + 1) + '\n\t\t(\n') for i in range(len(hVec)): bMD.write('\t\t\t ' + repr(hVec[i]) + '\n') bMD.write('\t\t); \n') bMD.write('\t} \n\n') bMD.write('}\n\n') #~ bMD.write('\tinlet \n\t{ \n') #~ bMD.write('\t\ttype\tfixedValue;\n') #~ bMD.write('\t\tvalue\tuniform \t\t' + repr(h0) + ';\n') #~ bMD.write('\t} \n\n') #~ bMD.write('}\n\n') #----------------------------------------------------------------------- # footline bMD.write( '// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // \n\n' ) #----------------------------------------------------------------------- # close file bMD.close() return
postProc, #case postprocessing (paraview) postProcData, #case postprocessing data export fluidData, #used database with fluid data #~ rivuletPostProc2Blender, #export paraview->blender #~ blenderPrep, #rivulet postprocessing (blender) ] for scName in scNames: sh.copyfile(scFolder + scName + '.py',caseDir + scName + '.py') #copy current script version #CASE CONSTANTS AND CALCULATIONS======================================== # input data------------------------------------------------------------ # -- global parameters g = 9.81 #grav. acc., m/s2 # -- liquid properties [sigma,rho,mu,theta0,thetaA,thetaR] = dfluidData(liqName) [_,rhoA,muA,_,_,_] = dfluidData('AIR') #~ NOTE: liquid properties are stored in a special dictionary #~ sigma ... surface tension coefficient of the liquid, N/m #~ rho ... density of the liquid, kg/m3 #~ mu ... liquid dynamic viscosity, Pas #~ theta0,thetaA,thetaR ... equilibrium, advancing and receding contact #~ angles # further calculations u0 = Re*mu/(rho*hIn) #inlet velocity calculation nu = [mu/rho,muA/rhoA] rho = [rho,rhoA] sigma = [sigma] #OPEN AUTOGENERATED README FILE=========================================
def fprepIC_noGravity(caseDir, #case directory name a0,Q0, #initial conditions liqName,l, #model defining properties alpha,L,nCellsX,H,nCellsZ, #geometrical and meshing parameters pltFlag, #output plots ): #IMPORT BLOCK======================================================= import math import numpy as np #~ from scipy.optimize import fsolve #NAE solver from scipy.integrate import odeint #ODE solver import matplotlib.pyplot as plt #IMPORT BLOCK-CUSTOM================================================ from dfluidData import dfluidData #LOCAL FUNCTIONS==================================================== def writeCylinder(h,a,x,deltaX): # function returning list o strings to write cylinderToCell entry # into setFieldsDict file R = h/2.0 + a**2.0/(2.0*h) #cylinder diameter d = R - h #how much bellow the plate is the cylinder center # -- create the strings to return cellStr = [] cellStr.append('\tcylinderToCell\n\t\t{\n') #entry openning lines cellStr.append('\t\t\tp1 (%5.5e %5.5e %5.5e);\n'%(x,0.0,-d)) cellStr.append('\t\t\tp2 (%5.5e %5.5e %5.5e);\n'%(x+deltaX,0.0,-d)) cellStr.append('\t\t\tradius %5.5e;\n\n'%R) cellStr.append('\t\t\tfieldValues\n\t\t\t(\n') cellStr.append('\t\t\t\tvolScalarFieldValue alpha.liquid 1\n\t\t\t);\n') cellStr.append('\t\t}\n') #entry ending line return cellStr def writeBox(h,deltah,a,x,deltaX,UVec,p_rgh): # function returning list of strings to write boxToCell entry into # setFieldsDict file cellStr = [] cellStr.append('\tboxToCell\n\t\t{\n') #entry openning lines cellStr.append('\t\t\tbox (%5.5e %5.5e %5.5e) (%5.5e %5.5e %5.5e);\n\n'%(x,-a,h,x+deltaX,a,h+deltah)) cellStr.append('\t\t\tfieldValues\n\t\t\t(\n') cellStr.append('\t\t\t\tvolVectorFieldValue U (%5.5e %5.5e %5.5e)\n'%tuple(UVec)) cellStr.append('\t\t\t\tvolScalarFieldValue p_rgh %5.5e\n\t\t\t);\n'%p_rgh) cellStr.append('\t\t}\n') #entry ending line return cellStr def writeBoxAlpha(h,deltah,a,x,deltaX,alpha): # function returning list of strings to write boxToCell entry into # setFieldsDict file cellStr = [] cellStr.append('\tboxToCell\n\t\t{\n') #entry openning lines cellStr.append('\t\t\tbox (%5.5e %5.5e %5.5e) (%5.5e %5.5e %5.5e);\n\n'%(x,-a,h,x+deltaX,a,h+deltah)) cellStr.append('\t\t\tfieldValues\n\t\t\t(\n') cellStr.append('\t\t\t\tvolScalarFieldValue alpha.liquid %5.5e\n\t\t\t);\n'%alpha) cellStr.append('\t\t}\n') #entry ending line return cellStr def writeRotBoxAlpha(origin,i,j,k,alpha): # function returning list of strings to write boxToCell entry into # setFieldsDict file cellStr = [] cellStr.append('\trotatedBoxToCell\n\t\t{\n') #entry openning lines cellStr.append('\t\t\torigin (%5.5e %5.5e %5.5e);\n'%tuple(origin)) cellStr.append('\t\t\ti (%5.5e %5.5e %5.5e);\n'%tuple(i)) cellStr.append('\t\t\tj (%5.5e %5.5e %5.5e);\n'%tuple(j)) cellStr.append('\t\t\tk (%5.5e %5.5e %5.5e);\n\n'%tuple(k)) cellStr.append('\t\t\tfieldValues\n\t\t\t(\n') cellStr.append('\t\t\t\tvolScalarFieldValue alpha.liquid %5.5e\n\t\t\t);\n'%alpha) cellStr.append('\t\t}\n') #entry ending line return cellStr ##CONSTANTS========================================================= # -- other physical properties g = 9.81 #gravity # -- liquid properties [sigma,rho,mu,theta0,thetaA,thetaR] = dfluidData(liqName) # -- calculation parameters deltaX = L/nCellsX deltaZ = H/nCellsZ #MODEL DEFINITION======================================================= # -- constants psi = np.power(105.0*mu*Q0 / (4.0*rho*g*np.sin(alpha)),0.3333) varpi = 2.0*mu/(rho*g*np.sin(alpha)*l**2.0) # -- functions betaFunc= lambda a : np.arctan(np.divide(psi,a**1.3333)) h0Func = lambda a,beta : 2.0*np.multiply(a,np.tan(beta)/2.0) # -- model ODE (to be solved numerically) def model(a,x): beta = betaFunc(a) dadx = 1.0*beta**3.0*sigma*varpi/(9.0*mu*np.log(a/(2.0*np.exp(2.0)*l))) return dadx def jac(a,x): dfun = -(1.0/9.0)*np.arctan(psi/a**4.0)**2.0*sigma*(np.arctan(psi/a**4.0)*(a**8.0+psi**2.0)-12.0*a**4.0*psi*(ln(2.0)+2.0-ln(a/l)))*varpi/(mu*(ln(2.0)+2.0-ln(a/l))**2.0*(a**8.0+psi**2.0)*a) return dfun #SETFIELDSDICT EDITING============================================== with open(caseDir + './system/setFieldsDict', 'r') as file: # read a list of lines into data data = file.readlines() regsLine = 0 #at the time empty # -- find position of regions keyword for i in range(len(data)): if data[i].find('regions') >-1: auxData = data[0:i+2] regsLine = i break # -- find the height of liquid surface at inlet h = 2.0*math.pi/(5.0*alpha)*(6.0*Q0**2.0/g)**0.2 a0 = 2.0*h*np.sqrt(3.0)/3.0 # -- fill in the inlet by liquid auxData.extend(writeRotBoxAlpha([-h,-10,0],[-10/np.tan(alpha),0,-10],[0,20,0],[10,0,-10/np.tan(alpha)],1.0)) #~ # -- connect the liquid in inlet with the liquid in rivulet #~ auxData.extend(writeRotBoxAlpha([0,-a0,h],[-10*np.tan(alpha),0,-10],[0,2*a0,0],[10,0,-10*np.tan(alpha)],1.0)) # -- solve the model ODE x = np.linspace(-h,L,nCellsX+int(round(nCellsX*h/L))+1) #create solution grid aList = odeint(model,a0,x,Dfun=jac,printmessg=True) #solve the system # -- auxiliary calculations betaList = betaFunc(aList) h0List = h0Func(aList,betaList) # -- extend the list by the cylinders (gas-liquid interface position) for i in range(nCellsX): # -- prepare the phase fraction fields cellStr = writeCylinder(h0List[i],aList[i],x.item(i),deltaX) auxData.extend(cellStr) # -- prepare the velocity field - as boxes R = h0List.item(i)/2.0 + aList.item(i)**2.0/(2.0*h0List.item(i)) for j in range(1,int(math.ceil(nCellsZ*h0List.item(i)/H))): uVec = [rho*g*np.sin(alpha)/(2.0*mu)*(2.0*h0List.item(i)*j*deltaZ - (j*deltaZ)**2.0),0.0,0.0] #~ p_rgh = rho*g*np.cos(alpha)*(h0List.item(i) - (j*deltaZ)) + np.tan(betaList.item(i))/aList.item(i)*sigma p_rgh = np.tan(betaList.item(i))/aList.item(i)*sigma # -- get the current rivulet width (at height j*deltaZ) c = np.sqrt((R-(h0List.item(i)-j*deltaZ)/2.0)*8.0*(h0List.item(i)-j*deltaZ)) cellStr = writeBox(j*deltaZ,deltaZ,c,x.item(i),deltaX,uVec,p_rgh) auxData.extend(cellStr) # -- extend the list by the rest of the lines auxData.extend(data[regsLine+2::]) # rewrite the setFieldsDict file with open(caseDir + './system/setFieldsDict', 'w') as file: file.writelines( auxData ) # PLOTTING THE CHARACTERISTICS OF PRESET SOLUTION=================== if pltFlag: plt.figure(num=None, figsize=(20, 12), dpi=80, facecolor='w', edgecolor='k') plt.show(block=False) plt.subplot(2,1,1) plt.plot(betaList,'bo') plt.title('Contact angle evolution along the rivulet') plt.xlabel('step count') plt.xlim(0,len(betaList)) plt.ylabel('apparent contact angle') plt.subplot(2,2,3) plt.plot(aList,'mo') plt.title('Rivulet half width evolution') plt.xlabel('step count') plt.xlim(0,len(aList)) plt.ylabel('rivulet half width') plt.subplot(2,2,4) plt.plot(h0List,'co') plt.title('Rivulet centerline height evolution') plt.xlabel('step count') plt.xlim(0,len(h0List)) plt.ylabel('rivulet centerline height') plt.show()
def finletBCWriter(caseDir, #need to specify case directory a0=0.01,h0=0.001,mDot=1e-3,alpha=1, liqName='DC10', cellW=0.150,cellL=0.300, nCellsW=150,nCellsL=300): #IMPORT BLOCK======================================================= import os import math from dfluidData import dfluidData # #GET THE DATA======================================================= #=================================================================== # EDITABLE #=================================================================== g = 9.81 [sigma,rho,mu,theta0,thetaA,thetaR] = dfluidData(liqName) beta = float((theta0+thetaA+thetaR)/3)/180*math.pi #get initial contact angle in radians #=================================================================== # DO NOT EDIT #=================================================================== # recalculation for ND mesh - lenght is ND by inlet height L = 1#h0 a0,h0,cellL,cellW = a0/L,h0/L,cellL/L,cellW/L # auxiliary variables - meshing nCellsIn = int(round(a0/cellW*nCellsW)+round(a0/cellW*nCellsW)%2) nCellsWVec = [(nCellsW-nCellsIn)/2,nCellsIn,(nCellsW-nCellsIn)/2] hVec = [] uVec = [] #~ for i in range(0,nCellsIn/2): #~ hVec.append(a0**2 - (2*i*a0/nCellsIn)**2) #~ for i in range(nCellsIn/2+1,nCellsIn) #~ hVec.append(a0**2 - (2*i*a0/nCellsIn)**2) Bsqrt = a0*math.sqrt(rho*g*math.cos(alpha)/sigma) A = a0*math.tan(beta)/(Bsqrt*math.sinh(Bsqrt)) #~ yVec = [(2*a0*i/float(nCellsIn) - a0) for i in range(nCellsIn+1)] #~ print yVec print 'sqrt(B) = ' + repr(Bsqrt) #~ print A # calculate the inlet profile shape for i in range(nCellsIn+1): dzeta = 2*i/float(nCellsIn) - 1 hVec.append(A*(math.cosh(Bsqrt)-math.cosh(Bsqrt*dzeta))) #calculate the inlet profile cross section step = 2*a0/float(nCellsIn) cSec = 0 for i in range(len(hVec)-1): cSec = cSec + hVec[i+1] + hVec[i] cSec = cSec*step/2 #calculate the inlet liquid velocity to sustain demanded mDot u0 = mDot/rho/cSec #~ for i in range(len(hVec)): #~ uVec.append([hVec[i]**2*rho*g/(2*mu),0,0]) #~ print uVec #======================================================================= #======================================================================= #CREATE FILE AND WRITE THE DATA IN====================================== idStr = 'inlet' # write everything to the file # Uf with open(caseDir + '0.org/wallFilmRegion/Uf', 'r') as file: # read a list of lines into data data = file.readlines() for i in range(len(data)): fInd = data[i].find(idStr) if fInd>-1: data[i:] = [] break with open(caseDir + '0.org/wallFilmRegion/Uf', 'w') as file: file.writelines( data ) bMD = open(caseDir + '0.org/wallFilmRegion/Uf','a') #open file temporary file for writing #----------------------------------------------------------------------- # write data to file # -- case of dirichlet boundary #~ bMD.write('\tinlet \n\t{ \n') #~ bMD.write('\t\ttype\tfixedValue;\n') #~ bMD.write('\t\tvalue\tnonuniform List<vector> \n\t\t' + repr(nCellsIn) + '\n\t\t(\n') #~ for row in uVec: #~ bMD.write('\t\t\t ( ' + ' '.join(str(e) for e in row) + ' )\n') #~ bMD.write('\t\t); \n') #~ bMD.write('\t} \n\n') #~ bMD.write('}\n\n') # -- case of flowRateInletVelocity (could it be applied?) #~ bMD.write('\tinlet \n\t{ \n') #~ bMD.write('\t\ttype\tflowRateInletVelocity;\n') #~ bMD.write('\t\tmassFlowRate\tconstant\t' + repr(mDot) + ';\n') #~ bMD.write('\t\tvalue\t\tuniform (1 0 0);\n') #~ bMD.write('\t} \n\n') #~ bMD.write('}\n\n') # -- case of constant velocity bMD.write('\tinlet \n\t{ \n') bMD.write('\t\ttype\tfixedValue;\n') bMD.write('\t\tvalue\tuniform \t\t(%5.4e 0 0);\n'%u0) bMD.write('\t} \n\n') bMD.write('}\n\n') #----------------------------------------------------------------------- # footline bMD.write('// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // \n\n') #----------------------------------------------------------------------- # close file bMD.close() # deltaf with open(caseDir + '0.org/wallFilmRegion/deltaf', 'r') as file: # read a list of lines into data data = file.readlines() for i in range(len(data)): fInd = data[i].find(idStr) if fInd>-1: data[i:] = [] break with open(caseDir + '0.org/wallFilmRegion/deltaf', 'w') as file: file.writelines( data ) bMD = open(caseDir + '0.org/wallFilmRegion/deltaf','a') #open file temporary file for writing #----------------------------------------------------------------------- # write data to file bMD.write('\tinlet \n\t{ \n') bMD.write('\t\ttype\tfixedValue;\n') bMD.write('\t\tvalue\tnonuniform List<scalar> \n\t\t' + repr(nCellsIn+1) + '\n\t\t(\n') for i in range(len(hVec)): bMD.write('\t\t\t ' + repr(hVec[i]) + '\n') bMD.write('\t\t); \n') bMD.write('\t} \n\n') bMD.write('}\n\n') #~ bMD.write('\tinlet \n\t{ \n') #~ bMD.write('\t\ttype\tfixedValue;\n') #~ bMD.write('\t\tvalue\tuniform \t\t' + repr(h0) + ';\n') #~ bMD.write('\t} \n\n') #~ bMD.write('}\n\n') #----------------------------------------------------------------------- # footline bMD.write('// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // \n\n') #----------------------------------------------------------------------- # close file bMD.close() return;
inletBCWriter, #preProcFunc - BC writer rivuletPostProc, #rivulet postprocessing (paraview) rivuletPostProc2Blender, #export paraview->blender blenderPrep, #rivulet postprocessing (blender) ] for scName in scNames: sh.copyfile(scFolder + scName + '.py',caseDir + scName + '.py') #copy current script version #CASE CONSTANTS AND CALCULATIONS======================================== # input data------------------------------------------------------------ # -- global parameters g = 9.81 #grav. acc., m/s2 deltaWet= 1e-5 #height above which is the plate considered wet, m # -- liquid properties [sigma,rho,mu,theta0,thetaA,thetaR] = dfluidData(liqName) #~ [_,rhoA,muA,_,_,_] = dfluidData('AIR') #~ NOTE: liquid properties are stored in a special dictionary #~ sigma ... surface tension coefficient of the liquid, N/m #~ rho ... density of the liquid, kg/m3 #~ mu ... liquid dynamic viscosity, Pas #~ theta0,thetaA,thetaR ... equilibrium, advancing and receding contact #~ angles # -- further calculations mDot = Q0*rho #mass flow rate calculation beta = float((theta0+thetaA+thetaR)/3)/180*math.pi #get initial contact angle in radians # -- additional parameters lC = math.sqrt(sigma/(rho*g)); #liquid capillary length
rivuletPostProc, #rivulet postprocessing (paraview) rivuletPostProc2Blender, #export paraview->blender blenderPrep, #rivulet postprocessing (blender) ] for scName in scNames: sh.copyfile(scFolder + scName + '.py', caseDir + scName + '.py') #copy current script version #CASE CONSTANTS AND CALCULATIONS======================================== # input data------------------------------------------------------------ # -- global parameters g = 9.81 #grav. acc., m/s2 deltaWet = 1e-5 #height above which is the plate considered wet, m # -- liquid properties [sigma, rho, mu, theta0, thetaA, thetaR] = dfluidData(liqName) #~ [_,rhoA,muA,_,_,_] = dfluidData('AIR') #~ NOTE: liquid properties are stored in a special dictionary #~ sigma ... surface tension coefficient of the liquid, N/m #~ rho ... density of the liquid, kg/m3 #~ mu ... liquid dynamic viscosity, Pas #~ theta0,thetaA,thetaR ... equilibrium, advancing and receding contact #~ angles # -- further calculations mDot = Q0 * rho #mass flow rate calculation beta = float((theta0 + thetaA + thetaR) / 3) / 180 * math.pi #get initial contact angle in radians # -- additional parameters lC = math.sqrt(sigma / (rho * g))