Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmerice/Solvers/Covarianceutils/CovarianceVectorMultiplySolver.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
! Comput the product of a covariance matrix with a vector
34
!***********************************************************************************************
35
!***********************************************************************************************
36
SUBROUTINE CovarianceVectorMultiplySolver( Model,Solver,dt,TransientSimulation )
37
!***********************************************************************************************
38
USE GeneralUtils
39
USE CovarianceUtils
40
IMPLICIT NONE
41
!------------------------------------------------------------------------------
42
TYPE(Solver_t) :: Solver
43
44
TYPE(Model_t) :: Model
45
REAL(KIND=dp) :: dt
46
LOGICAL :: TransientSimulation
47
48
TYPE(ValueList_t), POINTER :: SolverParams
49
50
TYPE(Variable_t), POINTER :: Var
51
REAL(KIND=dp), POINTER :: Values(:)
52
INTEGER, POINTER :: Perm(:)
53
CHARACTER(LEN=MAX_NAME_LEN) :: Varname
54
INTEGER :: DOFs
55
56
57
TYPE(Solver_t), POINTER, SAVE :: MSolver,KMSolver
58
REAL(kind=dp),allocatable,save :: aap(:) ! matrix in packed format
59
REAL(kind=dp),allocatable,save :: x(:),y(:),norm(:)
60
61
INTEGER,SAVE :: nn
62
INTEGER, ALLOCATABLE, SAVE :: ActiveNodes(:),InvPerm(:)
63
INTEGER,SAVE :: PbDim
64
65
CHARACTER(LEN=MAX_NAME_LEN),SAVE :: CovType
66
REAL(kind=dp),SAVE :: std
67
REAL(kind=dp) :: sigma2
68
INTEGER :: Op
69
70
LOGICAL, SAVE :: Firsttime=.TRUE.
71
LOGICAL, SAVE :: Normalize
72
LOGICAL :: Parallel
73
LOGICAL :: Found
74
75
CHARACTER(LEN=MAX_NAME_LEN) :: SolverName="Cov.x Solver"
76
77
! check Parallel/Serial
78
Parallel=(ParEnv % PEs > 1)
79
80
SolverParams => GetSolverParams()
81
82
VarName = ListGetString(SolverParams,"Input Variable",UnFoundFatal=.TRUE.)
83
84
Normalize = ListGetLogical(SolverParams,"Normalize",Found)
85
IF (.NOT.Found) Normalize=.FALSE.
86
87
Var => VariableGet( Solver % Mesh % Variables,TRIM(VarName), UnFoundFatal=.TRUE. )
88
Values => Var % Values
89
Perm => Var % Perm
90
DOFs = Var % DOFs
91
IF (DOFS.GT.1) &
92
CALL FATAL(SolverName,'Sorry 1DOFs variables')
93
94
!! some initialisation
95
IF (Firsttime) THEN
96
97
CALL GetActiveNodesSet(Solver,nn,ActiveNodes,InvPerm,PbDim)
98
99
!Sanity check
100
IF (ANY(Perm(ActiveNodes(1:nn)).LT.0)) &
101
CALL FATAL(SolverName,"Pb with input variable perm")
102
103
!! The covariance type
104
CovType = ListGetString(SolverParams,"Covariance type",UnFoundFatal=.TRUE.)
105
std = ListGetConstReal(SolverParams,"standard deviation",UnFoundFatal=.TRUE.)
106
107
SELECT CASE (CovType)
108
109
CASE('diagonal')
110
CALL INFO(SolverName,"Using diagonal covariance",level=3)
111
112
CASE('full matrix')
113
CALL INFO(SolverName,"Using full matrix covariance",level=3)
114
115
Op=1
116
ALLOCATE(aap(nn*(nn+1)/2))
117
CALL CovarianceInit(Solver,nn,InvPerm,aap,Op,PbDim)
118
119
CASE('diffusion operator')
120
CALL INFO(SolverName,"Using diffusion operator covariance",level=3)
121
122
CALL CovarianceInit(Solver,MSolver,KMSolver)
123
124
END SELECT
125
126
allocate(x(nn),y(nn))
127
128
IF (Normalize) THEN
129
allocate(norm(nn))
130
131
!input vector
132
x(:) = 1._dp
133
134
! C . x
135
SELECT CASE (CovType)
136
137
CASE('diagonal')
138
sigma2=std**2
139
norm(:)=sigma2*x(:)
140
141
CASE('full matrix')
142
CALL CovarianceVectorMultiply(Solver,nn,aap,x,norm)
143
144
CASE('diffusion operator')
145
! y = SIGMA C SIGMA . x
146
CALL CovarianceVectorMultiply(Solver,MSolver,KMSolver,nn,x,norm)
147
148
END SELECT
149
END IF
150
151
Firsttime=.FALSE.
152
END IF
153
154
!input vector
155
x(Solver%Variable%Perm(ActiveNodes(1:nn))) = Values(Perm(ActiveNodes(1:nn)))
156
157
! C . x
158
SELECT CASE (CovType)
159
160
CASE('diagonal')
161
sigma2=std**2
162
y(:)=sigma2*x(:)
163
164
CASE('full matrix')
165
CALL CovarianceVectorMultiply(Solver,nn,aap,x,y)
166
167
CASE('diffusion operator')
168
! y = SIGMA C SIGMA . x
169
CALL CovarianceVectorMultiply(Solver,MSolver,KMSolver,nn,x,y)
170
171
END SELECT
172
173
IF (Normalize) y(:)=y(:)/norm(:)
174
175
Solver % Variable % Values(Solver%Variable%Perm(ActiveNodes(1:nn)))=&
176
y(Solver%Variable%Perm(ActiveNodes(1:nn)))
177
178
END SUBROUTINE CovarianceVectorMultiplySolver
179
180