Salome HOME
Minor improvements for internal variables
[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                 "EnKF",
39                 "ETKF",
40                 "ETKF-N",
41                 "MLEF",
42                 "IEnKF",
43                 ],
44             listadv  = [
45                 "ETKF-KFF",
46                 "ETKF-VAR",
47                 "ETKF-N-11",
48                 "ETKF-N-15",
49                 "ETKF-N-16",
50                 "MLEF-T",
51                 "MLEF-B",
52                 "IEnKF-T",
53                 "IEnKF-B",
54                 "IEKF",
55                 ],
56             )
57         self.defineRequiredParameter(
58             name     = "NumberOfMembers",
59             default  = 100,
60             typecast = int,
61             message  = "Nombre de membres dans l'ensemble",
62             minval   = 2,
63             )
64         self.defineRequiredParameter(
65             name     = "EstimationOf",
66             default  = "State",
67             typecast = str,
68             message  = "Estimation d'etat ou de parametres",
69             listval  = ["State", "Parameters"],
70             )
71         self.defineRequiredParameter(
72             name     = "InflationType",
73             default  = "MultiplicativeOnAnalysisCovariance",
74             typecast = str,
75             message  = "Méthode d'inflation d'ensemble",
76             listval  = [
77                 "MultiplicativeOnAnalysisCovariance",
78                 "MultiplicativeOnBackgroundCovariance",
79                 "MultiplicativeOnAnalysisAnomalies",
80                 "MultiplicativeOnBackgroundAnomalies",
81                 "AdditiveOnBackgroundCovariance",
82                 "AdditiveOnAnalysisCovariance",
83                 "HybridOnBackgroundCovariance",
84                 ],
85             )
86         self.defineRequiredParameter(
87             name     = "InflationFactor",
88             default  = 1.,
89             typecast = float,
90             message  = "Facteur d'inflation",
91             minval   = 0.,
92             )
93         self.defineRequiredParameter(
94             name     = "LocalizationType",
95             default  = "SchurLocalization",
96             typecast = str,
97             message  = "Méthode d'inflation d'ensemble",
98             listval  = [
99                 "CovarianceLocalization",
100                 "DomainLocalization",
101                 "SchurLocalization",
102                 "GaspariCohnLocalization",
103                 ],
104             )
105         self.defineRequiredParameter(
106             name     = "LocalizationFactor",
107             default  = 1.,
108             typecast = float,
109             message  = "Facteur de localisation",
110             minval   = 0.,
111             )
112         self.defineRequiredParameter( # Pas de type
113             name     = "LocalizationMatrix",
114             message  = "Matrice de localisation ou de distances",
115             )
116         self.defineRequiredParameter(
117             name     = "SetSeed",
118             typecast = numpy.random.seed,
119             message  = "Graine fixée pour le générateur aléatoire",
120             )
121         self.defineRequiredParameter(
122             name     = "StoreInternalVariables",
123             default  = False,
124             typecast = bool,
125             message  = "Stockage des variables internes ou intermédiaires du calcul",
126             )
127         self.defineRequiredParameter(
128             name     = "StoreSupplementaryCalculations",
129             default  = [],
130             typecast = tuple,
131             message  = "Liste de calculs supplémentaires à stocker et/ou effectuer",
132             listval  = [
133                 "Analysis",
134                 "APosterioriCorrelations",
135                 "APosterioriCovariance",
136                 "APosterioriStandardDeviations",
137                 "APosterioriVariances",
138                 "BMA",
139                 "CostFunctionJ",
140                 "CostFunctionJAtCurrentOptimum",
141                 "CostFunctionJb",
142                 "CostFunctionJbAtCurrentOptimum",
143                 "CostFunctionJo",
144                 "CostFunctionJoAtCurrentOptimum",
145                 "CurrentIterationNumber",
146                 "CurrentOptimum",
147                 "CurrentState",
148                 "ForecastState",
149                 "IndexOfOptimum",
150                 "InnovationAtCurrentAnalysis",
151                 "InnovationAtCurrentState",
152                 "SimulatedObservationAtCurrentAnalysis",
153                 "SimulatedObservationAtCurrentOptimum",
154                 "SimulatedObservationAtCurrentState",
155                 ]
156             )
157         self.requireInputArguments(
158             mandatory= ("Xb", "Y", "HO", "R", "B"),
159             optional = ("U", "EM", "CM", "Q"),
160             )
161         self.setAttributes(tags=(
162             "DataAssimilation",
163             "NonLinear",
164             "Filter",
165             "Ensemble",
166             "Dynamic",
167             ))
168
169     def run(self, Xb=None, Y=None, U=None, HO=None, EM=None, CM=None, R=None, B=None, Q=None, Parameters=None):
170         self._pre_run(Parameters, Xb, Y, U, HO, EM, CM, R, B, Q)
171         #
172         #--------------------------
173         # Default EnKF = StochasticEnKF
174         if self._parameters["Minimizer"] in ["StochasticEnKF", "EnKF"]:
175             NumericObjects.senkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, VariantM="KalmanFilterFormula")
176         #
177         #--------------------------
178         # Default ETKF = ETKF-KFF
179         elif self._parameters["Minimizer"] in ["ETKF-KFF", "ETKF"]:
180             NumericObjects.etkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, VariantM="KalmanFilterFormula")
181         #
182         elif self._parameters["Minimizer"] == "ETKF-VAR":
183             NumericObjects.etkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, VariantM="Variational")
184         #
185         #--------------------------
186         # Default ETKF-N = ETKF-N-16
187         elif self._parameters["Minimizer"] == "ETKF-N-11":
188             NumericObjects.etkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, VariantM="FiniteSize11")
189         #
190         elif self._parameters["Minimizer"] == "ETKF-N-15":
191             NumericObjects.etkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, VariantM="FiniteSize15")
192         #
193         elif self._parameters["Minimizer"] in ["ETKF-N-16", "ETKF-N"]:
194             NumericObjects.etkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, VariantM="FiniteSize16")
195         #
196         #--------------------------
197         # Default MLEF = MLEF-T
198         elif self._parameters["Minimizer"] in ["MLEF-T", "MLEF"]:
199             NumericObjects.mlef(self, Xb, Y, U, HO, EM, CM, R, B, Q, BnotT=False)
200         #
201         elif self._parameters["Minimizer"] == "MLEF-B":
202             NumericObjects.mlef(self, Xb, Y, U, HO, EM, CM, R, B, Q, BnotT=True)
203         #
204         #--------------------------
205         # Default IEnKF = IEnKF-T
206         elif self._parameters["Minimizer"] in ["IEnKF-T", "IEnKF"]:
207             NumericObjects.ienkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, BnotT=False)
208         #
209         elif self._parameters["Minimizer"] in ["IEnKF-B", "IEKF"]:
210             NumericObjects.ienkf(self, Xb, Y, U, HO, EM, CM, R, B, Q, BnotT=True)
211         #
212         #--------------------------
213         else:
214             raise ValueError("Error in Minimizer name: %s"%self._parameters["Minimizer"])
215         #
216         self._post_run(HO)
217         return 0
218
219 # ==============================================================================
220 if __name__ == "__main__":
221     print('\n AUTODIAGNOSTIC\n')