1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2008-2024 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
23 import sys, unittest, numpy
25 # ==============================================================================
26 class TwoDimensionalInverseDistanceCS2010:
28 Two-dimensional inverse distance function of parameter µ=(µ1,µ2):
30 s(x,y,µ) = 1 / sqrt( (x-µ1)² + (y-µ2)² + 0.1² )
32 avec (x,y) ∈ [0.1,0.9]² et µ=(µ1,µ2) ∈ [-1,-0.01]².
34 This is the non-linear parametric function (3.38) of the reference:
35 Chaturantabut, S., Sorensen, D. C.,
36 Nonlinear Model Reduction via Discrete Empirical Interpolation,
37 SIAM Journal on Scientific Computing, 32(5), pp. 2737-2764 (2010).
39 def __init__(self, nx: int = 20, ny: int = 20):
42 self.x = numpy.linspace(0.1, 0.9, self.nx, dtype=float)
43 self.y = numpy.linspace(0.1, 0.9, self.ny, dtype=float)
45 def FunctionH(self, XX ):
46 __mu1, __mu2 = numpy.ravel(XX)
48 __x, __y = numpy.meshgrid( self.x, self.y )
49 __sxymu = 1. / numpy.sqrt( (__x - __mu1)**2 + (__y - __mu2)**2 + 0.1**2 )
56 def get_sample_of_mu(self, ns1: int = 20, ns2: int = 20):
57 smu1 = numpy.linspace(-1, -0.01, ns1, dtype=float)
58 smu2 = numpy.linspace(-1, -0.01, ns2, dtype=float)
59 smu = numpy.array([(mu1, mu2) for mu1 in smu1 for mu2 in smu2])
62 def get_random_sample_of_mu(self, ns1: int = 1, ns2: int = 1):
64 for i in range(ns1 * ns2):
65 smu1 = numpy.random.uniform(-1, -0.01)
66 smu2 = numpy.random.uniform(-1, -0.01)
67 smu.append((smu1, smu2))
68 smu = numpy.array(smu)
71 def get_bounds_on_space(self):
72 return [[min(self.x), max(self.x)], [min(self.y), max(self.y)]]
74 def get_bounds_on_parameter(self):
75 return [[-1, -0.01]] * 2
77 OneRealisation = FunctionH
79 # ==============================================================================
80 class LocalTest(unittest.TestCase):
83 print('\nAUTODIAGNOSTIC\n==============\n')
84 print(" " + TwoDimensionalInverseDistanceCS2010().__doc__.strip())
87 numpy.random.seed(123456789)
88 Equation = TwoDimensionalInverseDistanceCS2010()
89 for mu in Equation.get_sample_of_mu(5, 5):
90 solution = Equation.OneRealisation( mu )
91 # Nappe maximale au coin (0,0)
92 self.assertTrue(numpy.max(solution.flat) <= solution[0, 0])
93 # Nappe minimale au coin [-1,-1]
94 self.assertTrue(numpy.min(solution.flat) >= solution[-1, -1])
97 print("\n Tests OK\n")
99 # ==============================================================================
100 if __name__ == "__main__":
101 sys.stderr = sys.stdout
102 unittest.main(verbosity=0)