Salome HOME
Updating version and copyright date information
[modules/adao.git] / src / daComposant / daAlgorithms / EnsembleKalmanFilter.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (C) 2008-2021 EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
22
23 import logging
24 from daCore import BasicObjects, NumericObjects
25 import numpy
26
27 # ==============================================================================
28 class ElementaryAlgorithm(BasicObjects.Algorithm):
29     def __init__(self):
30         BasicObjects.Algorithm.__init__(self, "ENSEMBLEKALMANFILTER")
31         self.defineRequiredParameter(
32             name     = "Minimizer",
33             default  = "StochasticEnKF",
34             typecast = str,
35             message  = "Minimiseur utilisé",
36             listval  = [
37                 "StochasticEnKF",
38                 "ETKF",
39                 "ETKF-KFF",
40                 "ETKF-VAR",
41                 ],
42             )
43         self.defineRequiredParameter(
44             name     = "NumberOfMembers",
45             default  = 100,
46             typecast = int,
47             message  = "Nombre de membres dans l'ensemble",
48             minval   = -1,
49             )
50         self.defineRequiredParameter(
51             name     = "EstimationOf",
52             default  = "State",
53             typecast = str,
54             message  = "Estimation d'etat ou de parametres",
55             listval  = ["State", "Parameters"],
56             )
57         self.defineRequiredParameter(
58             name     = "InflationType",
59             default  = "MultiplicativeOnAnalysisCovariance",
60             typecast = str,
61             message  = "Méthode d'inflation d'ensemble",
62             listval  = [
63                 "MultiplicativeOnAnalysisCovariance",
64                 "MultiplicativeOnBackgroundCovariance",
65                 "MultiplicativeOnAnalysisAnomalies",
66                 "MultiplicativeOnBackgroundAnomalies",
67                 "AdditiveOnBackgroundCovariance",
68                 "AdditiveOnAnalysisCovariance",
69                 "HybridOnBackgroundCovariance",
70                 ],
71             )
72         self.defineRequiredParameter(
73             name     = "InflationFactor",
74             default  = 1.,
75             typecast = float,
76             message  = "Facteur d'inflation",
77             minval   = 0.,
78             )
79         self.defineRequiredParameter(
80             name     = "LocalizationType",
81             default  = "SchurLocalization",
82             typecast = str,
83             message  = "Méthode d'inflation d'ensemble",
84             listval  = [
85                 "CovarianceLocalization",
86                 "DomainLocalization",
87                 "SchurLocalization",
88                 "GaspariCohnLocalization",
89                 ],
90             )
91         self.defineRequiredParameter(
92             name     = "LocalizationFactor",
93             default  = 1.,
94             typecast = float,
95             message  = "Facteur de localisation",
96             minval   = 0.,
97             )
98         self.defineRequiredParameter( # Pas de type
99             name     = "LocalizationMatrix",
100             message  = "Matrice de localisation ou de distances",
101             )
102         self.defineRequiredParameter(
103             name     = "SetSeed",
104             typecast = numpy.random.seed,
105             message  = "Graine fixée pour le générateur aléatoire",
106             )
107         self.defineRequiredParameter(
108             name     = "StoreInternalVariables",
109             default  = False,
110             typecast = bool,
111             message  = "Stockage des variables internes ou intermédiaires du calcul",
112             )
113         self.defineRequiredParameter(
114             name     = "StoreSupplementaryCalculations",
115             default  = [],
116             typecast = tuple,
117             message  = "Liste de calculs supplémentaires à stocker et/ou effectuer",
118             listval  = [
119                 "Analysis",
120                 "APosterioriCorrelations",
121                 "APosterioriCovariance",
122                 "APosterioriStandardDeviations",
123                 "APosterioriVariances",
124                 "BMA",
125                 "CostFunctionJ",
126                 "CostFunctionJAtCurrentOptimum",
127                 "CostFunctionJb",
128                 "CostFunctionJbAtCurrentOptimum",
129                 "CostFunctionJo",
130                 "CostFunctionJoAtCurrentOptimum",
131                 "CurrentIterationNumber",
132                 "CurrentOptimum",
133                 "CurrentState",
134                 "ForecastState",
135                 "IndexOfOptimum",
136                 "InnovationAtCurrentAnalysis",
137                 "InnovationAtCurrentState",
138                 "SimulatedObservationAtCurrentAnalysis",
139                 "SimulatedObservationAtCurrentOptimum",
140                 "SimulatedObservationAtCurrentState",
141                 ]
142             )
143         self.requireInputArguments(
144             mandatory= ("Xb", "Y", "HO", "R", "B"),
145             optional = ("U", "EM", "CM", "Q"),
146             )
147         self.setAttributes(tags=(
148             "DataAssimilation",
149             "NonLinear",
150             "Filter",
151             "Ensemble",
152             "Dynamic",
153             ))
154
155     def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None):
156         self._pre_run(Parameters, Xb, Y, U, HO, EM, CM, R, B, Q)
157         #
158         if self._parameters["Minimizer"] == "StochasticEnKF":
159             NumericObjects.senkf(self, Xb, Y, U, HO, EM, CM, R, B, Q)
160         elif self._parameters["Minimizer"] in ["ETKF", "ETKF-KFF"]:
161             NumericObjects.etkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, KorV="KalmanFilterFormula")
162         elif self._parameters["Minimizer"] == "ETKF-VAR":
163             NumericObjects.etkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, KorV="Variational")
164         else:
165             raise ValueError("Error in Minimizer name: %s"%self._parameters["Minimizer"])
166         #
167         self._post_run(HO)
168         return 0
169
170 # ==============================================================================
171 if __name__ == "__main__":
172     print('\n AUTODIAGNOSTIC\n')