From 96cceb6151ed5e186c0d7953be0ffb1f541c0cb1 Mon Sep 17 00:00:00 2001 From: Ali Elarif Date: Fri, 26 Aug 2022 15:06:21 +0200 Subject: [PATCH] Add computation of reduced basis with Feelpp solver #25 --- .../Cemosis/DataCompressors/NIRBOffline.py | 22 +++--- .../DataCompressors/SnapshotReducedBasis.py | 79 +++++++++++++++---- 2 files changed, 75 insertions(+), 26 deletions(-) diff --git a/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/NIRBOffline.py b/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/NIRBOffline.py index 2e1afa1..feec975 100644 --- a/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/NIRBOffline.py +++ b/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/NIRBOffline.py @@ -94,7 +94,7 @@ generate snapshots -------------------------------------- """ -nbeOfInitSnapshots = 30 +nbeOfInitSnapshots = 10 nev =nbeOfInitSnapshots print("-----------------------------------") print(" STEP I. 0: start init ") @@ -138,17 +138,18 @@ reducedOrderBasisU = SRB.ComputeReducedOrderBasisWithPOD(fineSnapList,l2ScalarProducMatrix) else : #POD reducedOrderBasisU = SRB.ComputeReducedOrderBasisWithPOD(fineSnapList, l2ScalarProducMatrix) - # reducedOrderBasisU = SPOD.ComputeReducedOrderBasisWithPOD(fineSnapList) - -### Add basis to collectionProblemData -collectionProblemData.AddReducedOrderBasis("U", reducedOrderBasisU) -# collectionProblemData.CompressSolutions("U", l2ScalarProducMatrix) #Mass matrix -nev=collectionProblemData.GetReducedOrderBasisNumberOfModes("U") -collectionProblemData.AddOperatorCompressionData("U", l2ScalarProducMatrix) # Mass matrix -collectionProblemData.AddDataCompressionData("U", h1ScalarProducMatrix) # Energy matrix +# number of modes +nev = reducedOrderBasisU.size[0] print("number of modes: ", nev) +### Add basis to collectionProblemData +# collectionProblemData.AddReducedOrderBasis("U", reducedOrderBasisU) +# # collectionProblemData.CompressSolutions("U", l2ScalarProducMatrix) #Mass matrix +# nev=collectionProblemData.GetReducedOrderBasisNumberOfModes("U") +# collectionProblemData.AddOperatorCompressionData("U", l2ScalarProducMatrix) # Mass matrix +# collectionProblemData.AddDataCompressionData("U", h1ScalarProducMatrix) # Energy matrix + print("----------------------------------------") print(" STEP I. 3: Save datas for Online phase ") @@ -161,7 +162,8 @@ file = "stiffnessMatrix.dat" SavePetscArrayBin(file, h1ScalarProducMatrix.mat()) file="reducedBasisU" -SIO.SaveState(file, reducedOrderBasisU) +SavePetscArrayBin(file, reducedOrderBasisU) +# SIO.SaveState(file, reducedOrderBasisU) ## Ortho basis verification """ diff --git a/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/SnapshotReducedBasis.py b/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/SnapshotReducedBasis.py index 74af151..7542bdf 100644 --- a/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/SnapshotReducedBasis.py +++ b/src/poc-1/src/Mordicus/Modules/Cemosis/DataCompressors/SnapshotReducedBasis.py @@ -5,8 +5,9 @@ # # -from ast import MatMult +# from ast import MatMult import os +# from statistics import correlation from mpi4py import MPI if MPI.COMM_WORLD.Get_size() > 1: # pragma: no cover os.environ["OMP_NUM_THREADS"] = "1" @@ -21,6 +22,7 @@ from petsc4py import PETSc import petsc4py from petsc4py import * +from slepc4py import SLEPc def ComputeReducedOrderBasisWithPOD(snapshotList, snapshotCorrelationOperator, tolerance=1.e-6): @@ -50,42 +52,87 @@ def ComputeReducedOrderBasisWithPOD(snapshotList, snapshotCorrelationOperator, t numberOfDofs = snapshotList[0].functionSpace().nDof() - for s in snapshotList: - snapshots.append(s.to_petsc().vec()[:]) - # snapshots = np.array(snapshots) # numberOfSnapshots = snapshots.shape[0] numberOfSnapshots = len(snapshotList) print('number of snapshots = ', numberOfSnapshots) - correlationMatrix = np.zeros((numberOfSnapshots, numberOfSnapshots)) + #correlationMatrix = np.zeros((numberOfSnapshots, numberOfSnapshots)) + + correlationMatrix = PETSc.Mat().create() + correlationMatrix.setSizes([numberOfSnapshots, numberOfSnapshots]) + correlationMatrix.setFromOptions() + correlationMatrix.setUp() + for i, snapshot1 in enumerate(snapshotList): for j, snapshot2 in enumerate(snapshotList): if i >= j: correlationMatrix[i, j] = snapshotCorrelationOperator.energy(snapshot1, snapshot2) + correlationMatrix.assemble() - mpiReducedCorrelationMatrix = np.zeros((numberOfSnapshots, numberOfSnapshots)) - MPI.COMM_WORLD.Allreduce([correlationMatrix, MPI.DOUBLE], [mpiReducedCorrelationMatrix, MPI.DOUBLE]) + # Get eigenpairs of the correlation matrix + E = SLEPc.EPS() + E.create() # create the solver + E.setOperators(correlationMatrix) + E.setFromOptions() + E.setWhichEigenpairs(E.Which.LARGEST_MAGNITUDE) + E.setDimensions(numberOfSnapshots) - from Mordicus.Core.BasicAlgorithms import SVD as SVD + E.solve() + nbePODModes = E.getConverged() # number of eigenpairs + print("nbePODModes =", nbePODModes) - eigenValuesRed, eigenVectorsRed = SVD.TruncatedSVDSymLower(mpiReducedCorrelationMatrix, tolerance) + eigenval = np.zeros(nbePODModes) - nbePODModes = eigenValuesRed.shape[0] + eigenvect = PETSc.Vec().create() + eigenvect.setSizes(nbePODModes) + eigenvect.setFromOptions() + eigenvect.setUp() - print("nbePODModes =", nbePODModes) + eigenMatrix = PETSc.Mat().createDense(nbePODModes) + # eigenMatrix.setSizes([nbePODModes, nbePODModes]) + eigenMatrix.setFromOptions() + eigenMatrix.setUp() + + eigenpairs = {} + + for i in range(nbePODModes): + eigenval[i] = float(E.getEigenvalue(i).real) + E.getEigenvector(i, eigenvect) + eigenpairs[eigenval[i]] = eigenvect/np.sqrt(eigenval[i]) # normalized eigenvect + eigenMatrix[i,:] = eigenvect[:]/np.sqrt(eigenval[i]) + + eigenMatrix.assemble() + + + + ## Set reduced basis + for s in snapshotList: + snapshots.append(s.to_petsc().vec()[:]) + + + reducedOrderBasis = PETSc.Mat().createDense(size=(nbePODModes,numberOfDofs)) + reducedOrderBasis.setFromOptions() + reducedOrderBasis.setUp() + + reducedOrderBasis.assemble() + + tempMat = reducedOrderBasis.copy() + # for i in range(nbePODModes): + # for j in range(numberOfDofs): + # reducedOrderBasis[i,j] = - changeOfBasisMatrix = np.zeros((nbePODModes,numberOfSnapshots)) - for j in range(nbePODModes): - changeOfBasisMatrix[j,:] = eigenVectorsRed[:,j]/np.sqrt(eigenValuesRed[j]) + for i in range(nbePODModes): + tempMat[i,:] = snapshotList[i].to_petsc().vec()[:] + # reducedOrderBasis[i,:] = snapshotList[i].to_petsc().vec()[:] - snapshots = np.array(snapshots) - reducedOrderBasis = np.dot(changeOfBasisMatrix,snapshots) + tempMat.assemble() + eigenMatrix.matMult(tempMat, reducedOrderBasis) return reducedOrderBasis