Path: blob/devel/elmerice/Solvers/Covarianceutils/GaussianSimulationSolver.F90
3206 views
!/*****************************************************************************/1! *2! * Elmer/Ice, a glaciological add-on to Elmer3! * http://elmerice.elmerfem.org4! *5! *6! * This program is free software; you can redistribute it and/or7! * modify it under the terms of the GNU General Public License8! * as published by the Free Software Foundation; either version 29! * of the License, or (at your option) any later version.10! *11! * This program is distributed in the hope that it will be useful,12! * but WITHOUT ANY WARRANTY; without even the implied warranty of13! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14! * GNU General Public License for more details.15! *16! * You should have received a copy of the GNU General Public License17! * along with this program (in file fem/GPL-2); if not, write to the18! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,19! * Boston, MA 02110-1301, USA.20! *21! *****************************************************************************/22! ******************************************************************************23! ******************************************************************************24! *25! * Authors: F. Gillet-Chaulet26! * Web: http://elmerice.elmerfem.org27! *28! * Original Date: 24/06/202429! *30! *****************************************************************************31!***********************************************************************************************32! Generate random realization from a given covariance matrix33!***********************************************************************************************34!***********************************************************************************************35!***********************************************************************************************36SUBROUTINE GaussianSimulationSolver( Model,Solver,dt,TransientSimulation )37!***********************************************************************************************38USE GeneralUtils39USE CovarianceUtils40IMPLICIT NONE41!------------------------------------------------------------------------------42TYPE(Solver_t) :: Solver4344TYPE(Model_t) :: Model45REAL(KIND=dp) :: dt46LOGICAL :: TransientSimulation4748TYPE(ValueList_t), POINTER :: SolverParams4950TYPE(Variable_t), POINTER :: Var,Var_b51REAL(KIND=dp), POINTER :: Values(:),Values_b(:)52INTEGER, POINTER :: Perm(:),Perm_b(:)53CHARACTER(LEN=MAX_NAME_LEN) :: Varbname54INTEGER :: DOFs5556INTEGER :: i,k5758TYPE(Solver_t), POINTER, SAVE :: MSolver,KMSolver59REAL(kind=dp),allocatable,save :: aap(:) ! matrix in packed format60REAL(kind=dp),allocatable,save :: x(:),y(:)61REAL(kind=dp),allocatable,SAVE :: rr(:,:)6263INTEGER,SAVE :: nn64INTEGER, ALLOCATABLE, SAVE :: ActiveNodes(:),InvPerm(:)65INTEGER,SAVE :: PbDim6667CHARACTER(LEN=MAX_NAME_LEN),SAVE :: CovType68REAL(kind=dp),SAVE :: std69INTEGER :: Op7071LOGICAL, SAVE :: Firsttime=.TRUE.72Logical :: Parallel73LOGICAL :: Found7475CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="GaussianSimualtion"7677Integer,allocatable :: seed(:)78Integer :: ssize7980! check Parallel/Serial81Parallel=(ParEnv % PEs > 1)8283SolverParams => GetSolverParams()8485Var => Solver % Variable86IF (.NOT.ASSOCIATED(Var)) &87CALL FATAL(SolverName,'Variable not associated')88Values => Var % Values89Perm => Var % Perm90DOFs = Var % DOFs9192VarbName = ListGetString(SolverParams,"Background Variable name",UnFoundFatal=.TRUE.)9394Var_b => VariableGet(Solver % Mesh % Variables,TRIM(VarbName),UnFoundFatal=.TRUE.)95Values_b => Var_b % Values96Perm_b => Var_b % Perm97IF (Var_b % DOFs.GT.1) &98CALL FATAL(SolverName,'DoFs for mean variable should be 1')99100!! some initialisation101IF (Firsttime) THEN102CALL GetActiveNodesSet(Solver,nn,ActiveNodes,InvPerm,PbDim)103104!Sanity check105IF (ANY(Perm_b(ActiveNodes(1:nn)).LT.0)) &106CALL FATAL(SolverName,"Pb with background variable perm")107108!! The covariance type109CovType = ListGetString(SolverParams,"Covariance type",UnFoundFatal=.TRUE.)110std = ListGetConstReal(SolverParams,"standard deviation",UnFoundFatal=.TRUE.)111112SELECT CASE (CovType)113114CASE('diagonal')115CALL INFO(SolverName,"Using diagonal covariance",level=3)116117CASE('full matrix')118CALL INFO(SolverName,"Using full matrix covariance",level=3)119120Op=2121ALLOCATE(aap(nn*(nn+1)/2))122CALL CovarianceInit(Solver,nn,InvPerm,aap,Op,PbDim)123124CASE('diffusion operator')125CALL INFO(SolverName,"Using diffusion operator covariance",level=3)126127CALL CovarianceInit(Solver,MSolver,KMSolver)128129END SELECT130131allocate(x(nn),y(nn),rr(nn,DOFs))132133Firsttime=.FALSE.134END IF135136! CALL random_seed()137CALL random_seed(size=ssize)138allocate(seed(ssize))139seed = ListGetInteger( SolverParams , 'Random Seed',Found )140IF (Found) call random_seed( put=seed )141CALL random_seed(get=seed)142deallocate(seed)143144!Create DOFs random vectors of size n145rr=0._dp146DO k=1,DOFs147DO i=1,nn148rr(i,k)=NormalRandom()149END DO150END DO151152DO k=1,DOFs153x(Perm(ActiveNodes(1:nn)))=rr(ActiveNodes(1:nn),k)154155SELECT CASE (CovType)156CASE('diagonal')157y(:) = std*x(:)158159CASE('full matrix')160CALL SqrCovarianceVectorMultiply(Solver,nn,aap,x,y)161162CASE('diffusion operator')163CALL SqrCovarianceVectorMultiply(Solver,MSolver,KMSolver,nn,x,y)164165END SELECT166167Values(DOFs*(Perm(ActiveNodes(1:nn))-1)+k)=Values_b(Perm_b(ActiveNodes(1:nn)))+&168y(Perm(ActiveNodes(1:nn)))169END DO170171172END SUBROUTINE GaussianSimulationSolver173174175