From: Jean-Philippe ARGAUD Date: Sun, 26 May 2024 19:25:59 +0000 (+0200) Subject: Documentation examples corrections and update X-Git-Tag: V9_13_0a1~7 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=6108de0baf59f7282712bad3546b05e2738475f4;p=modules%2Fadao.git Documentation examples corrections and update --- diff --git a/doc/en/ref_algorithm_InterpolationByReducedModelTest.rst b/doc/en/ref_algorithm_InterpolationByReducedModelTest.rst index f6c55eb..d122878 100644 --- a/doc/en/ref_algorithm_InterpolationByReducedModelTest.rst +++ b/doc/en/ref_algorithm_InterpolationByReducedModelTest.rst @@ -31,13 +31,14 @@ Checking algorithm "*InterpolationByReducedModelTest*" .. include:: snippets/Header2Algo01.rst This algorithm provides a simple way of analyzing the quality of the empirical -state interpolation obtained using a reduced basis, using measurements at -specific points. +interpolation obtained by a reduced basis for complete states, using +measurements at precise points. The results displayed by default are simple statistics related to the -normalized errors of interpolation with a reduced basis. The test uses a -reduced base and a set of optimal measurement positions, and uses -pseudo-measurements from each complete state (“*snapshot*”) included in the +normalized errors between the interpolation with a reduced basis and the +complete states we seek to represent on the reduced basis. The test requires a +reduced basis and a set of optimal measurement positions, and uses +pseudo-measurements from each complete state ("*snapshot*") included in the given test set. Please note: to be consistent, this test must use the same mathematical norm as diff --git a/doc/en/ref_algorithm_MeasurementsOptimalPositioningTask.rst b/doc/en/ref_algorithm_MeasurementsOptimalPositioningTask.rst index 7e260eb..a61ccd3 100644 --- a/doc/en/ref_algorithm_MeasurementsOptimalPositioningTask.rst +++ b/doc/en/ref_algorithm_MeasurementsOptimalPositioningTask.rst @@ -220,6 +220,33 @@ StoreSupplementaryCalculations .. literalinclude:: scripts/simple_MeasurementsOptimalPositioningTask2.res :language: none +.. --------- .. +.. include:: scripts/simple_MeasurementsOptimalPositioningTask3.rst + +.. literalinclude:: scripts/simple_MeasurementsOptimalPositioningTask3.py + +.. include:: snippets/Header2Algo10.rst + +.. literalinclude:: scripts/simple_MeasurementsOptimalPositioningTask3.res + :language: none + +.. include:: snippets/Header2Algo11.rst + +.. _simple_MeasurementsOptimalPositioningTask31: +.. image:: scripts/simple_MeasurementsOptimalPositioningTask31.png + :align: center + :width: 60% + +.. _simple_MeasurementsOptimalPositioningTask32: +.. image:: scripts/simple_MeasurementsOptimalPositioningTask32.png + :align: center + :width: 60% + +.. _simple_MeasurementsOptimalPositioningTask33: +.. image:: scripts/simple_MeasurementsOptimalPositioningTask33.png + :align: center + :width: 60% + .. ------------------------------------ .. .. include:: snippets/Header2Algo06.rst diff --git a/doc/en/ref_observations_requirements.rst b/doc/en/ref_observations_requirements.rst index 81f896d..3ec2454 100644 --- a/doc/en/ref_observations_requirements.rst +++ b/doc/en/ref_observations_requirements.rst @@ -91,14 +91,15 @@ of measurements, or several fields physically homogeneous or not. - data text file (TXT, CSV, TSV, DAT), with variable pointer by name in column or row, indicated by the keyword "*DataFile*" with the condition ``Vector=True`` - binary data file (NPY, NPZ), with variable pointer by name, indicated by the keyword "*DataFile*" with the condition ``Vector=True`` -- Examples of statements in TUI interface: +Examples of statements in TUI interface: +:: - - ``case.setObservation( Vector = [1, 2, 3] )`` - - ``case.setObservation( Vector = numpy.array([1, 2, 3]) )`` - - ``case.setObservation( Vector = '1 2 3' )`` - - ``case.setObservation( Vector=True, Script = 'script.py' )``` - - ``case.setObservation( Vector=True, DataFile = 'data.csv' )``` - - ``case.setObservation( Vector=True, DataFile = 'data.npy' )``` + case.setObservation( Vector = [1, 2, 3] ) + case.setObservation( Vector = numpy.array([1, 2, 3]) ) + case.setObservation( Vector = '1 2 3' ) + case.setObservation( Vector=True, Script = 'script.py' ) + case.setObservation( Vector=True, DataFile = 'data.csv' ) + case.setObservation( Vector=True, DataFile = 'data.npy' ) Use note: in a given study, only the last record (whether a single vector or a series of vectors) can be used, as only one observation concept exists per ADAO @@ -139,16 +140,17 @@ of which we consider a history. - data text file (TXT, CSV, TSV), with variable pointer by name in column or row, indicated by the keyword "*DataFile*" with the condition ``VectorSerie=True`` - binary data file (NPY, NPZ), with variable pointer by name, indicated by the keyword "*DataFile*" with the condition ``VectorSerie=True`` -- Examples of statements in TUI interface: - - - ``case.setObservation( VectorSerie = [[1,2,3], [1,2,3]] )`` - - ``case.setObservation( VectorSerie = [numpy.array([1,2,3]), numpy.array([1,2,3])] )`` - - ``case.setObservation( VectorSerie = ['1 2 3', '1 2 3'] )`` - - ``case.setObservation( VectorSerie = '[[1,2,3], [1,2,3]]' )`` - - ``case.setObservation( VectorSerie = '1 2 3 ; 1 2 3' )`` - - ``case.setObservation( VectorSerie=True, Script = 'script.py' )``` - - ``case.setObservation( VectorSerie=True, DataFile = 'data.csv' )``` - - ``case.setObservation( VectorSerie=True, DataFile = 'data.npy' )``` +Examples of statements in TUI interface: +:: + + case.setObservation( VectorSerie = [[1,2,3], [1,2,3]] ) + case.setObservation( VectorSerie = [numpy.array([1,2,3]), numpy.array([1,2,3])] ) + case.setObservation( VectorSerie = ['1 2 3', '1 2 3'] ) + case.setObservation( VectorSerie = '[[1,2,3], [1,2,3]]' ) + case.setObservation( VectorSerie = '1 2 3 ; 1 2 3' ) + case.setObservation( VectorSerie=True, Script = 'script.py' ) + case.setObservation( VectorSerie=True, DataFile = 'data.csv' ) + case.setObservation( VectorSerie=True, DataFile = 'data.npy' ) Use note: in a given study, only the last record (whether a single vector or a series of vectors) can be used, as only one observation concept exists per ADAO diff --git a/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.py b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.py new file mode 100644 index 0000000..8878d12 --- /dev/null +++ b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# +import numpy as np +import matplotlib.pyplot as plt +np.random.seed(123456789) +# +dimension = 20 +# +print("Defining a set of artificial physical fields") +from Models.TwoDimensionalInverseDistanceCS2010 \ + import TwoDimensionalInverseDistanceCS2010 as Equation +Eq = Equation(dimension, dimension) +print() +# +print("Search for optimal measurement positions") +from adao import adaoBuilder +case = adaoBuilder.New() +case.setAlgorithmParameters( + Algorithm = 'MeasurementsOptimalPositioningTask', + Parameters = { + "Variant":"DEIM", + "SampleAsnUplet":Eq.get_sample_of_mu(15, 15), + "MaximumNumberOfLocations":50, + "ErrorNorm":"Linf", + "ErrorNormTolerance":0., + "StoreSupplementaryCalculations":[ + "SingularValues", + "OptimalPoints", + "EnsembleOfSimulations", + ], + } + ) +case.setBackground(Vector = [1,1] ) +case.setObservationOperator(OneFunction = Eq.OneRealisation) +case.execute() +# +print() +print("Graphical display of the results") +# +sp = case.get("EnsembleOfSimulations")[-1] +x1, x2 = Eq.get_x() +x1, x2 = np.meshgrid(x1, x2) +name = "Representation of a few snapshots of G out of a total of %i"%sp.shape[1] +print(" -", name) +fig, ax = plt.subplots(subplot_kw={"projection": "3d"}, figsize=(6, 6)) +fig.suptitle(name) +ax.set_xlabel("Position x1", fontweight='bold', color='red') +ax.set_ylabel("Position x2", fontweight='bold', color='red') +ax.set_zlabel("Magnitude of G", fontweight='bold', color='red') +for i in range(sp.shape[1]): + if i % 44 != 0: continue + ax.plot_surface(x1, x2, sp[:,i].reshape((dimension, dimension)), cmap='coolwarm') +fig.savefig("simple_MeasurementsOptimalPositioningTask31.png") +plt.close() +# +sv = case.get("SingularValues")[-1] +name = "Singular values of the set of G simulations" +print(" -", name) +fig, ax = plt.subplots(figsize=(6, 6)) +fig.suptitle(name) +ax.set_xlabel("Index of singular values, numbered from 1") +ax.set_ylabel("Magnitude of singular values") +ax.set_xlim(1, len(sv)) +ax.set_yscale("log") +ax.grid(True) +ax.plot(range(1, 1 + len(sv)), sv) +fig.savefig("simple_MeasurementsOptimalPositioningTask32.png") +plt.tight_layout() +plt.close() +# +nbmax = 15 +op = case.get("OptimalPoints")[-1] +posx1 = [x1.reshape((-1,))[ip] for ip in op[:nbmax]] +posx2 = [x2.reshape((-1,))[ip] for ip in op[:nbmax]] +name = "Set of %i first optimal points of measurement"%nbmax +Omega = Eq.get_bounds_on_space() +print(" -", name) +fig, ax = plt.subplots(figsize=(6, 6)) +fig.suptitle(name) +ax.set_xlabel("Position x1", fontweight='bold', color='red') +ax.set_ylabel("Position x2", fontweight='bold', color='red') +ax.set_xlim(Omega[0][0] - 0.05, Omega[0][1] + 0.05) +ax.set_ylim(Omega[1][0] - 0.05, Omega[1][1] + 0.05) +ax.grid(True, which='both', linestyle=(0, (1, 5)), linewidth=0.5) +ax.plot(posx1, posx2, markersize=6, marker="o", linestyle='') +for i in range(len(posx1)): + ax.text(posx1[i] + 0.005, posx2[i] + 0.01, str(i + 1), fontweight='bold') +fig.savefig("simple_MeasurementsOptimalPositioningTask33.png") +plt.tight_layout() +plt.close() diff --git a/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.res b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.res new file mode 100644 index 0000000..455a3d3 --- /dev/null +++ b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.res @@ -0,0 +1,8 @@ +Defining a set of artificial physical fields + +Search for optimal measurement positions + +Graphical display of the results + - Representation of a few snapshots of G out of a total of 225 + - Singular values of the set of G simulations + - Set of 15 first optimal points of measurement diff --git a/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.rst b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.rst new file mode 100644 index 0000000..9445285 --- /dev/null +++ b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask3.rst @@ -0,0 +1,30 @@ +.. index:: single: MeasurementsOptimalPositioningTask (example) + +Third example +............. + +This more complete example describes the optimal positioning of measurements +associated with a reduced DEIM-type decomposition on a classical parametric +non-linear function, as proposed in reference [Chaturantabut10]_. This +particular function has the notable advantage of being dependent only on a +position :math:`x` in 2D and a parameter :math:`\mu` in 2D too. It therefore +enables a pedagogical illustration of optimal measurement points. + +This function depends on the position :math:`x=(x_1,x_2)\in\Omega=[0.1,0.9]^2` +in the 2D plane, and on the parameter +:math:`\mu=(\mu_1,\mu_2)\in\mathcal{D}=[-1,-0.01]^2` of dimension 2 : + +.. math:: G(x;\mu) = \frac{1}{\sqrt{(x_1 - \mu_1)^2 + (x_2 - \mu_2)^2 + 0.1^2}} + +The function is represented on a regular :math:`\Omega_G` spatial grid of size +20x20 points. It is available in ADAO built-in test models under the name +`TwoDimensionalInverseDistanceCS2010`. So here we first build a set of +simulations of :math:`G`, then apply the DEIM-type decomposition algorithm to +it, and derive some simple illustrations. + +It can be seen that the singular values decrease steadily down to numerical +noise, indicating that around a hundred basis elements are needed to fully +represent the information contained in the set of :math:`G` simulations. +Furthermore, the optimal measurement points in the :math:`\Omega_G` domain are +inhomogeneously distributed, favoring the spatial zone near the +:math:`(0.1,0.1)` corner in which the :math:`G` function varies more. diff --git a/doc/en/scripts/simple_MeasurementsOptimalPositioningTask31.png b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask31.png new file mode 100644 index 0000000..128980d Binary files /dev/null and b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask31.png differ diff --git a/doc/en/scripts/simple_MeasurementsOptimalPositioningTask32.png b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask32.png new file mode 100644 index 0000000..8c78ab5 Binary files /dev/null and b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask32.png differ diff --git a/doc/en/scripts/simple_MeasurementsOptimalPositioningTask33.png b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask33.png new file mode 100644 index 0000000..e1aa57a Binary files /dev/null and b/doc/en/scripts/simple_MeasurementsOptimalPositioningTask33.png differ diff --git a/doc/fr/ref_algorithm_InterpolationByReducedModelTest.rst b/doc/fr/ref_algorithm_InterpolationByReducedModelTest.rst index 1b4831e..a0f4651 100644 --- a/doc/fr/ref_algorithm_InterpolationByReducedModelTest.rst +++ b/doc/fr/ref_algorithm_InterpolationByReducedModelTest.rst @@ -31,14 +31,15 @@ Algorithme de vérification "*InterpolationByReducedModelTest*" .. include:: snippets/Header2Algo01.rst Cet algorithme permet d'analyser de manière simple la qualité de -l'interpolation empirique des états obtenue par une base réduite, en utilisant -des mesures en des points précis. +l'interpolation empirique obtenue par une base réduite pour des états complets, +en utilisant des mesures en des points précis. Les résultats affichés par défaut sont des statistiques simples liées aux -erreurs normalisées de l'interpolation avec une base réduite. Le test utilise +erreurs normalisées entre l'interpolation avec une base réduite et les états +complets que l'on cherche à représenter sur la base réduite. Le test requiert une base réduite et un ensemble de positions de mesures optimales, et utilise des pseudo-mesures provenant de chaque état complet ("*snapshot*") inclus dans -l'ensemble de test donné. +l'ensemble donné de test. Attention : pour être cohérent, ce test doit utiliser la même norme mathématique que celle utilisée pour construire la base réduite. La norme étant diff --git a/doc/fr/ref_algorithm_MeasurementsOptimalPositioningTask.rst b/doc/fr/ref_algorithm_MeasurementsOptimalPositioningTask.rst index 26e45ee..a4adb23 100644 --- a/doc/fr/ref_algorithm_MeasurementsOptimalPositioningTask.rst +++ b/doc/fr/ref_algorithm_MeasurementsOptimalPositioningTask.rst @@ -223,6 +223,33 @@ StoreSupplementaryCalculations .. literalinclude:: scripts/simple_MeasurementsOptimalPositioningTask2.res :language: none +.. --------- .. +.. include:: scripts/simple_MeasurementsOptimalPositioningTask3.rst + +.. literalinclude:: scripts/simple_MeasurementsOptimalPositioningTask3.py + +.. include:: snippets/Header2Algo10.rst + +.. literalinclude:: scripts/simple_MeasurementsOptimalPositioningTask3.res + :language: none + +.. include:: snippets/Header2Algo11.rst + +.. _simple_MeasurementsOptimalPositioningTask31: +.. image:: scripts/simple_MeasurementsOptimalPositioningTask31.png + :align: center + :width: 60% + +.. _simple_MeasurementsOptimalPositioningTask32: +.. image:: scripts/simple_MeasurementsOptimalPositioningTask32.png + :align: center + :width: 60% + +.. _simple_MeasurementsOptimalPositioningTask33: +.. image:: scripts/simple_MeasurementsOptimalPositioningTask33.png + :align: center + :width: 60% + .. ------------------------------------ .. .. include:: snippets/Header2Algo06.rst diff --git a/doc/fr/ref_observations_requirements.rst b/doc/fr/ref_observations_requirements.rst index 327084e..dd04765 100644 --- a/doc/fr/ref_observations_requirements.rst +++ b/doc/fr/ref_observations_requirements.rst @@ -94,14 +94,15 @@ physiquement homogènes ou pas. - fichier texte de données (TXT, CSV, TSV, DAT), avec pointeur de variable par nom en colonne ou en ligne, indiqué par le mot-clé "*DataFile*" avec la condition ``Vector=True`` - fichier binaire de données (NPY, NPZ), avec pointeur de variable par nom, indiqué par le mot-clé "*DataFile*" avec la condition ``Vector=True`` -- Exemples de déclaration en interface TUI : +Exemples de déclaration en interface TUI : +:: - - ``case.setObservation( Vector = [1, 2, 3] )`` - - ``case.setObservation( Vector = numpy.array([1, 2, 3]) )`` - - ``case.setObservation( Vector = '1 2 3' )`` - - ``case.setObservation( Vector=True, Script = 'script.py' )``` - - ``case.setObservation( Vector=True, DataFile = 'data.csv' )``` - - ``case.setObservation( Vector=True, DataFile = 'data.npy' )``` + case.setObservation( Vector = [1, 2, 3] ) + case.setObservation( Vector = numpy.array([1, 2, 3]) ) + case.setObservation( Vector = '1 2 3' ) + case.setObservation( Vector=True, Script = 'script.py' ) + case.setObservation( Vector=True, DataFile = 'data.csv' ) + case.setObservation( Vector=True, DataFile = 'data.npy' ) Remarque d'utilisation : dans une étude donnée, seul le dernier enregistrement (que ce soit un vecteur unique ou une série de vecteurs) est utilisable, car un @@ -142,16 +143,17 @@ physiquement homogènes ou pas, dont on considère un historique. - fichier texte de données (TXT, CSV, TSV, DAT), avec pointeur de variable par nom en colonne ou en ligne, indiqué par le mot-clé "*DataFile*" avec la condition ``VectorSerie=True`` - fichier binaire de données (NPY, NPZ), avec pointeur de variable par nom, indiqué par le mot-clé "*DataFile*" avec la condition ``VectorSerie=True`` -- Exemples de déclaration en interface TUI : - - - ``case.setObservation( VectorSerie = [[1,2,3], [1,2,3]] )`` - - ``case.setObservation( VectorSerie = [numpy.array([1,2,3]), numpy.array([1,2,3])] )`` - - ``case.setObservation( VectorSerie = ['1 2 3', '1 2 3'] )`` - - ``case.setObservation( VectorSerie = '[[1,2,3], [1,2,3]]' )`` - - ``case.setObservation( VectorSerie = '1 2 3 ; 1 2 3' )`` - - ``case.setObservation( VectorSerie=True, Script = 'script.py' )``` - - ``case.setObservation( VectorSerie=True, DataFile = 'data.csv' )``` - - ``case.setObservation( VectorSerie=True, DataFile = 'data.npy' )``` +Exemples de déclaration en interface TUI : +:: + + case.setObservation( VectorSerie = [[1,2,3], [1,2,3]] ) + case.setObservation( VectorSerie = [numpy.array([1,2,3]), numpy.array([1,2,3])] ) + case.setObservation( VectorSerie = ['1 2 3', '1 2 3'] ) + case.setObservation( VectorSerie = '[[1,2,3], [1,2,3]]' ) + case.setObservation( VectorSerie = '1 2 3 ; 1 2 3' ) + case.setObservation( VectorSerie=True, Script = 'script.py' ) + case.setObservation( VectorSerie=True, DataFile = 'data.csv' ) + case.setObservation( VectorSerie=True, DataFile = 'data.npy' ) Remarque d'utilisation : dans une étude donnée, seul le dernier enregistrement (que ce soit un vecteur unique ou une série de vecteurs) est utilisable, car un diff --git a/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.py b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.py new file mode 100644 index 0000000..d9fca5a --- /dev/null +++ b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.py @@ -0,0 +1,90 @@ +# -*- coding: utf-8 -*- +# +import numpy as np +import matplotlib.pyplot as plt +np.random.seed(123456789) +# +dimension = 20 +# +print("Définition d'un ensemble artificiel de champs physiques") +from Models.TwoDimensionalInverseDistanceCS2010 \ + import TwoDimensionalInverseDistanceCS2010 as Equation +Eq = Equation(dimension, dimension) +print() +# +print("Recherche des positions optimales de mesure") +from adao import adaoBuilder +case = adaoBuilder.New() +case.setAlgorithmParameters( + Algorithm = 'MeasurementsOptimalPositioningTask', + Parameters = { + "Variant":"DEIM", + "SampleAsnUplet":Eq.get_sample_of_mu(15, 15), + "MaximumNumberOfLocations":50, + "ErrorNorm":"Linf", + "ErrorNormTolerance":0., + "StoreSupplementaryCalculations":[ + "SingularValues", + "OptimalPoints", + "EnsembleOfSimulations", + ], + } + ) +case.setBackground(Vector = [1,1] ) +case.setObservationOperator(OneFunction = Eq.OneRealisation) +case.execute() +# +print() +print("Affichage graphique des résultats") +# +sp = case.get("EnsembleOfSimulations")[-1] +x1, x2 = Eq.get_x() +x1, x2 = np.meshgrid(x1, x2) +name = "Représentation de quelques snapshots de G sur un total de %i"%sp.shape[1] +print(" -", name) +fig, ax = plt.subplots(subplot_kw={"projection": "3d"}, figsize=(6, 6)) +fig.suptitle(name) +ax.set_xlabel("Position x1", fontweight='bold', color='red') +ax.set_ylabel("Position x2", fontweight='bold', color='red') +ax.set_zlabel("Amplitude de G", fontweight='bold', color='red') +for i in range(sp.shape[1]): + if i % 44 != 0: continue + ax.plot_surface(x1, x2, sp[:,i].reshape((dimension, dimension)), cmap='coolwarm') +fig.savefig("simple_MeasurementsOptimalPositioningTask31.png") +plt.close() +# +sv = case.get("SingularValues")[-1] +name = "Valeurs singulières de l'ensemble des simulations de G" +print(" -", name) +fig, ax = plt.subplots(figsize=(6, 6)) +fig.suptitle(name) +ax.set_xlabel("Index des valeurs singulières, numérotées à partir de 1") +ax.set_ylabel("Amplitude des valeurs singulières") +ax.set_xlim(1, len(sv)) +ax.set_yscale("log") +ax.grid(True) +ax.plot(range(1, 1 + len(sv)), sv) +fig.savefig("simple_MeasurementsOptimalPositioningTask32.png") +plt.tight_layout() +plt.close() +# +nbmax = 15 +op = case.get("OptimalPoints")[-1] +posx1 = [x1.reshape((-1,))[ip] for ip in op[:nbmax]] +posx2 = [x2.reshape((-1,))[ip] for ip in op[:nbmax]] +name = "Ensemble des %i premiers points optimaux de mesure"%nbmax +Omega = Eq.get_bounds_on_space() +print(" -", name) +fig, ax = plt.subplots(figsize=(6, 6)) +fig.suptitle(name) +ax.set_xlabel("Position x1", fontweight='bold', color='red') +ax.set_ylabel("Position x2", fontweight='bold', color='red') +ax.set_xlim(Omega[0][0] - 0.05, Omega[0][1] + 0.05) +ax.set_ylim(Omega[1][0] - 0.05, Omega[1][1] + 0.05) +ax.grid(True, which='both', linestyle=(0, (1, 5)), linewidth=0.5) +ax.plot(posx1, posx2, markersize=6, marker="o", linestyle='') +for i in range(len(posx1)): + ax.text(posx1[i] + 0.005, posx2[i] + 0.01, str(i + 1), fontweight='bold') +fig.savefig("simple_MeasurementsOptimalPositioningTask33.png") +plt.tight_layout() +plt.close() diff --git a/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.res b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.res new file mode 100644 index 0000000..756b5bf --- /dev/null +++ b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.res @@ -0,0 +1,8 @@ +Définition d'un ensemble artificiel de champs physiques + +Recherche des positions optimales de mesure + +Affichage graphique des résultats + - Représentation de quelques snapshots de G sur un total de 225 + - Valeurs singulières de l'ensemble des simulations de G + - Ensemble des 15 premiers points optimaux de mesure diff --git a/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.rst b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.rst new file mode 100644 index 0000000..8225906 --- /dev/null +++ b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask3.rst @@ -0,0 +1,33 @@ +.. index:: single: MeasurementsOptimalPositioningTask (exemple) + +Troisième exemple +................. + +Cet exemple plus complet décrit le positionnement optimal de mesures associé à +une décomposition réduite de type DEIM sur une fonction classique paramétrique +non-linéaire, telle que proposée dans la référence [Chaturantabut10]_. Cette +fonction particulière a l'avantage notable de n'être dépendante que d'une +position :math:`x` en 2D et d'un paramètre :math:`\mu` en 2D aussi. Elle permet +donc une illustration pédagogique pour représenter les points optimaux de +mesure. + +Cette fonction dépend de la position :math:`x=(x_1,x_2)\in\Omega=[0.1,0.9]^2` +dans le plan 2D, et du paramètre +:math:`\mu=(\mu_1,\mu_2)\in\mathcal{D}=[-1,-0.01]^2` de dimension 2 : + +.. math:: G(x;\mu) = \frac{1}{\sqrt{(x_1 - \mu_1)^2 + (x_2 - \mu_2)^2 + 0.1^2}} + +La fonction est représenté sur une grille spatiale régulière :math:`\Omega_G` +de taille 20x20 points. Elle est disponible dans les modèles de tests intégrés +pour ADAO sous le nom `TwoDimensionalInverseDistanceCS2010`. On construit donc +ici tout d'abord un ensemble de simulations de :math:`G`, pour lui appliquer +ensuite l'algorithme de décomposition de type DEIM, et en tirer des +illustrations simples. + +On observe ainsi que les valeurs singulières décroissent régulièrement jusqu'au +bruit numérique, indiquant qu'il faut environ une centaine d'éléments de base +pour complètement représenter l'information contenue dans l'ensemble des +simulations de :math:`G`. Par ailleurs, les points de mesure optimaux dans le +domaine :math:`\Omega_G` sont répartis de manière inhomogène, privilégiant la +zone spatiale proche du coin :math:`(0.1,0.1)` dans laquelle la fonction +:math:`G` varie plus. diff --git a/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask31.png b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask31.png new file mode 100644 index 0000000..4e21179 Binary files /dev/null and b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask31.png differ diff --git a/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask32.png b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask32.png new file mode 100644 index 0000000..a84b5bd Binary files /dev/null and b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask32.png differ diff --git a/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask33.png b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask33.png new file mode 100644 index 0000000..296b6ea Binary files /dev/null and b/doc/fr/scripts/simple_MeasurementsOptimalPositioningTask33.png differ diff --git a/src/daComposant/daNumerics/Models/TwoDimensionalInverseDistanceCS2010.py b/src/daComposant/daNumerics/Models/TwoDimensionalInverseDistanceCS2010.py new file mode 100644 index 0000000..6df69eb --- /dev/null +++ b/src/daComposant/daNumerics/Models/TwoDimensionalInverseDistanceCS2010.py @@ -0,0 +1,102 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2008-2024 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D + +import sys, unittest, numpy + +# ============================================================================== +class TwoDimensionalInverseDistanceCS2010: + """ + Two-dimensional inverse distance function of parameter µ=(µ1,µ2): + + s(x,y,µ) = 1 / sqrt( (x-µ1)² + (y-µ2)² + 0.1² ) + + avec (x,y) ∈ [0.1,0.9]² et µ=(µ1,µ2) ∈ [-1,-0.01]². + + This is the non-linear parametric function (3.38) of the reference: + Chaturantabut, S., Sorensen, D. C., + Nonlinear Model Reduction via Discrete Empirical Interpolation, + SIAM Journal on Scientific Computing, 32(5), pp. 2737-2764 (2010). + """ + def __init__(self, nx: int = 20, ny: int = 20): + self.nx = max(1, nx) + self.ny = max(1, ny) + self.x = numpy.linspace(0.1, 0.9, self.nx, dtype=float) + self.y = numpy.linspace(0.1, 0.9, self.ny, dtype=float) + + def FunctionH(self, XX ): + __mu1, __mu2 = numpy.ravel(XX) + # + __x, __y = numpy.meshgrid( self.x, self.y ) + __sxymu = 1. / numpy.sqrt( (__x - __mu1)**2 + (__y - __mu2)**2 + 0.1**2 ) + # + return __sxymu + + def get_x(self): + return self.x, self.y + + def get_sample_of_mu(self, ns1: int = 20, ns2: int = 20): + smu1 = numpy.linspace(-1, -0.01, ns1, dtype=float) + smu2 = numpy.linspace(-1, -0.01, ns2, dtype=float) + smu = numpy.array([(mu1, mu2) for mu1 in smu1 for mu2 in smu2]) + return smu + + def get_random_sample_of_mu(self, ns1: int = 1, ns2: int = 1): + smu = [] + for i in range(ns1 * ns2): + smu1 = numpy.random.uniform(-1, -0.01) + smu2 = numpy.random.uniform(-1, -0.01) + smu.append((smu1, smu2)) + smu = numpy.array(smu) + return smu + + def get_bounds_on_space(self): + return [[min(self.x), max(self.x)], [min(self.y), max(self.y)]] + + def get_bounds_on_parameter(self): + return [[-1, -0.01]] * 2 + + OneRealisation = FunctionH + +# ============================================================================== +class LocalTest(unittest.TestCase): + @classmethod + def setUpClass(cls): + print('\nAUTODIAGNOSTIC\n==============\n') + print(" " + TwoDimensionalInverseDistanceCS2010().__doc__.strip()) + + def test001(self): + numpy.random.seed(123456789) + Equation = TwoDimensionalInverseDistanceCS2010() + for mu in Equation.get_sample_of_mu(5, 5): + solution = Equation.OneRealisation( mu ) + # Nappe maximale au coin (0,0) + self.assertTrue(numpy.max(solution.flat) <= solution[0, 0]) + # Nappe minimale au coin [-1,-1] + self.assertTrue(numpy.min(solution.flat) >= solution[-1, -1]) + + def tearDown(cls): + print("\n Tests OK\n") + +# ============================================================================== +if __name__ == "__main__": + sys.stderr = sys.stdout + unittest.main(verbosity=0) diff --git a/src/daComposant/daNumerics/Models/__init__.py b/src/daComposant/daNumerics/Models/__init__.py new file mode 100644 index 0000000..a32af42 --- /dev/null +++ b/src/daComposant/daNumerics/Models/__init__.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +# +# Copyright (C) 2008-2024 EDF R&D +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# +# Author: Jean-Philippe Argaud, jean-philippe.argaud@edf.fr, EDF R&D