1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2008-2023 EDF R&D
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.
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.
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
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 # Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D
26 __author__ = "Jean-Philippe ARGAUD"
29 import daCore.Persistence
31 # ==============================================================================
32 def EIM_offline(selfA, EOS = None, Verbose = False):
34 Établissement de base par Empirical Interpolation Method (EIM)
39 if isinstance(EOS, (numpy.ndarray, numpy.matrix)):
40 __EOS = numpy.asarray(EOS)
41 elif isinstance(EOS, (list, tuple, daCore.Persistence.Persistence)):
42 __EOS = numpy.stack([numpy.ravel(_sn) for _sn in EOS], axis=1)
43 # __EOS = numpy.asarray(EOS).T
45 raise ValueError("EnsembleOfSnapshots has to be an array/matrix (each column being a vector) or a list/tuple (each element being a vector).")
47 if selfA._parameters["ErrorNorm"] == "L2":
48 MaxNormByColumn = MaxL2NormByColumn
50 MaxNormByColumn = MaxLinfNormByColumn
52 if selfA._parameters["Variant"] == "PositioningByEIM":
56 if __LcCsts and "ExcludeLocations" in selfA._parameters:
57 __ExcludedMagicPoints = selfA._parameters["ExcludeLocations"]
59 __ExcludedMagicPoints = []
60 if __LcCsts and len(__ExcludedMagicPoints) > 0:
61 __ExcludedMagicPoints = numpy.ravel(numpy.asarray(__ExcludedMagicPoints, dtype=int))
62 __IncludedMagicPoints = numpy.setdiff1d(
63 numpy.arange(__EOS.shape[0]),
64 __ExcludedMagicPoints,
68 __IncludedMagicPoints = []
70 __dimS, __nbmS = __EOS.shape
71 if "MaximumNumberOfLocations" in selfA._parameters and "MaximumRBSize" in selfA._parameters:
72 selfA._parameters["MaximumRBSize"] = min(selfA._parameters["MaximumNumberOfLocations"],selfA._parameters["MaximumRBSize"])
73 elif "MaximumNumberOfLocations" in selfA._parameters:
74 selfA._parameters["MaximumRBSize"] = selfA._parameters["MaximumNumberOfLocations"]
75 elif "MaximumRBSize" in selfA._parameters:
78 selfA._parameters["MaximumRBSize"] = __nbmS
79 __maxM = min(selfA._parameters["MaximumRBSize"], __dimS, __nbmS)
80 if "ErrorNormTolerance" in selfA._parameters:
81 selfA._parameters["EpsilonEIM"] = selfA._parameters["ErrorNormTolerance"]
83 selfA._parameters["EpsilonEIM"] = 1.e-2
87 __Q = numpy.empty(__dimS)
92 __rhoM = numpy.empty(__dimS)
94 __eM, __muM = MaxNormByColumn(__EOS, __LcCsts, __IncludedMagicPoints)
95 __residuM = __EOS[:,__muM]
100 while __M < __maxM and __eM > selfA._parameters["EpsilonEIM"]:
105 # Détermination du point et de la fonction magiques
106 __abs_residuM = numpy.abs(__residuM)
107 __iM = numpy.argmax(__abs_residuM)
108 __rhoM = __residuM / __abs_residuM[__iM]
110 if __LcCsts and __iM in __ExcludedMagicPoints:
111 __sIndices = numpy.argsort(__abs_residuM)
113 assert __iM == __sIndices[__rang]
114 while __iM in __ExcludedMagicPoints and __rang >= -len(__abs_residuM):
116 __iM = __sIndices[__rang]
119 __Q = numpy.column_stack((__Q, __rhoM))
124 __restrictedQi = __Q[__I]
126 __Qi_inv = numpy.linalg.inv(__restrictedQi)
128 __Qi_inv = 1. / __restrictedQi
130 __restrictedEOSi = __EOS[__I]
132 __interpolator = numpy.empty(__EOS.shape)
134 __interpolator = numpy.dot(__Q,numpy.dot(__Qi_inv,__restrictedEOSi))
136 __interpolator = numpy.outer(__Q,numpy.outer(__Qi_inv,__restrictedEOSi))
138 __dataForNextIter = __EOS - __interpolator
139 __eM, __muM = MaxNormByColumn(__dataForNextIter, __LcCsts, __IncludedMagicPoints)
140 __errors.append(__eM)
142 __residuM = __dataForNextIter[:,__muM]
144 #--------------------------
145 if hasattr(selfA, "StoredVariables"):
146 selfA.StoredVariables["OptimalPoints"].store( __I )
147 if selfA._toStore("ReducedBasis"):
148 selfA.StoredVariables["ReducedBasis"].store( __Q )
149 if selfA._toStore("Residus"):
150 selfA.StoredVariables["Residus"].store( __errors )
152 return __mu, __I, __Q, __errors
154 # ==============================================================================
155 def EIM_online(selfA, QEIM, mu, iEIM):
156 raise NotImplementedError()
158 # ==============================================================================
159 def MaxL2NormByColumn(Ensemble, LcCsts = False, IncludedPoints = []):
161 if LcCsts and len(IncludedPoints) > 0:
162 for indice in range(Ensemble.shape[1]):
163 norme = numpy.linalg.norm(
164 numpy.take(Ensemble[:,indice], IncludedPoints, mode='clip'),
167 nmax, imax, = norme, indice
169 for indice in range(Ensemble.shape[1]):
170 norme = numpy.linalg.norm(
174 nmax, imax, = norme, indice
177 def MaxLinfNormByColumn(Ensemble, LcCsts = False, IncludedPoints = []):
179 if LcCsts and len(IncludedPoints) > 0:
180 for indice in range(Ensemble.shape[1]):
181 norme = numpy.linalg.norm(
182 numpy.take(Ensemble[:,indice], IncludedPoints, mode='clip'),
186 nmax, imax, = norme, indice
188 for indice in range(Ensemble.shape[1]):
189 norme = numpy.linalg.norm(
194 nmax, imax, = norme, indice
197 # ==============================================================================
198 if __name__ == "__main__":
199 print('\n AUTODIAGNOSTIC\n')