Example #1
0
 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
Example #2
0
    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
Example #3
0
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):
Example #4
0
#!/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()
Example #5
0
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