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