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 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 initPrimalData(self): if parallel.mpi.bcast(os.path.exists(primal.statusFile), root=0): firstCheckpoint, result = primal.readStatusFile() pprint('Read status file, checkpoint =', firstCheckpoint) else: firstCheckpoint = 0 result = [0.]*nPerturb if parallel.rank == 0: if not os.path.exists(primal.timeStepFile): assert primal.fixedTimeStep timeSteps = (startTime + np.arange(0, nSteps)*Dt).reshape(-1,1) timeSteps = np.hstack((timeSteps, np.ones((nSteps, 1))*Dt)) else: timeSteps = np.loadtxt(primal.timeStepFile, ndmin=2) assert timeSteps.shape == (nSteps, 2) timeSteps = np.concatenate((timeSteps, np.array([[np.sum(timeSteps[-1]).round(12), 0]]))) else: timeSteps = np.zeros((nSteps + 1, 2)) parallel.mpi.Bcast(timeSteps, root=0) checkpointData = (result, firstCheckpoint) primalData = (timeSteps,) return checkpointData, primalData
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
solver.readFields(times[0]) solver.compileInit() # plot over surface normals #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() # average #time = times[0] #postprocess(solver, time, suffix='_avg') #pprint() # instantaneous #for index, time in enumerate(times): # postprocess(solver, time) # pprint() # last time time = times[-1] postprocess(solver, time, suffix='') pprint()
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()
import numpy as np from adFVM import config, BCs from adFVM.field import Field, IOField from adFVM.mesh import Mesh from adFVM.parallel import pprint #config.hdf5 = True case = sys.argv[1] fields = sys.argv[2:] 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
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 with IOField.handle(time): T.write()
assert nSteps >= writeInterval assert writeInterval >= reportInterval assert (writeInterval % reportInterval) == 0 assert writeInterval >= sampleInterval assert (writeInterval % sampleInterval) == 0 assert writeInterval >= viscousInterval assert (writeInterval % viscousInterval) == 0 if not isinstance(parameters, list): parameters = [parameters] if not isinstance(perturb, list): perturb = [perturb] nPerturb = len(perturb) primal.timeStepFile = primal.mesh.case + '{0}.{1}.txt'.format(nSteps, writeInterval) pprint('') def writeResult(option, result, info='-', timeSeriesFile=None): globalResult = [res/(nSteps-avgStart) for res in result] resultFile = primal.resultFile if parallel.rank == 0: noise = 0 if option == 'perturb': previousResult = float(open(resultFile).readline().split(' ')[3]) globalResult[0] -= previousResult noise = [0. for res in result] if timeSeriesFile: import ar timeSeries = np.loadtxt(timeSeriesFile,ndmin=1)[avgStart::sampleInterval] if len(timeSeries.shape) == 1: