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