Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/Covarianceutils/GaussianSimulationSolver.F90
3206 views
1
!/*****************************************************************************/
2
! *
3
! * Elmer/Ice, a glaciological add-on to Elmer
4
! * http://elmerice.elmerfem.org
5
! *
6
! *
7
! * This program is free software; you can redistribute it and/or
8
! * modify it under the terms of the GNU General Public License
9
! * as published by the Free Software Foundation; either version 2
10
! * of the License, or (at your option) any later version.
11
! *
12
! * This program is distributed in the hope that it will be useful,
13
! * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
! * GNU General Public License for more details.
16
! *
17
! * You should have received a copy of the GNU General Public License
18
! * along with this program (in file fem/GPL-2); if not, write to the
19
! * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
! * Boston, MA 02110-1301, USA.
21
! *
22
! *****************************************************************************/
23
! ******************************************************************************
24
! ******************************************************************************
25
! *
26
! * Authors: F. Gillet-Chaulet
27
! * Web: http://elmerice.elmerfem.org
28
! *
29
! * Original Date: 24/06/2024
30
! *
31
! *****************************************************************************
32
!***********************************************************************************************
33
! Generate random realization from a given covariance matrix
34
!***********************************************************************************************
35
!***********************************************************************************************
36
!***********************************************************************************************
37
SUBROUTINE GaussianSimulationSolver( Model,Solver,dt,TransientSimulation )
38
!***********************************************************************************************
39
USE GeneralUtils
40
USE CovarianceUtils
41
IMPLICIT NONE
42
!------------------------------------------------------------------------------
43
TYPE(Solver_t) :: Solver
44
45
TYPE(Model_t) :: Model
46
REAL(KIND=dp) :: dt
47
LOGICAL :: TransientSimulation
48
49
TYPE(ValueList_t), POINTER :: SolverParams
50
51
TYPE(Variable_t), POINTER :: Var,Var_b
52
REAL(KIND=dp), POINTER :: Values(:),Values_b(:)
53
INTEGER, POINTER :: Perm(:),Perm_b(:)
54
CHARACTER(LEN=MAX_NAME_LEN) :: Varbname
55
INTEGER :: DOFs
56
57
INTEGER :: i,k
58
59
TYPE(Solver_t), POINTER, SAVE :: MSolver,KMSolver
60
REAL(kind=dp),allocatable,save :: aap(:) ! matrix in packed format
61
REAL(kind=dp),allocatable,save :: x(:),y(:)
62
REAL(kind=dp),allocatable,SAVE :: rr(:,:)
63
64
INTEGER,SAVE :: nn
65
INTEGER, ALLOCATABLE, SAVE :: ActiveNodes(:),InvPerm(:)
66
INTEGER,SAVE :: PbDim
67
68
CHARACTER(LEN=MAX_NAME_LEN),SAVE :: CovType
69
REAL(kind=dp),SAVE :: std
70
INTEGER :: Op
71
72
LOGICAL, SAVE :: Firsttime=.TRUE.
73
Logical :: Parallel
74
LOGICAL :: Found
75
76
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="GaussianSimualtion"
77
78
Integer,allocatable :: seed(:)
79
Integer :: ssize
80
81
! check Parallel/Serial
82
Parallel=(ParEnv % PEs > 1)
83
84
SolverParams => GetSolverParams()
85
86
Var => Solver % Variable
87
IF (.NOT.ASSOCIATED(Var)) &
88
CALL FATAL(SolverName,'Variable not associated')
89
Values => Var % Values
90
Perm => Var % Perm
91
DOFs = Var % DOFs
92
93
VarbName = ListGetString(SolverParams,"Background Variable name",UnFoundFatal=.TRUE.)
94
95
Var_b => VariableGet(Solver % Mesh % Variables,TRIM(VarbName),UnFoundFatal=.TRUE.)
96
Values_b => Var_b % Values
97
Perm_b => Var_b % Perm
98
IF (Var_b % DOFs.GT.1) &
99
CALL FATAL(SolverName,'DoFs for mean variable should be 1')
100
101
!! some initialisation
102
IF (Firsttime) THEN
103
CALL GetActiveNodesSet(Solver,nn,ActiveNodes,InvPerm,PbDim)
104
105
!Sanity check
106
IF (ANY(Perm_b(ActiveNodes(1:nn)).LT.0)) &
107
CALL FATAL(SolverName,"Pb with background variable perm")
108
109
!! The covariance type
110
CovType = ListGetString(SolverParams,"Covariance type",UnFoundFatal=.TRUE.)
111
std = ListGetConstReal(SolverParams,"standard deviation",UnFoundFatal=.TRUE.)
112
113
SELECT CASE (CovType)
114
115
CASE('diagonal')
116
CALL INFO(SolverName,"Using diagonal covariance",level=3)
117
118
CASE('full matrix')
119
CALL INFO(SolverName,"Using full matrix covariance",level=3)
120
121
Op=2
122
ALLOCATE(aap(nn*(nn+1)/2))
123
CALL CovarianceInit(Solver,nn,InvPerm,aap,Op,PbDim)
124
125
CASE('diffusion operator')
126
CALL INFO(SolverName,"Using diffusion operator covariance",level=3)
127
128
CALL CovarianceInit(Solver,MSolver,KMSolver)
129
130
END SELECT
131
132
allocate(x(nn),y(nn),rr(nn,DOFs))
133
134
Firsttime=.FALSE.
135
END IF
136
137
! CALL random_seed()
138
CALL random_seed(size=ssize)
139
allocate(seed(ssize))
140
seed = ListGetInteger( SolverParams , 'Random Seed',Found )
141
IF (Found) call random_seed( put=seed )
142
CALL random_seed(get=seed)
143
deallocate(seed)
144
145
!Create DOFs random vectors of size n
146
rr=0._dp
147
DO k=1,DOFs
148
DO i=1,nn
149
rr(i,k)=NormalRandom()
150
END DO
151
END DO
152
153
DO k=1,DOFs
154
x(Perm(ActiveNodes(1:nn)))=rr(ActiveNodes(1:nn),k)
155
156
SELECT CASE (CovType)
157
CASE('diagonal')
158
y(:) = std*x(:)
159
160
CASE('full matrix')
161
CALL SqrCovarianceVectorMultiply(Solver,nn,aap,x,y)
162
163
CASE('diffusion operator')
164
CALL SqrCovarianceVectorMultiply(Solver,MSolver,KMSolver,nn,x,y)
165
166
END SELECT
167
168
Values(DOFs*(Perm(ActiveNodes(1:nn))-1)+k)=Values_b(Perm_b(ActiveNodes(1:nn)))+&
169
y(Perm(ActiveNodes(1:nn)))
170
END DO
171
172
173
END SUBROUTINE GaussianSimulationSolver
174
175