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 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
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):
#!/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()
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) with IOField.handle(time2): phi2.write() print