Source code for genericROM.DataCompressors.IncrementalSnapshotPOD

# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE', which is part of this source code package.
#
#

import os
try:
    from mpi4py import MPI
except ImportError:# pragma: no cover
    print("MPI capabilities not available")
import numpy as np
from scipy import sparse
from Mordicus.BasicAlgorithms import SVD as SVD


#REMARK: do not work very well for low values of tolerance


[docs]def CompressData( collectionProblemData, solutionName, tolerance = None, snapshotCorrelationOperator = None, snapshots = None, compressSolutions = False, nbModes = None ): """ Computes a reducedOrderBasis using the SnapshotPOD algorithm, from the snapshots contained in the iterator snapshotsIterator, which a correlation operator between the snapshots defined by the matrix snapshotCorrelationOperator, with tolerance as target accuracy of the data compression. If a reducedOrderBasis prexists, it is updated using the snapshots from the solutions. Parameters ---------- collectionProblemData : CollectionProblemData input collectionProblemData containing the data solutionName : str name of the solutions from which snapshots are taken tolerance : float, cannot be provided with nbModes target accuracy of the data compression snapshotCorrelationOperator : scipy.sparse.csr_matrix, optional correlation operator between the snapshots snapshots : np.ndarray, optional of size (nbSnapshots, numberOfDofs): snapshots of the solutions to compress compressSolutions : bool, optional True to compresse solutions using the constructed reducedOrderBasis nbModes : int, cannot be provided with tolerance the number of keps snapshot POD modes """ assert isinstance(solutionName, str) if tolerance == None and nbModes == None:# pragma: no cover raise("must specify epsilon or nbModes") if tolerance != None and nbModes != None:# pragma: no cover raise("cannot specify both epsilon and nbModes") if snapshots is None: snapshots = collectionProblemData.GetSnapshots(solutionName) if snapshotCorrelationOperator is None: snapshotCorrelationOperator = sparse.eye(snapshots.shape[1]) numberOfSnapshots = snapshots.shape[0] previousReducedOrderBasis = collectionProblemData.GetReducedOrderBasis(solutionName) if previousReducedOrderBasis is None: correlationMatrix = np.zeros((numberOfSnapshots,numberOfSnapshots)) for i, snapshot1 in enumerate(snapshots): matVecProduct = snapshotCorrelationOperator.dot(snapshot1) for j, snapshot2 in enumerate(snapshots): if j <= i and j < numberOfSnapshots: correlationMatrix[i, j] = np.dot(matVecProduct, snapshot2) mpiReducedCorrelationMatrix = np.zeros((numberOfSnapshots, numberOfSnapshots)) MPI.COMM_WORLD.Allreduce([correlationMatrix, MPI.DOUBLE], [mpiReducedCorrelationMatrix, MPI.DOUBLE]) eigenValuesRed, eigenVectorsRed = SVD.TruncatedSVDSymLower(mpiReducedCorrelationMatrix, tolerance) nbePODModes = eigenValuesRed.shape[0] changeOfBasisMatrix = np.zeros((nbePODModes,numberOfSnapshots)) for j in range(nbePODModes): changeOfBasisMatrix[j,:] = eigenVectorsRed[:,j]/np.sqrt(eigenValuesRed[j]) reducedOrderBasis = np.dot(changeOfBasisMatrix,snapshots) collectionProblemData.AddReducedOrderBasis(solutionName, reducedOrderBasis) localGamma = np.dot(reducedOrderBasis, snapshotCorrelationOperator.dot(snapshots.T)) globalGamma = np.zeros(localGamma.shape) MPI.COMM_WORLD.Allreduce([localGamma, MPI.DOUBLE], [globalGamma, MPI.DOUBLE]) collectionProblemData.AddDataCompressionData(solutionName, globalGamma) else: for snap in snapshots: snap.shape = (1,snap.shape[0]) gammaNPrevInd = collectionProblemData.GetDataCompressionData(solutionName) localGammaNNewInd = np.dot(previousReducedOrderBasis, snapshotCorrelationOperator.dot(snap.T)) gammaNNewInd = np.zeros(localGammaNNewInd.shape) MPI.COMM_WORLD.Allreduce([localGammaNNewInd, MPI.DOUBLE], [gammaNNewInd, MPI.DOUBLE]) snap = snap - np.einsum('kl,km->ml', previousReducedOrderBasis, gammaNNewInd, optimize = True) localNorms = np.einsum('kl,lk->k', snap, snapshotCorrelationOperator.dot(snap.T), optimize = True) globalNorms = np.zeros(localNorms.shape) MPI.COMM_WORLD.Allreduce([localNorms, MPI.DOUBLE], [globalNorms, MPI.DOUBLE]) globalNorms = np.sqrt(globalNorms) snap = np.divide(snap, globalNorms[:,np.newaxis]) indices = globalNorms > tolerance snap = snap[indices,:] globalNorms = globalNorms[indices] gammaNNewInd = gammaNNewInd[:,indices] Vinter = np.append(previousReducedOrderBasis, snap, axis=0) numberOfAddedSnapshots = snap.shape[0] gammaInterPrevInd1 = np.append(gammaNPrevInd, np.zeros((numberOfAddedSnapshots,gammaNPrevInd.shape[1])), axis = 0) gammaInterPrevInd2 = np.append(gammaNNewInd, np.diag(globalNorms), axis = 0) gammaInterLocal = np.append(gammaInterPrevInd1, gammaInterPrevInd2, axis = 1) gammaInterLocal2 = np.dot(gammaInterLocal, gammaInterLocal.T) gammaInterGlobal2 = np.zeros(gammaInterLocal2.shape) MPI.COMM_WORLD.Allreduce([gammaInterLocal2, MPI.DOUBLE], [gammaInterGlobal2, MPI.DOUBLE]) eigenValuesRed, eigenVectorsRed = SVD.TruncatedSVDSymLower(gammaInterGlobal2, tolerance) previousReducedOrderBasis = np.dot(Vinter.T, eigenVectorsRed).T gammaNPrevInd = np.dot(eigenVectorsRed.T, gammaInterLocal) collectionProblemData.AddReducedOrderBasis(solutionName, previousReducedOrderBasis) collectionProblemData.AddDataCompressionData(solutionName, gammaNPrevInd) if compressSolutions == True: collectionProblemData.CompressSolutions(solutionName, snapshotCorrelationOperator)
if __name__ == "__main__":# pragma: no cover from genericROM import RunTestFile RunTestFile(__file__)