def test_mpi_comm_method(case_path): mesh = Mesh.create(case_path) IOField.setMesh(mesh) with IOField.handle(1.): U = IOField.read('U') U.partialComplete() with IOField.handle(2.): U.write() return
def test_field_io_mpi(case): mesh = Mesh.create(case) Field.setMesh(mesh) time = 1.0 config.hdf5 = False with IOField.handle(time): U = IOField.read('U') U.partialComplete() config.hdf5 = True with IOField.handle(time, case=case): Uh = IOField.read('U') Uh.partialComplete()
def diffAllTimes(): case1, case2, field = sys.argv[1:] mesh1 = Mesh.create(case1) mesh2 = Mesh.create(case2) times1 = mesh1.getTimes() times2 = mesh2.getTimes() for time1, time2 in zip(times1, times2): Field.setMesh(mesh1) with IOField.handle(time1): phi1 = IOField.read(field) Field.setMesh(mesh2) with IOField.handle(time2): phi2 = IOField.read(field) diff = np.abs(phi1.field-phi2.field) norm = np.sqrt(parallel.sum(diff**2*mesh1.volumes)) pprint(parallel.min(diff)) pprint('norm:', norm)
def createFields(self): fields = [] for name, dims in zip(self.names, self.dimensions): phi = np.zeros((self.mesh.nInternalCells, dims[0]), config.precision) fields.append(IOField(name, phi, dims, self.mesh.defaultBoundary)) self.fields = fields for phi in self.fields: phi.completeField() self.firstRun = False return fields
def postprocess(solver, time, suffix=''): mesh = solver.mesh point = np.array([0.052641, -0.1, 0.005]) normal = np.array([1., 0., 0.]) patches = ['pressure', 'suction'] pprint('postprocessing', time) rho, rhoU, rhoE = solver.initFields(solver.readFields(time, suffix=suffix)) U, T, p = solver.primitive(rho, rhoU, rhoE) T0 = 420. p0 = solver.p.phi.BC['inlet'].patch['_pt'][0, 0] #p0 = 177000. print p0 htc = getHTC(T, T0, patches) Ma = getIsentropicMa(p, p0, patches) print Ma wakeCells, pl = getPressureLoss(p, T, U, p0, point, normal) uplus, yplus, ustar, yplus1 = getYPlus(U, T, rho, patches) #for patchID in patches: # startFace = mesh.boundary[patchID]['startFace'] # endFace = startFace + mesh.boundary[patchID]['nFaces'] # index = 0 # mult = np.logspace(0, 2, 100) # points = mesh.faceCentres[startFace + index] \ # - mesh.normals[startFace + index]*yplus1[patchID][index]*mult.reshape(-1,1) # field = U.interpolate(points)/ustar[patchID][index] # field = ((field**2).sum(axis=1))**0.5 # plt.plot(mult, field) # plt.show() htc = IOField.boundaryField('htc' + suffix, htc, (1, )) Ma = IOField.boundaryField('Ma' + suffix, Ma, (1, )) uplus = IOField.boundaryField('uplus' + suffix, uplus, (3, )) yplus = IOField.boundaryField('yplus' + suffix, yplus, (1, )) with IOField.handle(time): htc.write() Ma.write() uplus.write() yplus.write()
def test_mpi_comm(): case_path = os.path.join(cases_path, 'forwardStep') mesh = Mesh.create(case_path) IOField.setMesh(mesh) with IOField.handle(0.): U = IOField.read('U') U.partialComplete() U.field = np.random.rand(*U.field.shape) try: with IOField.handle(1.): U.write() time.sleep(1) subprocess.check_output( ['decomposePar', '-case', case_path, '-time', '1']) subprocess.check_output([ 'mpirun', '-np', '4', 'python2', __file__, 'RUN', 'test_mpi_comm_method', case_path ]) checkFields(case_path, 'U', '1.0', '2.0', relThres=1e-12, nProcs=4) finally: shutil.rmtree(os.path.join(case_path, '1')) map(shutil.rmtree, glob.glob(os.path.join(case_path, 'processor*')))
def postprocess(solver, time, suffix=''): #T0 = 365. #p0 = 122300. #point = np.array([0.081 + 0.023*0.03973,-0.06,0.005]) #normal = np.array([1.,0.,0.]) T0 = 409. p0 = 184900. # valid? point = np.array([0.052641, -0.1, 0.005]) normal = np.array([1., 0., 0.]) #patches = [surface + '_pressure', surface + '_suction'] patches = [ 'blade_pressure', 'blade_suction', 'blade0_pressure', 'blade0_suction', 'nozzle_pressure', 'nozzle_suction' ] pprint('postprocessing', time) rho, rhoU, rhoE = solver.initFields(time, suffix=suffix) U, T, p = solver.U, solver.T, solver.p htc = getHTC(T, T0, patches) Ma = getIsentropicMa(p, p0, patches) wakeCells, pl = getPressureLoss(p, T, U, p0, point, normal) uplus, yplus, _, _ = getYPlus(U, T, rho, patches) htc = IOField.boundaryField('htc' + suffix, htc, (1, )) Ma = IOField.boundaryField('Ma' + suffix, Ma, (1, )) uplus = IOField.boundaryField('uplus' + suffix, uplus, (3, )) yplus = IOField.boundaryField('yplus' + suffix, yplus, (1, )) with IOField.handle(time): #htc.write() #Ma.write() uplus.write() yplus.write()
def run(self, checkpointData, primalData): mesh = self.mesh result, firstCheckpoint = checkpointData (timeSteps,) = primalData sensTimeSeries = [] energyTimeSeries = [] startTime = timeSteps[nSteps - firstCheckpoint*writeInterval][0] if (firstCheckpoint > 0) or self.forceReadFields: fields = self.readFields(startTime) for phi in fields: phi.field *= mesh.volumes else: fields = self.fields pprint('STARTING ADJOINT') pprint('Number of steps:', nSteps) pprint('Write interval:', writeInterval) pprint() perturbations = [] for index in range(0, len(perturb)): perturbation = perturb[index](None, mesh, 0) if isinstance(perturbation, tuple): perturbation = list(perturbation) if not isinstance(perturbation, list):# or (len(parameters) == 1 and len(perturbation) > 1): perturbation = [perturbation] # complex parameter perturbation not supported perturbations.append(perturbation) totalCheckpoints = nSteps//writeInterval nCheckpoints = min(firstCheckpoint + runCheckpoints, totalCheckpoints) checkpoint = firstCheckpoint while checkpoint < nCheckpoints: pprint('PRIMAL FORWARD RUN {0}/{1}: {2} Steps\n'.format(checkpoint, totalCheckpoints, writeInterval)) primalIndex = nSteps - (checkpoint + 1)*writeInterval t = timeSteps[primalIndex, 0] dts = timeSteps[primalIndex:primalIndex+writeInterval+1, 1] solutions = primal.run(startTime=t, dt=dts, nSteps=writeInterval, mode='forward', reportInterval=reportInterval) pprint('ADJOINT BACKWARD RUN {0}/{1}: {2} Steps\n'.format(checkpoint, totalCheckpoints, writeInterval)) pprint('Time marching for', ' '.join(self.names)) if checkpoint == 0: t, _ = timeSteps[-1] if primal.dynamicMesh: lastMesh, lastSolution = solutions[-1] mesh.boundary = lastMesh.boundarydata[m:].reshape(-1,1) else: lastSolution = solutions[-1] fieldsCopy = [phi.copy() for phi in fields] for phi in fields: phi.field /= mesh.volumes self.writeFields(fields, t, skipProcessor=True) fields = fieldsCopy primal.updateSource(source(solutions[-1], mesh, 0)) pprint('Time step', writeInterval) for phi in fields: phi.info() #energyTimeSeries.append(getAdjointEnergy(primal, *fields)) inputs = [phi.field for phi in fields + solutions[-1]] + mesh.getTensor() + mesh.getScalar() energyTimeSeries.append(self.computeEnergy(*inputs)) pprint() for step in range(0, writeInterval): report = ((step + 1) % reportInterval) == 0 sample = ((step + 1) % sampleInterval) == 0 viscous = ((step + 1) % viscousInterval) == 0 adjointIndex = writeInterval-1 - step t, dt = timeSteps[primalIndex + adjointIndex] if primal.dynamicMesh: previousMesh, previousSolution = solutions[adjointIndex] # new mesh boundary mesh.boundary = previousMesh.boundary else: previousSolution = solutions[adjointIndex] pprint('Time step', adjointIndex) if report: pprint('Time marching for', ' '.join(self.names)) start = time.time() #for index in range(0, n): # fields[index].field *= mesh.volumes dtca = np.zeros((1, 1)).astype(config.precision) obja = np.ones((1, 1)).astype(config.precision) if self.homogeneousAdjoint: obja *= 0. inputs = [phi.field for phi in previousSolution] + \ [np.array([[dt]], config.precision)] + \ mesh.getTensor() + mesh.getScalar() + \ [x[1] for x in primal.sourceTerms] + \ primal.getBoundaryTensor(1) + \ [x[1] for x in primal.extraArgs] + \ [phi.field for phi in fields] + \ [dtca, obja] + \ [np.array([[self.scaling]], config.precision)] options = {'return_static': sample, 'zero_static': sample, 'return_reusable': report, 'replace_reusable': False, } start10 = time.time() if self.viscosityType and not matop_python and viscous: outputs = self.viscousMap(*inputs, **options) else: outputs = self.map(*inputs, **options) pprint(time.time()-start10) #print(sum([(1e-3*phi).sum() for phi in gradient])) #inp1 = inputs[:3] + inputs[-3:-1] #inp2 = [phi + 1e-3 for phi in inputs[:3]] + inputs[-3:-1] #x1 = primal.map(*inp1)[-2] #x2 = primal.map(*inp2)[-2] #print(x1, x2, x1-x2) #import pdb;pdb.set_trace() # gradients n = len(fields) gradient = outputs[:n] for index in range(0, n): fields[index].field = gradient[index] #fields[index].field = gradient[index]/mesh.volumes if matop_python: stackedFields = np.concatenate([phi.field/mesh.volumes for phi in fields], axis=1) stackedFields = np.ascontiguousarray(stackedFields) inputs = previousSolution + [self.scaling] kwargs = {'visc': self.viscosityType, 'scale': self.viscosityScaler, 'report':report} weight = interp.centralOld(getAdjointViscosity(*inputs, **kwargs), mesh) stackedPhi = Field('a', stackedFields, (5,)) stackedPhi.old = stackedFields newStackedFields = (matop_petsc.ddt(stackedPhi, dt) - matop_petsc.laplacian(stackedPhi, weight, correction=False)).solve() #newStackedFields = stackedFields/(1 + weight*dt) newFields = [newStackedFields[:,[0]], newStackedFields[:,[1,2,3]], newStackedFields[:,[4]] ] fields = self.getFields(newFields, IOField) for phi in fields: phi.field = np.ascontiguousarray(phi.field)*mesh.volumes #print([type(x) for x in outputs]) if sample: paramGradient = list(outputs[n:n + self.nParams]) # compute sensitivity using adjoint solution sensitivities = [] for index, perturbation in enumerate(perturbations): # make efficient cpu implementation #sensitivity = 0. #for derivative, delphi in zip(paramGradient, perturbation): # sensitivity += np.sum(derivative * delphi) sensitivity = cmesh.computeSensitivity(paramGradient, perturbation) sensitivities.append(sensitivity) sensitivities = parallel.sum(sensitivities, allreduce=False) if (nSteps - (primalIndex + adjointIndex)) > avgStart: for index in range(0, len(perturb)): result[index] += sensitivities[index] sensitivities = [sens/sampleInterval for sens in sensitivities] for i in range(0, sampleInterval): sensTimeSeries.append(sensitivities) if report: for phi in fields: phi.info() #energyTimeSeries.append(getAdjointEnergy(primal, *fields)) inputs = [phi.field for phi in fields + previousSolution] + mesh.getTensor() + mesh.getScalar() energyTimeSeries.append(self.computeEnergy(*inputs)) #print(self.computeEnergy(*inputs), getSymmetrizedAdjointEnergy(primal, *inputs[:6])) end = time.time() pprint('Time for adjoint iteration: {0}'.format(end-start)) pprint('Time since beginning:', end-config.runtime) pprint('Simulation Time and step: {0}, {1}'.format(*timeSteps[primalIndex + adjointIndex + 1])) pprint() #parallel.mpi.Barrier() self.writeStatusFile([checkpoint + 1, result]) #energyTimeSeries = mpi.gather(timeSeries, root=0) if parallel.rank == 0: with open(self.sensTimeSeriesFile, 'ab') as f: np.savetxt(f, sensTimeSeries) with open(self.energyTimeSeriesFile, 'ab') as f: np.savetxt(f, energyTimeSeries) sensTimeSeries = [] energyTimeSeries = [] checkpoint += 1 #exit(1) #print(fields[0].field.max()) fieldsCopy = [phi.copy() for phi in fields] for phi in fields: phi.field /= mesh.volumes self.writeFields(fields, t, skipProcessor=True) fields = fieldsCopy # write M_2norm if write_M_2norm: with IOField.handle(t): IOField('M_2norm', outputs[-1], (1,)).write() #for phi in fields: # phi.field /= mesh.volumes #self.writeFields(fields, t, skipProcessor=True) #for phi in fields: # phi.field *= mesh.volumes #print(fields[0].field.max()) #pprint(checkpoint, totalCheckpoints) if checkpoint >= totalCheckpoints: writeResult('adjoint', result, str(self.scaling), self.sensTimeSeriesFile) #for index in range(0, nPerturb): # writeResult('adjoint', result[index], '{} {}'.format(index, self.scaling)) self.removeStatusFile() return
#!/usr/bin/python2 from adFVM import parallel, config import sys import os case = sys.argv[1] times = [float(x) for x in sys.argv[2:]] config.hdf5 = False from adFVM.field import IOField from adFVM.mesh import Mesh mesh = Mesh.create(case) mesh.writeHDF5(case) IOField.setMesh(mesh) if len(times) == 0: times = mesh.getTimes() for time in times: config.hdf5 = False fields = [] with IOField.handle(time): for name in mesh.getFields(time): if name == 'polyMesh': # replace mesh boundary !! continue phi = IOField.readFoam(name) phi.partialComplete() fields.append(phi) config.hdf5 = True
plt.savefig(saveFile) plt.clf() if __name__ == '__main__': from adFVM.mesh import Mesh from adFVM.field import Field, IOField import sys case, time = sys.argv[1:3] time = float(time) mesh = Mesh.create(case) Field.setMesh(mesh) with IOField.handle(time): htc = IOField.read('htc') htc.partialComplete() Ma = IOField.read('Ma') Ma.partialComplete() #nLayers = 1 nLayers = 200 from postpro import surface patches = [surface + '_pressure', surface + '_suction'] get_profile(surface) htc_args = [] Ma_args = [] mesh = mesh.origMesh
#!/usr/bin/python2 import sys import numpy as np from adFVM.density import RCF from adFVM.field import IOField case, time = sys.argv[1:3] time = float(time) rcf = RCF(case) with IOField.handle(time): U = IOField.read('U') T = IOField.read('T') p = IOField.read('p') rho, rhoU, rhoE = rcf.conservative(U, T, p) fields = [U, T, p, rho, rhoU, rhoE] for phi in fields: phi.info()
continue boundaryFile = boundaryDir + 'boundary' shutil.copyfile(boundaryFile, boundaryDir + 'boundary.cyclic') # intersection_master on the right, intersection_slave on the left (x-axis) patch = mesh.origMesh.boundary['intersection_master'] patch['type'] = 'slidingPeriodic1D' patch['periodicPatch'] = 'mid1plane' patch['velocity'] = '(0 252 0)' patch['nLayers'] = '1' #patch['nLayers'] = '10' patch.pop('movingCellCentres', None) patch = mesh.origMesh.boundary['intersection_slave'] patch['type'] = 'slidingPeriodic1D' patch['periodicPatch'] = 'mid2plane' patch['velocity'] = '(0 -252 0)' patch['nLayers'] = '1' #patch['nLayers'] = '10' patch.pop('movingCellCentres', None) mesh.writeFoamBoundary(boundaryFile, mesh.origMesh.boundary) fields = os.listdir(timeDir) for phi in fields: if phi == 'polyMesh': continue with IOField.handle(user.time): field = IOField.read(phi) field.boundary['intersection_master']['type'] = 'slidingPeriodic1D' field.boundary['intersection_slave']['type'] = 'slidingPeriodic1D' field.partialComplete() field.write(skipProcessor=True)
def test_field_io(case, hdf5): config.hdf5 = hdf5 mesh = Mesh.create(case) Field.setMesh(mesh) time = 1.0 field = np.random.rand(mesh.nInternalCells, 3) boundary = copy.deepcopy(mesh.defaultBoundary) nFaces = mesh.getPatchFaceRange('inlet')[2] boundary['inlet'] = { 'type':'CBC_TOTAL_PT', 'pt': 'uniform 20', 'value': np.random.rand(nFaces, 3) } U = IOField('U', field, (3,), boundary) U.partialComplete() field = np.random.rand(mesh.nInternalCells, 1) boundary = copy.deepcopy(mesh.defaultBoundary) T = IOField('T', field, (1,), boundary) boundary['outlet'] = { 'type':'fixedValue', 'value': 'uniform 10' } with IOField.handle(time): U.write() T.write() with IOField.handle(time):
centres1 = mesh1.cellCentres[:mesh1.nInternalCells] centres2 = mesh2.cellCentres[:mesh2.nInternalCells] internalIndices = mapNearest(centres1, centres2) patchIndices = {} for patchID in mesh1.boundary: startFace, endFace, indices1 = getPatchInfo(mesh1, patchID) centres1 = mesh1.faceCentres[startFace:endFace] startFace, endFace, indices2 = getPatchInfo(mesh2, patchID) centres2 = mesh2.faceCentres[startFace:endFace] patchIndices[patchID] = mapNearest(centres1, centres2) #for field in mesh1.getFields(time1): for field in ['U', 'T', 'p', 'rho', 'rhoU', 'rhoE']: print 'interpolating', field Field.setMesh(mesh1) with IOField.handle(time1): phi1 = IOField.read(field) phi1.partialComplete() dims = phi1.dimensions phi2 = np.zeros((mesh2.nCells, ) + dims) phi2 = IOField(field, phi2, dims) phi2.field[:mesh2.nInternalCells] = phi1.field[internalIndices] for patchID in phi1.boundary: startFace, endFace, indices1 = getPatchInfo(mesh1, patchID) startFace, endFace, indices2 = getPatchInfo(mesh2, patchID) phi2.field[indices2] = phi1.field[indices1][patchIndices[patchID]] phi2.boundary = copy.deepcopy(phi1.boundary) Field.setMesh(mesh2)
#from mms import source, solution # analytical inviscid comparison def test_shockTube(self): case = '../cases/shockTube/' t = 0.0 solver = RCF(case, mu=lambda T: T*0., faceReconstructor='AnkitENO', CFL=0.6) solver.readFields(t) solver.compile() timeRef = 0.006 solver.run(startTime=t, endTime=timeRef, dt=1e-5) f = open(case + '/output') f.readline() f.readline() data = np.loadtxt(f) with IOField.handle(timeRef): rho = IOField.read('rho') p = IOField.read('p') U = IOField.read('U') #rho.complete() #p.complete() #U.complete() self.mesh = solver.mesh checkVolSum(self, rho.getInternalField(), data[:, 2].reshape((-1,1)), relThres=0.02) checkVolSum(self, p.getInternalField(), data[:, 3].reshape((-1,1)), relThres=0.02) checkVolSum(self, U.getInternalField()[:,0].reshape((-1,1)), data[:, 4].reshape((-1,1)),relThres=0.05) if __name__ == "__main__": unittest.main(verbosity=2, buffer=True)
with IOField.handle(time2): phi2 = IOField.read(field) diff = np.abs(phi1.field-phi2.field) norm = np.sqrt(parallel.sum(diff**2*mesh1.volumes)) pprint(parallel.min(diff)) pprint('norm:', norm) def diffSingleTime(): case, field, time1, time2 = sys.argv[1:] time1 = float(time1) time2 = float(time2) mesh = Mesh.create(case) Field.setMesh(mesh) with IOField.handle(time1): phi1 = IOField.read(field) phi1.partialComplete() with IOField.handle(time2): phi2 = IOField.read(field) phi2.partialComplete() diff = abs(phi1.field-phi2.field) ref = parallel.max(phi1.field) pprint('ref:', ref) pprint('absolute:', parallel.max(diff)) pprint('relative:', parallel.max(diff)/ref) pprint('close:', np.allclose(phi1.field, phi2.field)) diffSingleTime() #diffAllTimes()
mesh = Mesh.create(case) Field.setMesh(mesh) times = mesh.getTimes() times = filter(lambda x: x > 3.00049, times) pprint(times) nLayers = 200 #nLayers = 1 for field in fields: # time avg: no dt avg = 0. not_nan_times = 0. for time in times: with IOField.handle(time): phi = IOField.read(field) phi.partialComplete() not_nan_times += 1. - np.isnan(phi.field) avg += np.nan_to_num(phi.field) avg /= not_nan_times # spanwise avg: structured nDims = avg.shape[1] #nLayers = 1 def average(start, end): nCellsPerLayer = (end - start) / nLayers spanAvg = avg[start:end].reshape( (nCellsPerLayer, nLayers, nDims)).sum(axis=1, keepdims=1) / nLayers spanAvg = np.tile(spanAvg, (1, nLayers, 1)).reshape(
#!/usr/bin/python2 import sys, os import numpy as np from adFVM import config from adFVM.field import Field, IOField from adFVM.mesh import Mesh case = sys.argv[1] time1, time2 = sys.argv[2:4] mesh = Mesh.create(case) Field.setMesh(mesh) fields = ['p', 'T', 'U'] fieldsRef = [2e5, 300, 100] for name, ref in zip(fields, fieldsRef): with IOField.handle(float(time1)): phi = IOField.read(name) phi.partialComplete() with IOField.handle(float(time2)): mid = np.array([-0.02, 0.01, 0.005]) G = 1e0 * np.exp(-3e3 * np.linalg.norm( mid - mesh.cellCentres[:mesh.nInternalCells], axis=1, keepdims=1)** 2) phi.field[:mesh.nInternalCells] = G * ref phi = IOField(name, phi.field, phi.dimensions, phi.boundary) phi.write()
def test_matop(): case = '../cases/cylinder/' time = 3.0 field = 'mua' case = '../cases/naca0012/test_laplacian/' time = 0.0 field = 'T' DT = 0.01 dt = 1e-8 nSteps = 1000 mesh = Mesh.create(case) Field.setMesh(mesh) with IOField.handle(time): T = IOField.read(field) T.partialComplete() weight = central(T, mesh.origMesh) weight.field[:] = DT #op = laplacian(T, weight) #op.eigenvalues() for index in range(0, nSteps): pprint(index) T.old = T.field equation = ddt(T, dt) - laplacian(T, weight) T.field = equation.solve() T.defaultComplete() time += dt
import sys import os import numpy as np from adFVM import config from adFVM.field import Field, IOField from adFVM.mesh import Mesh case, field = sys.argv[1:3] #times = sys.argv[3:] mesh = Mesh.create(case) Field.setMesh(mesh) # time avg: no dt times = mesh.getTimes() with IOField.handle(times[0]): phiAvg = IOField.read(field + '_avg') phiAvg.partialComplete() std = 0. for time in times: with IOField.handle(time): phi = IOField.read(field) phi.partialComplete() std += (phiAvg.field-phi.field)**2 # spanwise avg: structured nLayers = 200 nDims = std.shape[1] #nLayers = 1 def average(start, end):
#!/usr/bin/python2 import sys, os import numpy as np from adFVM import config from adFVM.field import Field, IOField from adFVM.mesh import Mesh case1, case2 = sys.argv[1:] mesh = Mesh.create(case1) times = mesh.getTimes() Field.setMesh(mesh) fields = ['p', 'T', 'U'] for name in fields: phimax = -1 for time in times: mesh.case = case1 phi1 = IOField.read(name, mesh, time) phi1.partialComplete() if phimax < 0: phimax = phi1.field.max() mesh.case = case2 phi2 = IOField.read(name, mesh, time) phi2.partialComplete() phi1.name += '_diff' phi1.field = (phi2.field-phi1.field)/phimax phi1.write(time)
pklFile = 'match_args.pkl' if __name__ == '__main__': if 0: #os.path.exists(pklFile): htc_args, Ma_args = pkl.load(open(pklFile)) else: from adFVM import config from adFVM.mesh import Mesh from adFVM.field import Field, IOField case, time = sys.argv[1:3] time = float(time) mesh = Mesh.create(case) Field.setMesh(mesh) with IOField.handle(time): htc = IOField.read('htc_avg') Ma = IOField.read('Ma_avg') #htc = IOField.read('htc') #Ma = IOField.read('Ma') htc.partialComplete() Ma.partialComplete() #join = '/' #if config.hdf5: # join = '_' #with open(mesh.getTimeDir(time) + join + 'wake_avg', 'r') as f: # data = load(f) # wakeCells, pl = data['arr_0'], data['arr_1'] patches = ['pressure', 'suction']