From 5ed1110d25d3046c02ee540d573684e9d7ac9b22 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sun, 4 Aug 2024 11:08:06 +0530 Subject: [PATCH 1/9] initial --- ...linearly_interpolated_projection_utils.cpp | 0 .../linearly_interpolated_projection_utils.h | 70 +++++++ .../controls/material/simp_control.py | 85 ++++---- .../thickness/shell_thickness_control.py | 1 + .../utilities/opt_projection.py | 186 ++++++++++++++++++ 5 files changed, 308 insertions(+), 34 deletions(-) create mode 100644 applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.cpp create mode 100644 applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h create mode 100644 applications/OptimizationApplication/python_scripts/utilities/opt_projection.py diff --git a/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.cpp b/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.cpp new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h b/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h new file mode 100644 index 000000000000..4e47fb0c3d9c --- /dev/null +++ b/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h @@ -0,0 +1,70 @@ +// | / | +// ' / __| _` | __| _ \ __| +// . \ | ( | | ( |\__ ` +// _|\_\_| \__,_|\__|\___/ ____/ +// Multi-Physics +// +// License: BSD License +// license: OptimizationApplication/license.txt +// +// Main author: Suneth Warnakulasuriya +// + +#pragma once + +// System includes +#include + +// Project includes +#include "includes/define.h" +#include "expression/container_expression.h" + +// Application includes + +namespace Kratos +{ + +///@name Kratos Classes +///@{ + +class KRATOS_API(OPTIMIZATION_APPLICATION) LinearlyInterpolatedProjectionUtils +{ +public: + ///@name Type definitions + ///@{ + + using IndexType = std::size_t; + + ///@} + ///@name Static operations + ///@{ + + template + static ContainerExpression ProjectForward( + const ContainerExpression& rInputExpression, + const std::vector& rXValues, + const std::vector& rYValues, + const double Beta, + const int PenaltyFactor); + + template + static ContainerExpression ProjectBackward( + const ContainerExpression& rInputExpression, + const std::vector& rXValues, + const std::vector& rYValues, + const double Beta, + const int PenaltyFactor); + + template + static ContainerExpression CalculateForwardProjectionGradient( + const ContainerExpression& rInputExpression, + const std::vector& rXValues, + const std::vector& rYValues, + const double Beta, + const int PenaltyFactor); + + ///@} +}; + +///@} +} \ No newline at end of file diff --git a/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py b/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py index 933ba8bcafbe..9a3edb90be57 100644 --- a/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py +++ b/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py @@ -9,6 +9,7 @@ from KratosMultiphysics.OptimizationApplication.utilities.helper_utilities import IsSameContainerExpression from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView from KratosMultiphysics.OptimizationApplication.filtering.filter import Factory as FilterFactory +from KratosMultiphysics.OptimizationApplication.utilities.opt_projection import CreateProjection def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> Control: if not parameters.Has("name"): @@ -65,7 +66,6 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters default_settings = Kratos.Parameters("""{ "controlled_model_part_names": [""], - "simp_power_fac" : 3, "output_all_fields": true, "echo_level" : 0, "list_of_materials": [ @@ -74,16 +74,27 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters "young_modulus": 1.0 } ], - "beta_settings": { - "initial_value": 5, - "max_value" : 30, - "adaptive" : true, - "increase_fac" : 1.05, - "update_period": 50 + "density_projection_settings": { + "type" : "adaptive_sigmoidal_projection", + "initial_value" : 5, + "max_value" : 30, + "increase_fac" : 1.05, + "update_period" : 50, + "penalty_factor": 1 + }, + "young_modulus_projection_settings": { + "type" : "adaptive_sigmoidal_projection", + "initial_value" : 5, + "max_value" : 30, + "increase_fac" : 1.05, + "update_period" : 50, + "penalty_factor": 3 }, "filter_settings" : {} }""") + parameters.ValidateAndAssignDefaults(default_settings) + self.simp_power_fac = parameters["simp_power_fac"].GetInt() self.output_all_fields = parameters["output_all_fields"].GetBool() self.echo_level = parameters["echo_level"].GetInt() @@ -92,15 +103,11 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters self.materials = Materials(parameters["list_of_materials"].values()) - # beta settings - beta_settings = parameters["beta_settings"] - beta_settings.ValidateAndAssignDefaults(default_settings["beta_settings"]) - self.beta = beta_settings["initial_value"].GetDouble() - self.beta_max = beta_settings["max_value"].GetDouble() - self.beta_adaptive = beta_settings["adaptive"].GetBool() - self.beta_increase_frac = beta_settings["increase_fac"].GetDouble() - self.beta_update_period = beta_settings["update_period"].GetInt() - self.beta_computed_step = 1 + parameters["density_projection_settings"].ValidateAndAssignDefaults(default_settings["density_projection_settings"]) + self.density_projection = CreateProjection(parameters["density_projection_settings"], self.optimization_problem) + + parameters["young_modulus_projection_settings"].ValidateAndAssignDefaults(default_settings["young_modulus_projection_settings"]) + self.young_modulus_projection = CreateProjection(parameters["young_modulus_projection_settings"], self.optimization_problem) controlled_model_names_parts = parameters["controlled_model_part_names"].GetStringArray() if len(controlled_model_names_parts) == 0: @@ -125,10 +132,28 @@ def Initialize(self) -> None: self.filter.SetComponentDataView(ComponentDataView(self, self.optimization_problem)) self.filter.Initialize() - # calculate phi from existing density - density = Kratos.Expression.ElementExpression(self.model_part) - KratosOA.PropertiesVariableExpressionIO.Read(density, Kratos.DENSITY) - self.simp_physical_phi = KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectBackward(density, self.materials.GetPhi(), self.materials.GetDensities(), self.beta, 1) + # initialize the projections + self.density_projection.SetProjectionSpaces(self.materials.GetPhi(), self.materials.GetDensities()) + self.young_modulus_projection.SetProjectionSpaces(self.materials.GetPhi(), self.materials.GetYoungModulus()) + + # check if the density or Young's modulus is defined + element: Kratos.Element + for element in self.model_part.Elements: + break + is_density_defined = element.Properties.Has(Kratos.DENSITY) + is_youngs_modulus_defined = element.Properties.Has(Kratos.YOUNG_MODULUS) + if is_density_defined: + if is_youngs_modulus_defined: + Kratos.Logger.PrintWarning(self.__class__.__name__, f"Elements of {self.model_part.FullName()} defines both DENSITY and YOUNG_MODULUS. Using DENSITY for initial field calculation and ignoring YOUNG_MODULUS.") + density = Kratos.Expression.ElementExpression(self.model_part) + KratosOA.PropertiesVariableExpressionIO.Read(density, Kratos.DENSITY) + self.simp_physical_phi = self.density_projection.ProjectBackward(density) + elif is_youngs_modulus_defined: + young_modulus = Kratos.Expression.ElementExpression(self.model_part) + KratosOA.PropertiesVariableExpressionIO.Read(young_modulus, Kratos.YOUNG_MODULUS) + self.simp_physical_phi = self.young_modulus_projection.ProjectBackward(young_modulus) + else: + raise RuntimeError(f"Elements of {self.model_part.FullName()} does not define either DENSITY or YOUNG_MODULUS.") # get the control field self.control_phi = self.filter.UnfilterField(self.simp_physical_phi) @@ -180,35 +205,27 @@ def Update(self, control_field: ContainerExpressionTypes) -> bool: self._UpdateAndOutputFields(update) self.filter.Update() - self.__UpdateBeta() - - def __UpdateBeta(self) -> None: - if self.beta_adaptive: - step = self.optimization_problem.GetStep() - if step % self.beta_update_period == 0 and self.beta_computed_step != step: - self.beta_computed_step = step - self.beta = min(self.beta * self.beta_increase_frac, self.beta_max) - if self.echo_level > 0: - Kratos.Logger.PrintInfo(f"::{self.GetName()}::", f"Increased beta to {self.beta}.") + self.density_projection.Update() + self.young_modulus_projection.Update() def _UpdateAndOutputFields(self, update: ContainerExpressionTypes) -> None: # filter the control field physical_phi_update = self.filter.ForwardFilterField(update) self.simp_physical_phi = Kratos.Expression.Utils.Collapse(self.simp_physical_phi + physical_phi_update) - density = KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectForward(self.simp_physical_phi, self.materials.GetPhi(), self.materials.GetDensities(), self.beta, 1) + density = self.density_projection.ProjectForward(self.simp_physical_phi) KratosOA.PropertiesVariableExpressionIO.Write(density, Kratos.DENSITY) self.un_buffered_data.SetValue("DENSITY", density.Clone(), overwrite=True) - youngs_modulus = KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectForward(self.simp_physical_phi, self.materials.GetPhi(), self.materials.GetYoungModulus(), self.beta, self.simp_power_fac) + youngs_modulus = self.young_modulus_projection.ProjectForward(self.simp_physical_phi) KratosOA.PropertiesVariableExpressionIO.Write(youngs_modulus, Kratos.YOUNG_MODULUS) self.un_buffered_data.SetValue("YOUNG_MODULUS", youngs_modulus.Clone(), overwrite=True) # now calculate the total sensitivities of density w.r.t. phi - self.d_density_d_phi = KratosOA.ControlUtils.SigmoidalProjectionUtils.CalculateForwardProjectionGradient(self.simp_physical_phi, self.materials.GetPhi(), self.materials.GetDensities(), self.beta, 1) + self.d_density_d_phi = self.density_projection.ForwardProjectionGradient(self.simp_physical_phi) # now calculate the total sensitivities of young modulus w.r.t. simp_physical_phi - self.d_young_modulus_d_phi = KratosOA.ControlUtils.SigmoidalProjectionUtils.CalculateForwardProjectionGradient(self.simp_physical_phi, self.materials.GetPhi(), self.materials.GetYoungModulus(), self.beta, self.simp_power_fac) + self.d_young_modulus_d_phi = self.young_modulus_projection.ForwardProjectionGradient(self.simp_physical_phi) # now output the fields un_buffered_data = ComponentDataView(self, self.optimization_problem).GetUnBufferedData() diff --git a/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py b/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py index 01b679dd68d6..1fd6382aa078 100644 --- a/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py +++ b/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py @@ -11,6 +11,7 @@ from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem from KratosMultiphysics.OptimizationApplication.filtering.filter import Factory as FilterFactory +from KratosMultiphysics.OptimizationApplication.utilities.opt_projection import CreateProjection def Factory(model: Kratos.Model, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> Control: if not parameters.Has("name"): diff --git a/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py b/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py new file mode 100644 index 000000000000..861d9fa239c0 --- /dev/null +++ b/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py @@ -0,0 +1,186 @@ +from typing import Optional +from abc import ABC, abstractmethod + +import KratosMultiphysics as Kratos +import KratosMultiphysics.OptimizationApplication as KratosOA +from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem +from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import ContainerExpressionTypes + +class Projection(ABC): + """Projection methods to convert given x space values to given y space values + + This is the interface class which can be used to implement projection classes + which project forward and backward given x space values to y space. + + The projection spaces should be scalar spaces. + """ + + @abstractmethod + def SetProjectionSpaces(self, x_space_values: 'list[float]', y_space_values: 'list[float]') -> None: + """Space values in x space and y space + + Args: + x_space_values (list[float]): List of values to be used in x space + y_space_values (list[float]): List of values to be used in y space + """ + pass + + @abstractmethod + def ProjectForward(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + """Project x space values to y space + + Args: + x_values (ContainerExpressionTypes): x space values. + + Returns: + ContainerExpressionTypes: y space values. + """ + pass + + @abstractmethod + def ProjectBackward(self, y_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + """Project y space values to x space values + + Args: + y_values (ContainerExpressionTypes): y space values. + + Returns: + ContainerExpressionTypes: x space values. + """ + pass + + @abstractmethod + def ForwardProjectionGradient(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + """Computes the forward projected y space values' gradient w.r.t x space. + + Args: + x_values (ContainerExpressionTypes): x space values. + + Returns: + ContainerExpressionTypes: gradient of the y space values w.r.t. x space. + """ + pass + + @abstractmethod + def Update(self) -> None: + """Updates the projection method + """ + +class LinearlyInterpolatedProjection(Projection): + def __init__(self, parameters: Kratos.Parameters, _): + default_settings = Kratos.Parameters("""{ + "type" : "linearly_interpolated_projection", + "extrapolate": "false" + }""") + parameters.ValidateAndAssignDefaults(default_settings) + pass + + def SetProjectionSpaces(self, x_space_values: list[float], y_space_values: list[float]) -> None: + pass + + def ProjectForward(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return x_values.Clone() + + def ProjectBackward(self, y_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return y_values.Clone() + + def ForwardProjectionGradient(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + result = x_values.Clone() + Kratos.Expression.LiteralExpressionIO.SetData(result, 1.0) + return result + + def Update(self) -> None: + pass + +class SigmoidalProjection(Projection): + def __init__(self, parameters: Kratos.Parameters, _): + default_parameters = Kratos.Parameters("""{ + "type" : "sigmoidal_projection", + "beta_value" : 5, + "penalty_factor": 1 + }""") + + parameters.ValidateAndAssignDefaults(default_parameters) + self.beta = parameters["beta_value"].GetDouble() + self.penalty_factor = parameters["penalty_factor"].GetInt() + + self.x_space_values: 'Optional[list[float]]' = None + self.y_space_values: 'Optional[list[float]]' = None + + def SetProjectionSpaces(self, x_space_values: list[float], y_space_values: list[float]) -> None: + self.x_space_values = x_space_values + self.y_space_values = y_space_values + + def ProjectForward(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectForward(x_values, self.x_space_values, self.y_space_values, self.beta, self.penalty_factor) + + def ProjectBackward(self, y_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectBackward(y_values, self.x_space_values, self.y_space_values, self.beta, self.penalty_factor) + + def ForwardProjectionGradient(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return KratosOA.ControlUtils.SigmoidalProjectionUtils.CalculateForwardProjectionGradient(x_values, self.x_space_values, self.y_space_values, self.beta, self.penalty_factor) + + def Update(self) -> None: + pass + +class AdaptiveSigmoidalProjection(Projection): + def __init__(self, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem): + default_parameters = Kratos.Parameters("""{ + "type" : "adaptive_sigmoidal_projection", + "initial_value" : 5, + "max_value" : 30, + "increase_fac" : 1.05, + "update_period" : 50, + "penalty_factor": 1 + }""") + + parameters.ValidateAndAssignDefaults(default_parameters) + self.beta = parameters["initial_value"].GetDouble() + self.max_beta = parameters["max_value"].GetDouble() + self.increase_fac = parameters["increase_fac"].GetDouble() + self.update_period = parameters["update_period"].GetInt() + self.penalty_factor = parameters["penalty_factor"].GetInt() + self.beta_computed_step = 1 + + self.x_space_values: 'Optional[list[float]]' = None + self.y_space_values: 'Optional[list[float]]' = None + + self.optimization_problem = optimization_problem + + def SetProjectionSpaces(self, x_space_values: list[float], y_space_values: list[float]) -> None: + self.x_space_values = x_space_values + self.y_space_values = y_space_values + + def ProjectForward(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectForward(x_values, self.x_space_values, self.y_space_values, self.beta, self.penalty_factor) + + def ProjectBackward(self, y_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectBackward(y_values, self.x_space_values, self.y_space_values, self.beta, self.penalty_factor) + + def ForwardProjectionGradient(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + return KratosOA.ControlUtils.SigmoidalProjectionUtils.CalculateForwardProjectionGradient(x_values, self.x_space_values, self.y_space_values, self.beta, self.penalty_factor) + + def Update(self) -> None: + step = self.optimization_problem.GetStep() + if step % self.update_period == 0 and self.beta_computed_step != step: + self.beta_computed_step = step + self.beta = min(self.beta * self.increase_fac, self.max_beta) + Kratos.Logger.PrintInfo(self.__class__.__name__, f"Increased beta to {self.beta}.") + + +def CreateProjection(parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> Projection: + if not parameters.Has("type"): + raise RuntimeError("Projection \"type\" is not present in following parameters:\n" + str(parameters)) + + projection_type = parameters["type"].GetString() + + projection_types_map: 'dict[str, type[Projection]]' = { + "identity_projection" : IdentityProjection, + "sigmoidal_projection" : SigmoidalProjection, + "adaptive_sigmoidal_projection": AdaptiveSigmoidalProjection + } + + if projection_type in projection_types_map.keys(): + return projection_types_map[projection_type](parameters, optimization_problem) + else: + raise RuntimeError(f"Unsupported projected type = \"{projection_type}\" requested. Followings are supported:\n\t" + "\n\t".join(list(projection_types_map.keys()))) From 176860d8a43e953794ad14b6c84081b7357bdbaa Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sun, 4 Aug 2024 15:21:19 +0530 Subject: [PATCH 2/9] fix identity projection --- ...linearly_interpolated_projection_utils.cpp | 0 .../linearly_interpolated_projection_utils.h | 70 ------------------- .../utilities/opt_projection.py | 10 ++- 3 files changed, 7 insertions(+), 73 deletions(-) delete mode 100644 applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.cpp delete mode 100644 applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h diff --git a/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.cpp b/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.cpp deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h b/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h deleted file mode 100644 index 4e47fb0c3d9c..000000000000 --- a/applications/OptimizationApplication/custom_utilities/control/linearly_interpolated_projection_utils.h +++ /dev/null @@ -1,70 +0,0 @@ -// | / | -// ' / __| _` | __| _ \ __| -// . \ | ( | | ( |\__ ` -// _|\_\_| \__,_|\__|\___/ ____/ -// Multi-Physics -// -// License: BSD License -// license: OptimizationApplication/license.txt -// -// Main author: Suneth Warnakulasuriya -// - -#pragma once - -// System includes -#include - -// Project includes -#include "includes/define.h" -#include "expression/container_expression.h" - -// Application includes - -namespace Kratos -{ - -///@name Kratos Classes -///@{ - -class KRATOS_API(OPTIMIZATION_APPLICATION) LinearlyInterpolatedProjectionUtils -{ -public: - ///@name Type definitions - ///@{ - - using IndexType = std::size_t; - - ///@} - ///@name Static operations - ///@{ - - template - static ContainerExpression ProjectForward( - const ContainerExpression& rInputExpression, - const std::vector& rXValues, - const std::vector& rYValues, - const double Beta, - const int PenaltyFactor); - - template - static ContainerExpression ProjectBackward( - const ContainerExpression& rInputExpression, - const std::vector& rXValues, - const std::vector& rYValues, - const double Beta, - const int PenaltyFactor); - - template - static ContainerExpression CalculateForwardProjectionGradient( - const ContainerExpression& rInputExpression, - const std::vector& rXValues, - const std::vector& rYValues, - const double Beta, - const int PenaltyFactor); - - ///@} -}; - -///@} -} \ No newline at end of file diff --git a/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py b/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py index 861d9fa239c0..bb2e5c8b9438 100644 --- a/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py +++ b/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py @@ -66,26 +66,30 @@ def Update(self) -> None: """Updates the projection method """ -class LinearlyInterpolatedProjection(Projection): +class IdentityProjection(Projection): def __init__(self, parameters: Kratos.Parameters, _): default_settings = Kratos.Parameters("""{ - "type" : "linearly_interpolated_projection", + "type" : "identity_projection", "extrapolate": "false" }""") parameters.ValidateAndAssignDefaults(default_settings) pass - def SetProjectionSpaces(self, x_space_values: list[float], y_space_values: list[float]) -> None: + def SetProjectionSpaces(self, _: list[float], __: list[float]) -> None: + # not using any of the spaces provided. pass def ProjectForward(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + # returns the x_values since x and y are the same for IdentityProjection return x_values.Clone() def ProjectBackward(self, y_values: ContainerExpressionTypes) -> ContainerExpressionTypes: + # return the y_values since x and y are the same for Identity projection return y_values.Clone() def ForwardProjectionGradient(self, x_values: ContainerExpressionTypes) -> ContainerExpressionTypes: result = x_values.Clone() + # x = y, hence the gradients are 1.0 Kratos.Expression.LiteralExpressionIO.SetData(result, 1.0) return result From d9fe16f909fa927d242edc0310462b18758ce4a6 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sun, 4 Aug 2024 16:14:10 +0530 Subject: [PATCH 3/9] test fixes --- .../controls/material/simp_control.py | 39 ++++------ .../thickness/shell_thickness_control.py | 64 ++++------------ .../optimization_parameters.json | 17 ++++- .../test_relaxed_gradient_projection.py | 76 +++++++++---------- .../control/material/test_simp_control.py | 41 +++++++--- .../thickness/test_shell_thickness_control.py | 15 ++-- 6 files changed, 118 insertions(+), 134 deletions(-) diff --git a/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py b/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py index 9a3edb90be57..1d62b8df4c32 100644 --- a/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py +++ b/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py @@ -65,37 +65,22 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters self.optimization_problem = optimization_problem default_settings = Kratos.Parameters("""{ - "controlled_model_part_names": [""], - "output_all_fields": true, - "echo_level" : 0, - "list_of_materials": [ + "controlled_model_part_names" : [""], + "output_all_fields" : true, + "echo_level" : 0, + "density_projection_settings" : {}, + "young_modulus_projection_settings": {}, + "filter_settings" : {}, + "list_of_materials" : [ { "density" : 1.0, "young_modulus": 1.0 } - ], - "density_projection_settings": { - "type" : "adaptive_sigmoidal_projection", - "initial_value" : 5, - "max_value" : 30, - "increase_fac" : 1.05, - "update_period" : 50, - "penalty_factor": 1 - }, - "young_modulus_projection_settings": { - "type" : "adaptive_sigmoidal_projection", - "initial_value" : 5, - "max_value" : 30, - "increase_fac" : 1.05, - "update_period" : 50, - "penalty_factor": 3 - }, - "filter_settings" : {} + ] }""") parameters.ValidateAndAssignDefaults(default_settings) - self.simp_power_fac = parameters["simp_power_fac"].GetInt() self.output_all_fields = parameters["output_all_fields"].GetBool() self.echo_level = parameters["echo_level"].GetInt() @@ -103,10 +88,7 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters self.materials = Materials(parameters["list_of_materials"].values()) - parameters["density_projection_settings"].ValidateAndAssignDefaults(default_settings["density_projection_settings"]) self.density_projection = CreateProjection(parameters["density_projection_settings"], self.optimization_problem) - - parameters["young_modulus_projection_settings"].ValidateAndAssignDefaults(default_settings["young_modulus_projection_settings"]) self.young_modulus_projection = CreateProjection(parameters["young_modulus_projection_settings"], self.optimization_problem) controlled_model_names_parts = parameters["controlled_model_part_names"].GetStringArray() @@ -205,8 +187,13 @@ def Update(self, control_field: ContainerExpressionTypes) -> bool: self._UpdateAndOutputFields(update) self.filter.Update() + # self.density_projection.Update() + # self.young_modulus_projection.Update() + # return True + self.density_projection.Update() self.young_modulus_projection.Update() + # return False def _UpdateAndOutputFields(self, update: ContainerExpressionTypes) -> None: # filter the control field diff --git a/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py b/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py index 1fd6382aa078..676f28d6aa55 100644 --- a/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py +++ b/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py @@ -36,18 +36,11 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters self.optimization_problem = optimization_problem default_settings = Kratos.Parameters("""{ - "controlled_model_part_names": [], - "filter_settings" : {}, - "penalty_power" : 1, - "output_all_fields" : false, - "physical_thicknesses" : [], - "beta_settings": { - "initial_value": 5, - "max_value" : 30, - "adaptive" : true, - "increase_fac" : 1.05, - "update_period": 50 - } + "controlled_model_part_names" : [], + "filter_settings" : {}, + "output_all_fields" : false, + "physical_thicknesses" : [], + "thickness_projection_settings": {} }""") self.parameters.ValidateAndAssignDefaults(default_settings) @@ -61,19 +54,10 @@ def __init__(self, name: str, model: Kratos.Model, parameters: Kratos.Parameters self.filter = FilterFactory(self.model, self.model_part_operation.GetModelPartFullName(), Kratos.THICKNESS, Kratos.Globals.DataLocation.Element, self.parameters["filter_settings"]) - self.penalty_power = self.parameters["penalty_power"].GetInt() self.output_all_fields = self.parameters["output_all_fields"].GetBool() self.physical_thicknesses = self.parameters["physical_thicknesses"].GetVector() - # beta settings - beta_settings = parameters["beta_settings"] - beta_settings.ValidateAndAssignDefaults(default_settings["beta_settings"]) - self.beta = beta_settings["initial_value"].GetDouble() - self.beta_max = beta_settings["max_value"].GetDouble() - self.beta_adaptive = beta_settings["adaptive"].GetBool() - self.beta_increase_frac = beta_settings["increase_fac"].GetDouble() - self.beta_update_period = beta_settings["update_period"].GetInt() - self.beta_computed_step = 1 + self.thickness_projection = CreateProjection(parameters["thickness_projection_settings"], self.optimization_problem) num_phys_thick = len(self.physical_thicknesses) if num_phys_thick == 0: @@ -91,16 +75,14 @@ def Initialize(self) -> None: self.filter.SetComponentDataView(ComponentDataView(self, self.optimization_problem)) self.filter.Initialize() + # initialize the projections + self.thickness_projection.SetProjectionSpaces(self.filtered_thicknesses, self.physical_thicknesses) + physical_thickness_field = Kratos.Expression.ElementExpression(self.model_part) KratosOA.PropertiesVariableExpressionIO.Read(physical_thickness_field, Kratos.THICKNESS) # project backward the uniform physical control field and assign it to the control field - self.physical_phi_field = KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectBackward( - physical_thickness_field, - self.filtered_thicknesses, - self.physical_thicknesses, - self.beta, - self.penalty_power) + self.physical_phi_field = self.thickness_projection.ProjectBackward(physical_thickness_field) # take the physical and control field the same self.control_phi_field = self.filter.UnfilterField(self.physical_phi_field) @@ -163,17 +145,11 @@ def Update(self, new_control_field: ContainerExpressionTypes) -> bool: self.filter.Update() - self.__UpdateBeta() + self.thickness_projection.Update() return True - return False - def __UpdateBeta(self) -> None: - if self.beta_adaptive: - step = self.optimization_problem.GetStep() - if step % self.beta_update_period == 0 and self.beta_computed_step != step: - self.beta_computed_step = step - self.beta = min(self.beta * self.beta_increase_frac, self.beta_max) - Kratos.Logger.PrintInfo(f"::{self.GetName()}::", f"Increased beta to {self.beta}.") + # self.thickness_projection.Update() + return False def _UpdateAndOutputFields(self, update: ContainerExpressionTypes) -> None: # filter the control field @@ -181,22 +157,12 @@ def _UpdateAndOutputFields(self, update: ContainerExpressionTypes) -> None: self.physical_phi_field = Kratos.Expression.Utils.Collapse(self.physical_phi_field + filtered_thickness_field_update) # project forward the filtered thickness field - projected_filtered_thickness_field = KratosOA.ControlUtils.SigmoidalProjectionUtils.ProjectForward( - self.physical_phi_field, - self.filtered_thicknesses, - self.physical_thicknesses, - self.beta, - self.penalty_power) + projected_filtered_thickness_field = self.thickness_projection.ProjectForward(self.physical_phi_field) # now update physical field KratosOA.PropertiesVariableExpressionIO.Write(projected_filtered_thickness_field, Kratos.THICKNESS) # compute and stroe projection derivatives for consistent filtering of the sensitivities - self.projection_derivative_field = KratosOA.ControlUtils.SigmoidalProjectionUtils.CalculateForwardProjectionGradient( - self.physical_phi_field, - self.filtered_thicknesses, - self.physical_thicknesses, - self.beta, - self.penalty_power) + self.projection_derivative_field = self.thickness_projection.ForwardProjectionGradient(self.physical_phi_field) # now output the fields un_buffered_data = ComponentDataView(self, self.optimization_problem).GetUnBufferedData() diff --git a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/optimization_parameters.json b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/optimization_parameters.json index 67ac2f13f113..a45ea6bdc887 100644 --- a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/optimization_parameters.json +++ b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/optimization_parameters.json @@ -67,14 +67,22 @@ "Structure.Parts_Shell_structure" ], "filter_settings": { - "filter_type" : "implicit_filter", + "filter_type": "implicit_filter", "filter_radius": 0.2 }, "output_all_fields": false, "physical_thicknesses": [ 0.1, 0.2 - ] + ], + "thickness_projection_settings": { + "type": "adaptive_sigmoidal_projection", + "initial_value": 5, + "max_value": 30, + "increase_fac": 1.05, + "update_period": 50, + "penalty_factor": 1 + } } } ], @@ -122,7 +130,10 @@ "output_file_name": "summary.csv", "write_kratos_version": false, "write_time_stamp": false, - "list_of_output_components": ["response_function.mass", "response_function.strain_energy"], + "list_of_output_components": [ + "response_function.mass", + "response_function.strain_energy" + ], "format_info": { "int_length": 7, "float_precision": 6, diff --git a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py index 3064d2f31ea2..0f9dbf241ba2 100644 --- a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py +++ b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py @@ -28,46 +28,46 @@ def test_gradient_projection_analysis(self): "relative_tolerance" : 1e-6 }""")).Execute() - def test_gradient_projection_components(self): - with KratosUnittest.WorkFolderScope(".", __file__): - with open("optimization_parameters.json", "r") as file_input: - parameters = Kratos.Parameters(file_input.read()) + # def test_gradient_projection_components(self): + # with KratosUnittest.WorkFolderScope(".", __file__): + # with open("optimization_parameters.json", "r") as file_input: + # parameters = Kratos.Parameters(file_input.read()) - model = Kratos.Model() - analysis = OptimizationAnalysis(model, parameters) - - analysis.Initialize() - analysis.Check() - algorithm = analysis.GetAlgorithm() - algorithm.Initialize() - active_constraints = algorithm.GetConstraintsList() - constraint = active_constraints[0] - control_field = algorithm.GetCurrentControlField() - value = constraint.CalculateStandardizedValue(control_field) - w = constraint.ComputeW() - self.assertAlmostEqual(w, 1.0) - value = constraint.CalculateStandardizedValue(control_field * 2) - constraint.UpdateBufferSize() - w = constraint.ComputeW() - self.assertAlmostEqual(w, 0.0) - self.assertAlmostEqual(constraint.BSF, 2.0) - self.assertAlmostEqual(constraint.BSF_init, 2.0) - self.assertAlmostEqual(constraint.CBV, 0.0) - self.assertAlmostEqual(constraint.BS, 1e-6, 3) - self.assertAlmostEqual(constraint.max_w_c, 10) - self.assertAlmostEqual(constraint.CF, 1) + # model = Kratos.Model() + # analysis = OptimizationAnalysis(model, parameters) + + # analysis.Initialize() + # analysis.Check() + # algorithm = analysis.GetAlgorithm() + # algorithm.Initialize() + # active_constraints = algorithm.GetConstraintsList() + # constraint = active_constraints[0] + # control_field = algorithm.GetCurrentControlField() + # value = constraint.CalculateStandardizedValue(control_field) + # w = constraint.ComputeW() + # self.assertAlmostEqual(w, 1.0) + # value = constraint.CalculateStandardizedValue(control_field * 2) + # constraint.UpdateBufferSize() + # w = constraint.ComputeW() + # self.assertAlmostEqual(w, 0.0) + # self.assertAlmostEqual(constraint.BSF, 2.0) + # self.assertAlmostEqual(constraint.BSF_init, 2.0) + # self.assertAlmostEqual(constraint.CBV, 0.0) + # self.assertAlmostEqual(constraint.BS, 1e-6, 3) + # self.assertAlmostEqual(constraint.max_w_c, 10) + # self.assertAlmostEqual(constraint.CF, 1) - algorithm._optimization_problem.AdvanceStep() - value = constraint.CalculateStandardizedValue(control_field*0.5) - constraint.UpdateBufferSize() - w = constraint.ComputeW() - self.assertAlmostEqual(w, 1.4727706310667317) - self.assertAlmostEqual(constraint.BSF, 2.0) - self.assertAlmostEqual(constraint.BSF_init, 2.0) - self.assertAlmostEqual(constraint.CBV, 0.0) - self.assertAlmostEqual(int(constraint.BS), 143814638) - self.assertAlmostEqual(constraint.max_w_c, 10) - self.assertAlmostEqual(constraint.CF, 1) + # algorithm._optimization_problem.AdvanceStep() + # value = constraint.CalculateStandardizedValue(control_field*0.5) + # constraint.UpdateBufferSize() + # w = constraint.ComputeW() + # self.assertAlmostEqual(w, 1.4727706310667317) + # self.assertAlmostEqual(constraint.BSF, 2.0) + # self.assertAlmostEqual(constraint.BSF_init, 2.0) + # self.assertAlmostEqual(constraint.CBV, 0.0) + # self.assertAlmostEqual(int(constraint.BS), 143814638) + # self.assertAlmostEqual(constraint.max_w_c, 10) + # self.assertAlmostEqual(constraint.CF, 1) @classmethod diff --git a/applications/OptimizationApplication/tests/control/material/test_simp_control.py b/applications/OptimizationApplication/tests/control/material/test_simp_control.py index e0d889068946..3293bf7bce57 100644 --- a/applications/OptimizationApplication/tests/control/material/test_simp_control.py +++ b/applications/OptimizationApplication/tests/control/material/test_simp_control.py @@ -19,7 +19,6 @@ def setUpClass(cls): "controlled_model_part_names": [ "shell" ], - "simp_power_fac": 3, "output_all_fields": true, "list_of_materials": [ { @@ -31,13 +30,21 @@ def setUpClass(cls): "young_modulus": 206900000000.0 } ], - "beta_settings": { + "density_projection_settings": { + "type": "adaptive_sigmoidal_projection", "initial_value": 2, "max_value": 50, - "adaptive": true, "increase_fac": 1.05, "update_period": 25 }, + "young_modulus_projection_settings": { + "type": "adaptive_sigmoidal_projection", + "initial_value": 2, + "max_value": 50, + "increase_fac": 1.05, + "update_period": 25, + "penalty_factor": 3 + }, "filter_settings": { "filter_type": "explicit_filter", "filter_function_type": "linear", @@ -162,19 +169,27 @@ def test_AdaptiveBeta(self): "damped_model_part_settings": {} } }, - "beta_settings": { + "density_projection_settings": { + "type": "adaptive_sigmoidal_projection", "initial_value": 0.01, "max_value" : 30, - "adaptive" : true, "increase_fac" : 1.05, "update_period": 3 + }, + "young_modulus_projection_settings": { + "type": "adaptive_sigmoidal_projection", + "initial_value": 0.01, + "max_value" : 30, + "increase_fac" : 1.05, + "update_period": 3, + "penalty_factor": 3 } }""") simp_control = SimpControl("test_adaptive", self.model, parameters, self.optimization_problem) self.optimization_problem.AddComponent(simp_control) simp_control.Initialize() - self.assertAlmostEqual(simp_control.beta, 0.01) + self.assertAlmostEqual(simp_control.density_projection.beta, 0.01) control_field = simp_control.GetControlField() simp_control.Update(control_field) @@ -183,7 +198,7 @@ def test_AdaptiveBeta(self): simp_control.Update(control_field) self.optimization_problem.AdvanceStep() - self.assertAlmostEqual(simp_control.beta, 0.01 * (1.05 ** 7)) + self.assertAlmostEqual(simp_control.density_projection.beta, 0.01 * (1.05 ** 7)) def test_NonRemovalOfMaterials(self): parameters = Kratos.Parameters("""{ @@ -213,12 +228,20 @@ def test_NonRemovalOfMaterials(self): "damped_model_part_settings": {} } }, - "beta_settings": { + "density_projection_settings": { + "type": "adaptive_sigmoidal_projection", "initial_value": 0.01, "max_value" : 30, - "adaptive" : true, "increase_fac" : 1.05, "update_period": 3 + }, + "young_modulus_projection_settings": { + "type": "adaptive_sigmoidal_projection", + "initial_value": 0.01, + "max_value" : 30, + "increase_fac" : 1.05, + "update_period": 3, + "penalty_factor": 3 } }""") diff --git a/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py b/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py index 6a9eda322462..aa2ac32b16e4 100644 --- a/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py +++ b/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py @@ -22,12 +22,9 @@ def setUpClass(cls): "filter_type" : "implicit_filter", "filter_radius": 0.2 }, - "beta_settings": { - "initial_value": 25, - "max_value" : 30, - "adaptive" : false, - "increase_fac" : 1.05, - "update_period": 50 + "thickness_projection_settings": { + "type": "sigmoidal_projection", + "beta_value": 25 } }""") @@ -98,10 +95,10 @@ def test_AdaptiveBeta(self): "filter_type" : "implicit_filter", "filter_radius": 0.2 }, - "beta_settings": { + "thickness_projection_settings": { + "type": "adaptive_sigmoidal_projection", "initial_value": 0.01, "max_value" : 30, - "adaptive" : true, "increase_fac" : 1.05, "update_period": 3 } @@ -117,7 +114,7 @@ def test_AdaptiveBeta(self): thickness_control.Update(control_field) self.optimization_problem.AdvanceStep() - self.assertAlmostEqual(thickness_control.beta, 0.01157625) + self.assertAlmostEqual(thickness_control.thickness_projection.beta, 0.01157625) self.assertAlmostEqual(Kratos.Expression.Utils.NormL2(thickness_control.GetPhysicalField()), 0.031173377425432858) if __name__ == "__main__": From 717e3131586520f20ca233229ed6fca1331684f5 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sun, 4 Aug 2024 16:14:46 +0530 Subject: [PATCH 4/9] fix simp::Update return value --- .../python_scripts/controls/material/simp_control.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py b/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py index 1d62b8df4c32..02f97e858fd7 100644 --- a/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py +++ b/applications/OptimizationApplication/python_scripts/controls/material/simp_control.py @@ -187,13 +187,13 @@ def Update(self, control_field: ContainerExpressionTypes) -> bool: self._UpdateAndOutputFields(update) self.filter.Update() - # self.density_projection.Update() - # self.young_modulus_projection.Update() - # return True + self.density_projection.Update() + self.young_modulus_projection.Update() + return True self.density_projection.Update() self.young_modulus_projection.Update() - # return False + return False def _UpdateAndOutputFields(self, update: ContainerExpressionTypes) -> None: # filter the control field From 64e65523b51497652a47c126556eded4a6f281f6 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sun, 4 Aug 2024 16:20:41 +0530 Subject: [PATCH 5/9] add shell_thickness_proj update --- .../controls/thickness/shell_thickness_control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py b/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py index 676f28d6aa55..3719a959c54a 100644 --- a/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py +++ b/applications/OptimizationApplication/python_scripts/controls/thickness/shell_thickness_control.py @@ -148,7 +148,7 @@ def Update(self, new_control_field: ContainerExpressionTypes) -> bool: self.thickness_projection.Update() return True - # self.thickness_projection.Update() + self.thickness_projection.Update() return False def _UpdateAndOutputFields(self, update: ContainerExpressionTypes) -> None: From 9af838f2dc0808c03e2c49dfa87b07eb3b054285 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sun, 4 Aug 2024 18:25:32 +0530 Subject: [PATCH 6/9] change of ref values --- .../summary_orig.csv | 20 +++++++++---------- .../thickness/test_shell_thickness_control.py | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/summary_orig.csv b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/summary_orig.csv index 22832c540530..2530554c77cc 100644 --- a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/summary_orig.csv +++ b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/summary_orig.csv @@ -13,14 +13,14 @@ # Headers: # STEP, mass:value, strain_energy:value 0, 5.887500e+03, 5.004872e+06 - 1, 5.878896e+03, 9.030505e+05 - 2, 5.822313e+03, 1.028289e+06 - 3, 5.781430e+03, 1.075626e+06 - 4, 5.740856e+03, 1.132388e+06 - 5, 5.700680e+03, 1.190006e+06 - 6, 5.660883e+03, 1.250367e+06 - 7, 5.621474e+03, 1.313503e+06 - 8, 5.582462e+03, 1.379604e+06 - 9, 5.543855e+03, 1.448842e+06 - 10, 5.505668e+03, 1.521395e+06 + 1, 5.877712e+03, 9.031804e+05 + 2, 5.819053e+03, 1.035807e+06 + 3, 5.776169e+03, 1.085432e+06 + 4, 5.733628e+03, 1.145764e+06 + 5, 5.691533e+03, 1.206921e+06 + 6, 5.649862e+03, 1.271146e+06 + 7, 5.608626e+03, 1.338458e+06 + 8, 5.567833e+03, 1.409084e+06 + 9, 5.527498e+03, 1.483221e+06 + 10, 5.487634e+03, 1.561076e+06 # End of file \ No newline at end of file diff --git a/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py b/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py index aa2ac32b16e4..526bed8a917a 100644 --- a/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py +++ b/applications/OptimizationApplication/tests/control/thickness/test_shell_thickness_control.py @@ -114,8 +114,8 @@ def test_AdaptiveBeta(self): thickness_control.Update(control_field) self.optimization_problem.AdvanceStep() - self.assertAlmostEqual(thickness_control.thickness_projection.beta, 0.01157625) - self.assertAlmostEqual(Kratos.Expression.Utils.NormL2(thickness_control.GetPhysicalField()), 0.031173377425432858) + self.assertAlmostEqual(thickness_control.thickness_projection.beta, 0.014071004226562506) + self.assertAlmostEqual(Kratos.Expression.Utils.NormL2(thickness_control.GetPhysicalField()), 0.031423121954655735) if __name__ == "__main__": kratos_unittest.main() \ No newline at end of file From 898d8b67d864b9805f4527c9f9c73ab427d14d03 Mon Sep 17 00:00:00 2001 From: sunethwarna Date: Sun, 4 Aug 2024 18:38:15 +0530 Subject: [PATCH 7/9] fix tests with ref value changes --- .../test_relaxed_gradient_projection.py | 74 +++++++++---------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py index 0f9dbf241ba2..7fd604d61931 100644 --- a/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py +++ b/applications/OptimizationApplication/tests/algorithm_tests/analysis_based_tests/algorithm_relaxed_gradient_projection/test_relaxed_gradient_projection.py @@ -28,46 +28,46 @@ def test_gradient_projection_analysis(self): "relative_tolerance" : 1e-6 }""")).Execute() - # def test_gradient_projection_components(self): - # with KratosUnittest.WorkFolderScope(".", __file__): - # with open("optimization_parameters.json", "r") as file_input: - # parameters = Kratos.Parameters(file_input.read()) + def test_gradient_projection_components(self): + with KratosUnittest.WorkFolderScope(".", __file__): + with open("optimization_parameters.json", "r") as file_input: + parameters = Kratos.Parameters(file_input.read()) - # model = Kratos.Model() - # analysis = OptimizationAnalysis(model, parameters) + model = Kratos.Model() + analysis = OptimizationAnalysis(model, parameters) - # analysis.Initialize() - # analysis.Check() - # algorithm = analysis.GetAlgorithm() - # algorithm.Initialize() - # active_constraints = algorithm.GetConstraintsList() - # constraint = active_constraints[0] - # control_field = algorithm.GetCurrentControlField() - # value = constraint.CalculateStandardizedValue(control_field) - # w = constraint.ComputeW() - # self.assertAlmostEqual(w, 1.0) - # value = constraint.CalculateStandardizedValue(control_field * 2) - # constraint.UpdateBufferSize() - # w = constraint.ComputeW() - # self.assertAlmostEqual(w, 0.0) - # self.assertAlmostEqual(constraint.BSF, 2.0) - # self.assertAlmostEqual(constraint.BSF_init, 2.0) - # self.assertAlmostEqual(constraint.CBV, 0.0) - # self.assertAlmostEqual(constraint.BS, 1e-6, 3) - # self.assertAlmostEqual(constraint.max_w_c, 10) - # self.assertAlmostEqual(constraint.CF, 1) + analysis.Initialize() + analysis.Check() + algorithm = analysis.GetAlgorithm() + algorithm.Initialize() + active_constraints = algorithm.GetConstraintsList() + constraint = active_constraints[0] + control_field = algorithm.GetCurrentControlField() + value = constraint.CalculateStandardizedValue(control_field) + w = constraint.ComputeW() + self.assertAlmostEqual(w, 1.0) + value = constraint.CalculateStandardizedValue(control_field * 2) + constraint.UpdateBufferSize() + w = constraint.ComputeW() + self.assertAlmostEqual(w, 0.0) + self.assertAlmostEqual(constraint.BSF, 2.0) + self.assertAlmostEqual(constraint.BSF_init, 2.0) + self.assertAlmostEqual(constraint.CBV, 0.0) + self.assertAlmostEqual(constraint.BS, 1e-6, 3) + self.assertAlmostEqual(constraint.max_w_c, 10) + self.assertAlmostEqual(constraint.CF, 1) - # algorithm._optimization_problem.AdvanceStep() - # value = constraint.CalculateStandardizedValue(control_field*0.5) - # constraint.UpdateBufferSize() - # w = constraint.ComputeW() - # self.assertAlmostEqual(w, 1.4727706310667317) - # self.assertAlmostEqual(constraint.BSF, 2.0) - # self.assertAlmostEqual(constraint.BSF_init, 2.0) - # self.assertAlmostEqual(constraint.CBV, 0.0) - # self.assertAlmostEqual(int(constraint.BS), 143814638) - # self.assertAlmostEqual(constraint.max_w_c, 10) - # self.assertAlmostEqual(constraint.CF, 1) + algorithm._optimization_problem.AdvanceStep() + value = constraint.CalculateStandardizedValue(control_field*0.5) + constraint.UpdateBufferSize() + w = constraint.ComputeW() + self.assertAlmostEqual(w, 1.472738040151665) + self.assertAlmostEqual(constraint.BSF, 2.0) + self.assertAlmostEqual(constraint.BSF_init, 2.0) + self.assertAlmostEqual(constraint.CBV, 0.0) + self.assertAlmostEqual(int(constraint.BS), 143622435) + self.assertAlmostEqual(constraint.max_w_c, 10) + self.assertAlmostEqual(constraint.CF, 1) @classmethod From 0b1403f04eebddd9252efd9b119bd5e06447c946 Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Tue, 15 Oct 2024 16:37:35 +0200 Subject: [PATCH 8/9] left over --- .../tests/responses_tests/test_combined_response_function.py | 1 - 1 file changed, 1 deletion(-) diff --git a/applications/OptimizationApplication/tests/responses_tests/test_combined_response_function.py b/applications/OptimizationApplication/tests/responses_tests/test_combined_response_function.py index 749778d68821..9af9cb375fc0 100644 --- a/applications/OptimizationApplication/tests/responses_tests/test_combined_response_function.py +++ b/applications/OptimizationApplication/tests/responses_tests/test_combined_response_function.py @@ -164,7 +164,6 @@ def get_data(add_density_physical_var = True): v7_shape, v7_rho, data = get_data() self.resp_7.CalculateGradient(data) - print(v6_shape.Evaluate()) self.assertAlmostEqual(Kratos.Expression.Utils.NormL2(v6_shape - v1_shape * 2.1 - v2_shape * 3.1 - v3_shape * 4.1), 0.0) self.assertAlmostEqual(Kratos.Expression.Utils.NormL2(v6_rho - v1_rho * 2.1 - v2_rho * 3.1 - v3_rho * 4.1), 0.0) From 0be2607160a6e6be236d62038a9d8cb73d06bf2c Mon Sep 17 00:00:00 2001 From: Suneth Warnakulasuriya Date: Tue, 15 Oct 2024 16:37:42 +0200 Subject: [PATCH 9/9] name change --- .../utilities/opt_projection.py | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py b/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py index bb2e5c8b9438..1dfbe74d8224 100644 --- a/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py +++ b/applications/OptimizationApplication/python_scripts/utilities/opt_projection.py @@ -6,10 +6,10 @@ from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem from KratosMultiphysics.OptimizationApplication.utilities.union_utilities import ContainerExpressionTypes -class Projection(ABC): - """Projection methods to convert given x space values to given y space values +class DesignVariableProjection(ABC): + """Design variable projection methods to convert given x space values to given y space values - This is the interface class which can be used to implement projection classes + This is the interface class which can be used to implement design variable projection classes which project forward and backward given x space values to y space. The projection spaces should be scalar spaces. @@ -66,7 +66,7 @@ def Update(self) -> None: """Updates the projection method """ -class IdentityProjection(Projection): +class IdentityDesignVariableProjection(DesignVariableProjection): def __init__(self, parameters: Kratos.Parameters, _): default_settings = Kratos.Parameters("""{ "type" : "identity_projection", @@ -96,7 +96,7 @@ def ForwardProjectionGradient(self, x_values: ContainerExpressionTypes) -> Conta def Update(self) -> None: pass -class SigmoidalProjection(Projection): +class SigmoidalDesignVariableProjection(DesignVariableProjection): def __init__(self, parameters: Kratos.Parameters, _): default_parameters = Kratos.Parameters("""{ "type" : "sigmoidal_projection", @@ -127,7 +127,7 @@ def ForwardProjectionGradient(self, x_values: ContainerExpressionTypes) -> Conta def Update(self) -> None: pass -class AdaptiveSigmoidalProjection(Projection): +class AdaptiveSigmoidalDesignVariableProjection(DesignVariableProjection): def __init__(self, parameters: Kratos.Parameters, optimization_problem: OptimizationProblem): default_parameters = Kratos.Parameters("""{ "type" : "adaptive_sigmoidal_projection", @@ -172,16 +172,16 @@ def Update(self) -> None: Kratos.Logger.PrintInfo(self.__class__.__name__, f"Increased beta to {self.beta}.") -def CreateProjection(parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> Projection: +def CreateProjection(parameters: Kratos.Parameters, optimization_problem: OptimizationProblem) -> DesignVariableProjection: if not parameters.Has("type"): - raise RuntimeError("Projection \"type\" is not present in following parameters:\n" + str(parameters)) + raise RuntimeError("DesignVariableProjection \"type\" is not present in following parameters:\n" + str(parameters)) projection_type = parameters["type"].GetString() - projection_types_map: 'dict[str, type[Projection]]' = { - "identity_projection" : IdentityProjection, - "sigmoidal_projection" : SigmoidalProjection, - "adaptive_sigmoidal_projection": AdaptiveSigmoidalProjection + projection_types_map: 'dict[str, type[DesignVariableProjection]]' = { + "identity_projection" : IdentityDesignVariableProjection, + "sigmoidal_projection" : SigmoidalDesignVariableProjection, + "adaptive_sigmoidal_projection": AdaptiveSigmoidalDesignVariableProjection } if projection_type in projection_types_map.keys():