From c86b5f8e734ee3acfa8ee9b53d6c52bdca6632a5 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Fri, 29 Nov 2024 15:52:41 +0100 Subject: [PATCH 1/8] fixed: fix check_jacobian bug when giving input_data and input_names as arguments --- changelog/fragments/1369.fixed.rst | 1 + src/gemseo/utils/derivatives/derivatives_approx.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 changelog/fragments/1369.fixed.rst diff --git a/changelog/fragments/1369.fixed.rst b/changelog/fragments/1369.fixed.rst new file mode 100644 index 0000000000..f24fa1c9c0 --- /dev/null +++ b/changelog/fragments/1369.fixed.rst @@ -0,0 +1 @@ +- ``Discipline.check_jacobian`` uses input data for the approximate Jacobian when given input_data and input_names as arguments. diff --git a/src/gemseo/utils/derivatives/derivatives_approx.py b/src/gemseo/utils/derivatives/derivatives_approx.py index 1d89bc66b0..8f146e1722 100644 --- a/src/gemseo/utils/derivatives/derivatives_approx.py +++ b/src/gemseo/utils/derivatives/derivatives_approx.py @@ -144,7 +144,11 @@ class DisciplineJacApprox: Raises: ValueError: If the Jacobian approximation method is unknown. """ - self.func = self.generator.get_function(input_names, output_names) + self.func = self.generator.get_function( + input_names, + output_names, + self.discipline.io.get_input_data(with_namespaces=False), + ) self.approximator = GradientApproximatorFactory().create( self.approx_method, self.func.evaluate, -- GitLab From d944f9c32a7bd3919df7732efa20cdf280084d15 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Fri, 29 Nov 2024 16:04:25 +0100 Subject: [PATCH 2/8] Added test for check_jacobian when giving input_data and input_names as arguments --- tests/core/test_discipline.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/tests/core/test_discipline.py b/tests/core/test_discipline.py index 3fb3f87dab..f0e7a54214 100644 --- a/tests/core/test_discipline.py +++ b/tests/core/test_discipline.py @@ -38,6 +38,7 @@ from numpy import ndarray from numpy import ones from numpy.linalg import norm +from gemseo import create_discipline from gemseo.caches.hdf5_cache import HDF5Cache from gemseo.caches.simple_cache import SimpleCache from gemseo.core.chains.chain import MDOChain @@ -51,6 +52,9 @@ from gemseo.disciplines.analytic import AnalyticDiscipline from gemseo.disciplines.auto_py import AutoPyDiscipline from gemseo.mda.base_mda import BaseMDA from gemseo.problems.mdo.sellar.sellar_1 import Sellar1 +from gemseo.problems.mdo.sellar.variables import X_1 +from gemseo.problems.mdo.sellar.variables import X_SHARED +from gemseo.problems.mdo.sellar.variables import Y_2 from gemseo.problems.mdo.sobieski._disciplines_sg import SobieskiStructureSG from gemseo.problems.mdo.sobieski.core.problem import SobieskiProblem from gemseo.problems.mdo.sobieski.disciplines import SobieskiAerodynamics @@ -482,6 +486,19 @@ def test_check_jacobian_2() -> None: disc.linearize({"x": x}, compute_all_jacobians=True) +def test_check_jacobian_input_data() -> None: + sellar_1 = create_discipline("Sellar1") + input_data = { + X_1: array([3.0]), + X_SHARED: array([3.0, 3.0]), + Y_2: array([3.0]), + } + sellar_1.check_jacobian( + input_data=input_data, + input_names=[Y_2], + ) + + def test_check_jacobian_parallel_fd() -> None: """Test check_jacobian in parallel.""" sm = SobieskiMission() -- GitLab From d0508e0839edbba9ad6befbcadcec4fbdcddf324 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Tue, 3 Dec 2024 17:10:08 +0100 Subject: [PATCH 3/8] fixed: fixed bug introduced with previous changes --- src/gemseo/core/discipline/discipline.py | 1 + .../utils/derivatives/derivatives_approx.py | 20 ++++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/gemseo/core/discipline/discipline.py b/src/gemseo/core/discipline/discipline.py index 7e78b02655..b666ffc8bb 100644 --- a/src/gemseo/core/discipline/discipline.py +++ b/src/gemseo/core/discipline/discipline.py @@ -667,6 +667,7 @@ class Discipline(BaseDiscipline, metaclass=ClassInjector): reference_jacobian_path=reference_jacobian_path, save_reference_jacobian=save_reference_jacobian, indices=indices, + input_data=input_data, ) def _get_differentiated_io( diff --git a/src/gemseo/utils/derivatives/derivatives_approx.py b/src/gemseo/utils/derivatives/derivatives_approx.py index 8f146e1722..f4ea8d04ac 100644 --- a/src/gemseo/utils/derivatives/derivatives_approx.py +++ b/src/gemseo/utils/derivatives/derivatives_approx.py @@ -134,12 +134,15 @@ class DisciplineJacApprox: self, output_names: Sequence[str], input_names: Sequence[str], + input_data: Mapping[str, ndarray] = READ_ONLY_EMPTY_DICT, ) -> None: """Create the Jacobian approximation class. Args: input_names: The names of the inputs used to differentiate the outputs. output_names: The names of the outputs to be differentiated. + input_data: the default values of the input variables for the Jacobian + approximation. Raises: ValueError: If the Jacobian approximation method is unknown. @@ -147,7 +150,7 @@ class DisciplineJacApprox: self.func = self.generator.get_function( input_names, output_names, - self.discipline.io.get_input_data(with_namespaces=False), + input_data or None, ) self.approximator = GradientApproximatorFactory().create( self.approx_method, @@ -264,6 +267,7 @@ class DisciplineJacApprox: output_names: Iterable[str], input_names: Iterable[str], x_indices: Sequence[int] = (), + input_data: Mapping[str, ndarray] = READ_ONLY_EMPTY_DICT, ) -> dict[str, dict[str, ndarray]]: """Approximate the Jacobian. @@ -273,11 +277,14 @@ class DisciplineJacApprox: x_indices: The components of the input vector to be used for the differentiation. If empty, use all the components. + input_data: The input data needed to approximate the Jacobian + according to the discipline input grammar. + If ``None``, use the :attr:`.Discipline.default_input_data`. Returns: The approximated Jacobian. """ - self._create_approximator(output_names, input_names) + self._create_approximator(output_names, input_names, input_data) if self.auto_steps and all(key in self.auto_steps for key in input_names): step = ( @@ -344,6 +351,7 @@ class DisciplineJacApprox: indices: Mapping[ str, int | Sequence[int] | Ellipsis | slice ] = READ_ONLY_EMPTY_DICT, + input_data: Mapping[str, ndarray] = READ_ONLY_EMPTY_DICT, ) -> bool: """Check if the analytical Jacobian is correct with respect to a reference one. @@ -385,6 +393,9 @@ class DisciplineJacApprox: If a variable name is missing, consider all its components. If ``None``, consider all the components of all the ``inputs`` and ``outputs``. + input_data: The input data needed to execute the discipline + according to the discipline input grammar. + If ``None``, use the :attr:`.Discipline.default_input_data`. Returns: Whether the analytical Jacobian is correct. @@ -408,8 +419,11 @@ class DisciplineJacApprox: analytic_jacobian = analytic_jacobian or self.discipline.jac if not reference_jacobian_path or save_reference_jacobian: + for input_name in list(input_data): + if input_name not in self.discipline.input_grammar.names: + del input_data[input_name] approximated_jacobian = self.compute_approx_jac( - output_names, input_names, input_indices + output_names, input_names, input_indices, input_data ) else: with Path(reference_jacobian_path).open("rb") as infile: -- GitLab From e68f548335e7af8a4298c3129f9e78b0d8fe0381 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Fri, 6 Dec 2024 13:12:56 +0000 Subject: [PATCH 4/8] corrections --- src/gemseo/utils/derivatives/derivatives_approx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gemseo/utils/derivatives/derivatives_approx.py b/src/gemseo/utils/derivatives/derivatives_approx.py index f4ea8d04ac..f5ab00d241 100644 --- a/src/gemseo/utils/derivatives/derivatives_approx.py +++ b/src/gemseo/utils/derivatives/derivatives_approx.py @@ -419,7 +419,7 @@ class DisciplineJacApprox: analytic_jacobian = analytic_jacobian or self.discipline.jac if not reference_jacobian_path or save_reference_jacobian: - for input_name in list(input_data): + for input_name in input_data: if input_name not in self.discipline.input_grammar.names: del input_data[input_name] approximated_jacobian = self.compute_approx_jac( -- GitLab From 8f30f3aee3dfc91e25786ceda362f6ff23f214ef Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Fri, 6 Dec 2024 14:37:27 +0100 Subject: [PATCH 5/8] Revert "corrections" This reverts commit d1c3541ce3cbff73a754b160b59720d4e26dfe31. --- src/gemseo/utils/derivatives/derivatives_approx.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gemseo/utils/derivatives/derivatives_approx.py b/src/gemseo/utils/derivatives/derivatives_approx.py index f5ab00d241..f4ea8d04ac 100644 --- a/src/gemseo/utils/derivatives/derivatives_approx.py +++ b/src/gemseo/utils/derivatives/derivatives_approx.py @@ -419,7 +419,7 @@ class DisciplineJacApprox: analytic_jacobian = analytic_jacobian or self.discipline.jac if not reference_jacobian_path or save_reference_jacobian: - for input_name in input_data: + for input_name in list(input_data): if input_name not in self.discipline.input_grammar.names: del input_data[input_name] approximated_jacobian = self.compute_approx_jac( -- GitLab From 27e9ae4a64fdd4106d24435ff2b381418d010f70 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Thu, 12 Dec 2024 06:50:25 +0000 Subject: [PATCH 6/8] description suggestion --- src/gemseo/utils/derivatives/derivatives_approx.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gemseo/utils/derivatives/derivatives_approx.py b/src/gemseo/utils/derivatives/derivatives_approx.py index f4ea8d04ac..ac27b6b017 100644 --- a/src/gemseo/utils/derivatives/derivatives_approx.py +++ b/src/gemseo/utils/derivatives/derivatives_approx.py @@ -141,8 +141,7 @@ class DisciplineJacApprox: Args: input_names: The names of the inputs used to differentiate the outputs. output_names: The names of the outputs to be differentiated. - input_data: the default values of the input variables for the Jacobian - approximation. + input_data: The input data for the Jacobian approximation. Raises: ValueError: If the Jacobian approximation method is unknown. -- GitLab From 762945b19a33e567b8aca20ea0d341fc2e69f639 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Fri, 13 Dec 2024 15:57:52 +0000 Subject: [PATCH 7/8] fragment corrections --- changelog/fragments/1369.fixed.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/fragments/1369.fixed.rst b/changelog/fragments/1369.fixed.rst index f24fa1c9c0..d6927ed072 100644 --- a/changelog/fragments/1369.fixed.rst +++ b/changelog/fragments/1369.fixed.rst @@ -1 +1 @@ -- ``Discipline.check_jacobian`` uses input data for the approximate Jacobian when given input_data and input_names as arguments. +- ``Discipline.check_jacobian`` now correctly uses the ``input_data`` argument for the approximate Jacobian when provided. -- GitLab From e3df25fbd738b630d3775c0d9f79309ed5a1e3d3 Mon Sep 17 00:00:00 2001 From: Fabian Castaneda Date: Wed, 8 Jan 2025 14:18:49 +0100 Subject: [PATCH 8/8] minor changes --- src/gemseo/utils/derivatives/derivatives_approx.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gemseo/utils/derivatives/derivatives_approx.py b/src/gemseo/utils/derivatives/derivatives_approx.py index ac27b6b017..560113374a 100644 --- a/src/gemseo/utils/derivatives/derivatives_approx.py +++ b/src/gemseo/utils/derivatives/derivatives_approx.py @@ -278,7 +278,7 @@ class DisciplineJacApprox: If empty, use all the components. input_data: The input data needed to approximate the Jacobian according to the discipline input grammar. - If ``None``, use the :attr:`.Discipline.default_input_data`. + If empty, use the :attr:`.Discipline.default_input_data`. Returns: The approximated Jacobian. @@ -394,7 +394,7 @@ class DisciplineJacApprox: consider all the components of all the ``inputs`` and ``outputs``. input_data: The input data needed to execute the discipline according to the discipline input grammar. - If ``None``, use the :attr:`.Discipline.default_input_data`. + If empty, use the :attr:`.Discipline.default_input_data`. Returns: Whether the analytical Jacobian is correct. @@ -418,7 +418,7 @@ class DisciplineJacApprox: analytic_jacobian = analytic_jacobian or self.discipline.jac if not reference_jacobian_path or save_reference_jacobian: - for input_name in list(input_data): + for input_name in tuple(input_data): if input_name not in self.discipline.input_grammar.names: del input_data[input_name] approximated_jacobian = self.compute_approx_jac( -- GitLab