diff --git a/applications/OptimizationApplication/python_scripts/algorithms/algorithm.py b/applications/OptimizationApplication/python_scripts/algorithms/algorithm.py index 095182505fff..d3639163cb06 100644 --- a/applications/OptimizationApplication/python_scripts/algorithms/algorithm.py +++ b/applications/OptimizationApplication/python_scripts/algorithms/algorithm.py @@ -4,26 +4,64 @@ from KratosMultiphysics.OptimizationApplication.utilities.helper_utilities import CallOnAll class Algorithm(ABC): + """Base class for algorithm. + + Algorithm works purely in the control space. Hence, the ResponseRoutine which + the algorithm is associated with should convert all physical space gradients to + control space and control space designs to physical space designs. + + The purpose of the algorithm is to solve a minimization problem. Hence, the used + ResponseRoutine should standardize the values and gradients it computes accordingly. + + Algorithm should create one MasterControl from all the require controls, and share + it among all the ResponseRoutines. + + Once it received the objective/constraint values and their gradients, the algorithm + will compute the new design and request new objective/constraints values and their + gradients until the specified convergence criteria is met. + """ def __init__(self, optimization_problem: OptimizationProblem) -> None: self._optimization_problem = optimization_problem @abstractmethod def Initialize(self) -> None: + """Initializes the algorithm, ResponseRoutines and MasterControl. + """ pass @abstractmethod def Check(self) -> None: + """Checks algorithm, ResponseRoutines and MasterControl. + """ pass @abstractmethod def Finalize(self) -> None: + """Finalizes algorithm ResponseRoutines and MasterControl. + """ pass @abstractmethod def Solve(self) -> bool: + """Solves the optimization problem. + + This method will have a loop which iterates until the specified + convergence for the given optimization problem. + + Returns: + bool: Convergence status. True for converged, False for non-converged. + """ pass def GetProcessesOrder(self) -> 'list[str]': + """The order of execution of the process categories. + + This defines the order of execution of the processes defined under "processes" + in either "kratos_process" or "optimization_data_processes". + + Returns: + list[str]: List of strings for process categories. + """ return ["auxiliary_processes", "output_processes"] def CallOnAllProcesses(self, process_types: 'list[str]', *args, **kwargs): diff --git a/applications/OptimizationApplication/python_scripts/execution_policies/execution_policy.py b/applications/OptimizationApplication/python_scripts/execution_policies/execution_policy.py index 7516953b3c16..27ccaa6d6792 100644 --- a/applications/OptimizationApplication/python_scripts/execution_policies/execution_policy.py +++ b/applications/OptimizationApplication/python_scripts/execution_policies/execution_policy.py @@ -2,6 +2,13 @@ import KratosMultiphysics as Kratos class ExecutionPolicy(ABC): + """Base class for execution policy + + This represents the base class for the execution policy which + can be used to execute primal analysis to obtain response function + values and their gradients. + + """ def __init__(self, execution_policy_name: str) -> None: self.__name = execution_policy_name @@ -22,8 +29,18 @@ def Finalize(self) -> None: @abstractmethod def GetAnalysisModelPart(self) -> Kratos.ModelPart: + """Returns the analysis model part. + + Each execution policy will be using a domain to compute the primal model part. + This method should return that domain as a Kratos::ModelPart. + + Returns: + Kratos.ModelPart: Domain used to compute the primal solution. + """ pass @abstractmethod def Execute(self) -> None: + """Solves the associated primal problem. + """ pass \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/Algorithms/Gradient_Projection.md b/docs/pages/Applications/Optimization_Application/Algorithms/Gradient_Projection.md new file mode 100644 index 000000000000..5cf1f4aa7422 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Algorithms/Gradient_Projection.md @@ -0,0 +1,7 @@ +--- +title: Gradient Projection +keywords: +tags: [gradient_projection.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Algorithms/Overview.md b/docs/pages/Applications/Optimization_Application/Algorithms/Overview.md new file mode 100644 index 000000000000..7e33bac5441a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Algorithms/Overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +keywords: +tags: [Overview.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Algorithms/Steepest_Descent.md b/docs/pages/Applications/Optimization_Application/Algorithms/Steepest_Descent.md new file mode 100644 index 000000000000..24315e7d9780 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Algorithms/Steepest_Descent.md @@ -0,0 +1,7 @@ +--- +title: Steepest Descent +keywords: +tags: [steepest_descent.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Algorithms/menu_info.json b/docs/pages/Applications/Optimization_Application/Algorithms/menu_info.json new file mode 100644 index 000000000000..0cc207564821 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Algorithms/menu_info.json @@ -0,0 +1,5 @@ +{ + "custom_entries": [ + "Overview.md" + ] +} \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/Controls/Overview.md b/docs/pages/Applications/Optimization_Application/Controls/Overview.md new file mode 100644 index 000000000000..7e33bac5441a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Controls/Overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +keywords: +tags: [Overview.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Controls/Shell_Thickness_Control.md b/docs/pages/Applications/Optimization_Application/Controls/Shell_Thickness_Control.md new file mode 100644 index 000000000000..076ac1eacb79 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Controls/Shell_Thickness_Control.md @@ -0,0 +1,7 @@ +--- +title: Shell Thickness Control +keywords: +tags: [Shell_Thickness_Control.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Controls/Vertex_Morphing_Shape_Control.md b/docs/pages/Applications/Optimization_Application/Controls/Vertex_Morphing_Shape_Control.md new file mode 100644 index 000000000000..c61d1ac95a01 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Controls/Vertex_Morphing_Shape_Control.md @@ -0,0 +1,94 @@ +--- +title: Vertex Morphing Shape Control +keywords: +tags: [Vertex_Morphing_Shape_Control.md] +sidebar: optimization_application +summary: +--- + +## Introduction + +```VertexMorphingShapeControl``` is used to control the shape of a specified domain (given by a model part). This control can use either [Explicit Vertex Morphing](../Filtering/Explicit_Vertex_Morphing.html) or Implicit Vertex Morphing as the filtering method. Therefore, the physical space gradients will be transformed to smoothened vertex morphed control space gradients. + +This has an inbuilt mesh motion solver to solve for the mesh once the shape is changed. Therefore, it requires to have mesh motion settings as well. + +## Json settings + +### Explicit vertex morphing +Following json snippet illustrates one use case of explicit vertex morphing +```json +{ + "name": "explicit_shape_control", + "type": "shape.vertex_morphing_shape_control", + "module" : "KratosMultiphysics.OptimizationApplication.controls", + "settings":{ + "controlled_model_part_names": [], + "filter_settings": { + "type" : "surface_explicit", + "filter_function_type" : "linear", + "damping_function_type" : "sigmoidal", + "radius": 0.000000000001, + "max_nodes_in_filter_radius": 1000 + }, + "mesh_motion_settings" : {}, + "output_all_fields": false, + "fixed_model_parts": {}, + } +} +``` + +| Option | Allowed values | +| ------------- | ------------- | +| name | A unique string name | +| type | "shape.vertex_morphing_shape_control" | +| module | "KratosMultiphysics.OptimizationApplication.model_part_controllers" | +| controlled_model_part_names | List of model part names of which the shape should be controlled. | +| filter_settings::type | "surface_explicit" | +| filter_settings::filter_function_type | Types of filter functions to be used. ["gaussian"](../Filtering/Explicit_Vertex_Morphing.html#gaussian-filter-function), ["linear"](../Filtering/Explicit_Vertex_Morphing.html#linear-filter-function), ["constant"](../Filtering/Explicit_Vertex_Morphing.html#constant-filter-function), ["cosine"](../Filtering/Explicit_Vertex_Morphing.html#cosine-filter-function), ["quartic"](../Filtering/Explicit_Vertex_Morphing.html#quartic-filter-function) are supported.| +| filter_settings::damping_function_type | Type of the damping function to be used. ["gaussian"](../Filtering/Explicit_Vertex_Morphing.md#gaussian-filter-function-1), ["linear"](../Filtering/Explicit_Vertex_Morphing.md#linear-filter-function-1), ["constant"](../Filtering/Explicit_Vertex_Morphing.md#constant-filter-function-1), ["cosine"](../Filtering/Explicit_Vertex_Morphing.md#constant-filter-function-1), ["quartic"](../Filtering/Explicit_Vertex_Morphing.md#quartic-filter-function-1) "sigmoidal" are supported. | +| filter_settings::radius| Filter radius | +| filter_settings::max_nodes_in_filter_radius| Number of max nodes to be found in the filter radius. This specifies maximum number of neighbours will be searched for. If the radii is higher, or mesh is refined, then this number should be increased. | +| mesh_motion_settings | Mesh motion solver settings | +| output_all_fields | Output intermediate results also to the ```OptimizationProblem``` data container. | +| fixed_model_parts | List of model part names to be dampened | + +### Implicit vertex morphing +Following json snippet illustrates one use case of explicit vertex morphing +```json +{ + "name": "implicit_shape_control", + "type": "shape.vertex_morphing_shape_control", + "module" : "KratosMultiphysics.OptimizationApplication.controls", + "settings":{ + "controlled_model_part_names": [], + "filter_settings": { + "type" : "bulk_surface_implicit", + "radius": 0.000000000001, + "linear_solver_settings" : {} + }, + "mesh_motion_settings" : {}, + "output_all_fields": false, + "fixed_model_parts": {}, + } +} +``` + +| Option | Allowed values | +| ------------- | ------------- | +| name | A unique string name | +| type | "shape.vertex_morphing_shape_control" | +| module | "KratosMultiphysics.OptimizationApplication.model_part_controllers" | +| controlled_model_part_names | List of model part names of which the shape should be controlled. | +| filter_settings::type | "bulk_surface_implicit" | +| filter_settings::radius| Filter radius | +| filter_settings::linear_solver_settings | Linear solver to be used in the implicit vertex morphing solver | +| mesh_motion_settings | Mesh motion solver settings | +| output_all_fields | Output intermediate results also to the ```OptimizationProblem``` data container. | +| fixed_model_parts | List of model part names to be dampened | + +## Source files +* [Doxygen](TODO) TODO +* [applications/OptimizationApplication/python_scripts/controls/shape/vertex_morphing_shape_control.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/controls/shape/vertex_morphing_shape_control.py) +* [applications/OptimizationApplication/python_scripts/filtering/helmholtz_analysis.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/filtering/helmholtz_analysis.py) + + diff --git a/docs/pages/Applications/Optimization_Application/Controls/menu_info.json b/docs/pages/Applications/Optimization_Application/Controls/menu_info.json new file mode 100644 index 000000000000..0cc207564821 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Controls/menu_info.json @@ -0,0 +1,5 @@ +{ + "custom_entries": [ + "Overview.md" + ] +} \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/Execution_Policies/Independent_Analysis_Execution_Policy.md b/docs/pages/Applications/Optimization_Application/Execution_Policies/Independent_Analysis_Execution_Policy.md new file mode 100644 index 000000000000..ed67f04d4c3d --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Execution_Policies/Independent_Analysis_Execution_Policy.md @@ -0,0 +1,38 @@ +--- +title: Independent Analysis Execution Policy +keywords: +tags: [independent, execution policy, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +```IndependentAnalysisExecutionPolicy``` is used to execute a primal analysis which needs to be independent from the model parts of the origin. But they both share the same ```Kratos::Model```. + +## Json settings +Following json-snippet illustrates an example use case +```json +{ + "type": "independent_analysis_execution_policy", + "module": "KratosMultiphysics.OptimizationApplication.execution_policies", + "settings": { + "analysis_module" : "KratosMultiphysics", + "analysis_type" : "", + "analysis_model_part_name": "", + "analysis_settings" : {} + } +} +``` + +| Option | Allowed values | +| ------------- | ------------- | +| type | "independent_analysis_execution_policy" | +| module | "KratosMultiphysics.OptimizationApplication.model_part_controllers" | +| analysis_module | Where to find the module for `analysis_type`. | +| analysis_type | Analysis type to used to solve the primal analysis. | +| analysis_settings | Settings for the analysis | + +## Source files +* [Doxygen](TODO) TODO +* [applications/OptimizationApplication/python_scripts/execution_policies/independent_analysis_execution_policy.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/execution_policies/independent_analysis_execution_policy.py) \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/Execution_Policies/Kratos_Analysis_Execution_Policy.md b/docs/pages/Applications/Optimization_Application/Execution_Policies/Kratos_Analysis_Execution_Policy.md new file mode 100644 index 000000000000..d530073694e4 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Execution_Policies/Kratos_Analysis_Execution_Policy.md @@ -0,0 +1,55 @@ +--- +title: Kratos Analysis Execution Policy +keywords: +tags: [kratos, execution policy, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +```KratosAnalysisExecutionPolicy``` is used to execute a primal analysis which may or not need to be independent from the model parts of the origin. But they both share the same ```Kratos::Model```. + +In this execution policy, when ```Execute``` method is called, following variables in the specified model parts are made to zero. +* STEP +* TIME +* DELTA_TIME + +## Json settings +Following json-snippet illustrates an example use case +```json +{ + "type": "independent_analysis_execution_policy", + "module": "KratosMultiphysics.OptimizationApplication.execution_policies", + "settings": { + "model_part_names" : [], + "analysis_module" : "KratosMultiphysics", + "analysis_type" : "", + "analysis_settings": {}, + "analysis_output_settings": { + "nodal_solution_step_data_variables": [], + "nodal_data_value_variables" : [], + "element_data_value_variables" : [], + "condition_data_value_variables" : [] + } + } +} +``` + +| Option | Allowed values | +| ------------- | ------------- | +| type | "independent_analysis_execution_policy" | +| module | "KratosMultiphysics.OptimizationApplication.model_part_controllers" | +| model_part_names | Model part names to be used for outputting data and resetting variables. | +| analysis_module | Where to find the module for `analysis_type`. | +| analysis_type | Analysis type to used to solve the primal analysis. | +| analysis_settings | Settings for the analysis | +| analysis_output_settings | Output settings for variables in the model parts listed in `model_part_names`. An [OptimizationProblemVtuOutputProcess](../Processes/Optimization_Problem_Vtu_Output_Process.html) needs to be used to write these fields to files. | +| nodal_solution_step_data_variables | List of nodal solution step variable names | +| nodal_data_value_variables | List of nodal non-historical variable names | +| element_data_value_variables | Element data value variable names | +| condition_data_value_variables | Condition data value variable names | + +## Source files +* [Doxygen](TODO) TODO +* [applications/OptimizationApplication/python_scripts/execution_policies/kratos_analysis_execution_policy.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/execution_policies/kratos_analysis_execution_policy.py) diff --git a/docs/pages/Applications/Optimization_Application/Execution_Policies/Overview.md b/docs/pages/Applications/Optimization_Application/Execution_Policies/Overview.md new file mode 100644 index 000000000000..7e33bac5441a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Execution_Policies/Overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +keywords: +tags: [Overview.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Execution_Policies/Stepping_Analysis_Execution_Policy.md b/docs/pages/Applications/Optimization_Application/Execution_Policies/Stepping_Analysis_Execution_Policy.md new file mode 100644 index 000000000000..587ad517c21e --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Execution_Policies/Stepping_Analysis_Execution_Policy.md @@ -0,0 +1,44 @@ +--- +title: Stepping Analysis Execution Policy +keywords: +tags: [stepping kratos, execution policy, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +```SteppingAnalysisExecutionPolicy``` is used to execute a primal analysis which may or not need to be independent from the model parts of the origin. But they both share the same ```Kratos::Model```. + +In this execution policy, when ```Execute``` method is called, following variables in the specified model parts are made to zero before and thereafter, original values are restored after running the primal analysis. +* STEP +* TIME +* DELTA_TIME + +## Json settings +Following json-snippet illustrates an example use case +```json +{ + "type": "independent_analysis_execution_policy", + "module": "KratosMultiphysics.OptimizationApplication.execution_policies", + "settings": { + "model_part_names" : [], + "analysis_module" : "KratosMultiphysics", + "analysis_type" : "", + "analysis_settings": {} + } +} +``` + +| Option | Allowed values | +| ------------- | ------------- | +| type | "independent_analysis_execution_policy" | +| module | "KratosMultiphysics.OptimizationApplication.model_part_controllers" | +| model_part_names | Model part names to be used for outputting data and resetting variables. | +| analysis_module | Where to find the module for `analysis_type`. | +| analysis_type | Analysis type to used to solve the primal analysis. | +| analysis_settings | Settings for the analysis | + +## Source files +* [Doxygen](TODO) TODO +* [applications/OptimizationApplication/python_scripts/execution_policies/stepping_analysis_execution_policy.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/execution_policies/stepping_analysis_execution_policy.py) \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/Execution_Policies/menu_info.json b/docs/pages/Applications/Optimization_Application/Execution_Policies/menu_info.json new file mode 100644 index 000000000000..0cc207564821 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Execution_Policies/menu_info.json @@ -0,0 +1,5 @@ +{ + "custom_entries": [ + "Overview.md" + ] +} \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/Filtering/Explicit_Vertex_Morphing.md b/docs/pages/Applications/Optimization_Application/Filtering/Explicit_Vertex_Morphing.md new file mode 100644 index 000000000000..a6d52432ade5 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Filtering/Explicit_Vertex_Morphing.md @@ -0,0 +1,143 @@ +--- +title: Explicit Vertex Morphing +keywords: +tags: [explicit, vertex morphing, filtering, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +Explicit Vertex morphing (here onwards called as vertex morphing) is a discrete filtering method to regularize optimization problem. Non-smooth discrete gradient field is a common challenge in optimization problems which makes design updates noisy and non-applicable for numerical model, for instance, bad elements which eventually result in failure in primal and adjoint solution computation. Therefore it is crucial to apply a filtering technique to obtain a smooth design updates. An example of a noisy field is shown in figure 1. + +
+ +
+Figure 1: Noisy design field
+ +### Definition + +Figure 2 illustrates the filtering methodology applied in vertex morphing. Control field (i.e. sensitivity field) is demonstrated by $$S\left(\xi\right)$$. Filtering domain is identified by the used $$r$$ filter radii for each mesh coordinate. Then a filtering function of $$A\left(\xi-\xi_0\right)$$ is applied on the filtering domain to obtain smoothened and filtered design control field of $$z\left(\xi_o\right)$$ as illustrated in the figure. + ++ +
+Figure 2: Vertex morphing filtering
+ +Following equation is used to obtain the final filtered design control field. + +$$ z\left(x_0\right) = \int_{x_0-r}^{x_0+r} A\left(x, x_0, r\right)s\left(x\right) d\Gamma $$
+ +Figure 2 illustrates obtained filtered and smoothened design field of the noist design field illustrated in figure 1. + ++ +
+Figure 2: Filtered design field
+ +It is important to note that the variability of the resulting shape is characterized by the density of the design grid used to discretize the physical field $$s$$. The filter helps to control the continuity properties of the resulting shape. The filter does not affect the global and local solutions and leaves them unchanged. Typically, of course, in the case of non-convex problems different local solutions are found for different filters as they modify the descent directions. The physical space and its variety of alternative local optima are easily explored with repeated optimization and varied filters. + +### Effect of filter radii + +Higher filter radii (i.e. $$r$$) results in smoothened design field over a circular area in 2D and a spherical area in 3D with radius $$r$$. It may loose the local effect which are significant in obtaining design field which is capable of optimizing the given objective(s). This is illustrated in figure 3. In there, green plot illustrates the noisy design field in physical space, blue plot illustrates filtered design field in control space with $$r=4$$ and red plots illustrate filtered design fields with $$r=6$$ (left) and $$r=16$$ (right). + ++ +
+Figure 3: Filter radii effect on smoothened design field
+ +### Filter functions + +Following is a list of supported filter functions and their definitions. + +#### Gaussian filter function + +$$ A\left(\mathbf{x},\mathbf{x_0},r\right) = \max\left\lbrace 0.0, e^{\frac{-9\left|\mathbf{x}-\mathbf{x_0}\right|^2}{2r^2}}\right\rbrace$$
+ +#### Linear filter function +$$ A\left(x,x_0,r\right) = \max\left\lbrace 0.0, \frac{r-\left|\mathbf{x}-\mathbf{x_0}\right|}{r}\right\rbrace$$
+ +#### Constant filter function +$$ A\left(x,x_0,r\right) = 1.0$$
+ +#### Cosine filter function +$$ A\left(x,x_0,r\right) = \max\left\lbrace 0.0, 1-0.5\left(1-\cos\left(\pi\frac{\left|\mathbf{x}-\mathbf{x_0}\right|}{r}\right)\right)\right\rbrace$$
+ + +#### Quartic filter function +$$ A\left(x,x_0,r\right) = \max\left\lbrace 0.0, \left(\frac{\left|\mathbf{x}-\mathbf{x_0}\right|-r}{r}\right)^4\right\rbrace$$
+ +#### Area weighted sum integration method + +This method modifies chosen ``filter_function_type`` based on the nodal area averaging methodology. $$B\left(x, x_0, r\right)$$ is the nodal area of the neighbour node at $$x$$ position, $$N$$ is the number of neighbour nodes. + +$$ A\left(x,x_0,r\right) = A\left(x,x_0,r\right)\times \frac{B\left(x, x_0, r\right)}{\sum_{n=1}^{N}\left[B\left(x, x_0, r\right)\right]}$$
+ +## Damping + +An optimized design is obtained by changing the design variables in the opposite direction of the objective gradient (if a minimization problem is considered). Then the next question is, what if the user wants to retain the initial design in some parts of the design surface (i.e. damping regions as in the left half of the line segment in figure 4.). The most simplistic way to achieve this would be to disregard the gradient information on those regions (refer figure 5). The main issue with this approach is, it creates steep gradients between these damped and undamped regions making the obtained optimized design un-natural and with a poor quality to perform **FEM** analysis afterwards. Therefore, to overcome this problem, damping is used. Damping uses smooth functional to dampen the gradient information in the damped regions such that there does not exist any steep gradients between damped and undamped regions (refer figure 6). ++ +
+Figure 4: Physical space gradients along the line left half to be restricted.)
+ ++ +
+Figure 5: Sensitivities along the line when damped region sensitivities are set to zero (left half to be restricted.)
+ ++ +
+Figure 6: Gradients along the line when damped region is damped using a damping methodology. (left half to be restricted.)
+ +### Damping functions + +Following damping functions are supported: + +#### Gaussian filter function + +$$ A\left(\mathbf{x},\mathbf{x_0},r\right) = \max\left\lbrace 0.0, e^{\frac{-9\left|\mathbf{x}-\mathbf{x_0}\right|^2}{2r^2}}\right\rbrace$$
+ +#### Linear filter function +$$ A\left(x,x_0,r\right) = \max\left\lbrace 0.0, \frac{r-\left|\mathbf{x}-\mathbf{x_0}\right|}{r}\right\rbrace$$
+ +#### Constant filter function +$$ A\left(x,x_0,r\right) = 1.0$$
+ +#### Cosine filter function +$$ A\left(x,x_0,r\right) = \max\left\lbrace 0.0, 1-0.5\left(1-\cos\left(\pi\frac{\left|\mathbf{x}-\mathbf{x_0}\right|}{r}\right)\right)\right\rbrace$$
+ + +#### Quartic filter function +$$ A\left(x,x_0,r\right) = \max\left\lbrace 0.0, \left(\frac{\left|\mathbf{x}-\mathbf{x_0}\right|-r}{r}\right)^4\right\rbrace$$
+ +## Vertices for different containers +This vertex morphing and damping are used to compute vertex morphed and constrained gradients of objectives and constraints. The vertex morphing and damping requires always a vertices to compute the smoothen control field in control space. +1. In the case physical field is in the ```Kratos::NodesContainerType```, then it uses nodal locations as the vertices. +2. In the case physical field is in the ```Kratos::ConditionsContainerType```, then it uses conditions' underlying geometry's center as the vertices. +3. In the case physical field is in the ```Kratos::ElementsContainerType```, then it uses elements' underlying geometry's center as the vertices. + +## Damping methodology + +Damping factors (i.e. $$\beta_{i, damp}$$) are computed for each $$i^{th}$$ vertex in the damping regions as follows. First neighbours of each vertex in the damping region is found using a KDTree search. +$$ \beta_{i, damp} = \min_{x_j \in \Omega_{i, neighbours}} 1.0 - A(x_i, x_j, r) $$
+ +Thereafter, the gradient of the vertex is multiplied by the damping factor to compute the damped sensitivities as shown in the following equation: +$$ \left(\frac{dh}{d\underline{s}}\right)_{i, damped} = \beta_{i, damp}\left(\frac{dh}{d\underline{s}}\right)_i $$
+ +## Vertex morphing methodology + +Then for each vertex's (i.e. $$i^{th}$$) neigbhour vertices (i.e. $$j^{th}$$) the weights are computed using filter functions mentioned above (i.e. $$A_{ij}$$). Thereafter, the vertex morphed gradients for each gradient is computed as given in the following equation. + +$$ \left(\frac{df}{d\underline{s}}\right)_{i, morphed} = \frac{1}{\sum_{j=1}^N A_{ij}}\sum_{j=1}^{N} A_{ij}\left(\frac{df}{d\underline{s}}\right)_j$$
+ +## References +TODO: + + +## Source files +* [Doxygen](TODO) TODO +* [applications/OptimizationApplication/custom_utilities/filtering/filter_function.h](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/custom_utilities/filtering/filter_function.h) +* [applications/OptimizationApplication/custom_utilities/filtering/damping_function.h](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/custom_utilities/filtering/damping_function.h) +* [applications/OptimizationApplication/custom_utilities/filtering/explicit_filter.h](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/custom_utilities/filtering/explicit_filter.h) diff --git a/docs/pages/Applications/Optimization_Application/Filtering/Overview.md b/docs/pages/Applications/Optimization_Application/Filtering/Overview.md new file mode 100644 index 000000000000..7e33bac5441a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Filtering/Overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +keywords: +tags: [Overview.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Filtering/menu_info.json b/docs/pages/Applications/Optimization_Application/Filtering/menu_info.json new file mode 100644 index 000000000000..0cc207564821 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Filtering/menu_info.json @@ -0,0 +1,5 @@ +{ + "custom_entries": [ + "Overview.md" + ] +} \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/General/Algorithm.md b/docs/pages/Applications/Optimization_Application/General/Algorithm.md new file mode 100644 index 000000000000..d5627ec1baee --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Algorithm.md @@ -0,0 +1,43 @@ +--- +title: Algorithm +keywords: +tags: [algorithm, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +Figure 1 illustrates how an algorithm operates when ```OptimizationAnalysis``` executes ```Algorithm::Solve``` method. Overview of the existing algorithms can be found [here](../Algorithms/Overview.html). + ++ +
+Figure 1: Algorithm
+ +## Working space. + +As illustrated in the Figure 1, ```Algorithm``` purely works in the control space. Hence, all the inputs to the ```Algorithm``` should be in the control space. Therefore, all the outputs from it also will be in the control space. + +## Supporting components + +When an ```Algorithm``` is constructed by the ```OptimizationAnalysis```, +1. It will create the ```MasterControl``` which links all the ```Control```s used by the ```Algorithm```. +2. It will create all the necessary ```ResponseRoutine```s for the algorithm. It will not create any ```ResponseFunction```s, it will merely link a ```ResponseRoutine``` with a ```ResponseFunction```. +3. Thereafter, it will create all the other necessary components. + +## Data flow and work flow + +```Algorithm``` is developed basically to perform minimization. Therefore, it is the duty of the ```ResponseRoutine``` to standardize the objective and constraint values (i.e. $$\tilde{J}_1$$ and $$\tilde{J}_2$$ and the gradients (i.e. $$\frac{d\tilde{J}_1}{d\underline{\hat{\phi}}}$$, $$\frac{d\tilde{J}_2}{d\underline{\hat{\phi}}}$$) accordingly and send it to the algorithm which will be based on physical space response values (i.e. $$J_1$$, $$J_2$$) and their gradients (i.e. $$\frac{dJ_1}{d\underline{\phi}}$$, $$\frac{dJ_2}{d\underline{\phi}}$$). Then using the algorithm, it will compute the new design in control space (i.e. $$\hat{\underline{\phi}}$$) which needs to mapped to a design in the physical space (i.e. $$\underline{\phi}$$) by the ```ResponseRoutine```. ```ResponseRoutine``` then should update its design surfaces using ```MasterControl``` for the next iteration computations. + + +## Notes + +1. Since each algorithm is specific, they can have their own specific types of ```ResponseRoutine```s developed. Therefore, the methods being called by an ```Algorithm``` to ```ResponseRoutine``` may differ depending on the type of the ```Algorithm```. +2. ```OptimizationApplication``` supports linking with third party libraries for various algorithms. In that case, one needs to develop the ```Algorithm``` wrapper, ```ResponseRoutine``` and ```MasterControl``` for that third party library. + +## Source files +* [applications/OptimizationApplication/python_scripts/algorithms/algorithm.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/algorithms/algorithm.py) +* [Doxygen](TODO) TODO + + diff --git a/docs/pages/Applications/Optimization_Application/General/Collective_Expressions.md b/docs/pages/Applications/Optimization_Application/General/Collective_Expressions.md new file mode 100644 index 000000000000..885ac553716a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Collective_Expressions.md @@ -0,0 +1,43 @@ +--- +title: Collective Expressions +keywords: +tags: [collective expressions, expressions, optimization] +sidebar: optimization_application +summary: +--- + + +## Introduction + +```CollectiveExpressions``` as name suggests is a collection of ```NodalExpression``` and/or ```ConditionExpression``` and/or ```ElementExpression```. You can assume the ```CollectiveExpression``` as a flat vector flattening all the ```Expressions``` it hold. It also allows doing all the arithmetic and other operations which are defined for ```Expressions```. Even though they appear as a flat double vector, A ```CollectiveExpression``` can easily return the underlying ```Expression```s if required. + +## Adding and removing ```Expression```s and retrieving expressions. + +Following code snippet illustrates how to add and remove ```Expression```s to ```CollectiveExpression``` +```python +import KratosMultiphysics as Kratos +import KratosMultiphysics.OptimizationApplication as KratosOA + +model = Kratos.Model() +model_part = model.CreateModelPart("test") + +nodal_expression = Kratos.Expression.NodalExpression(model_part) +cond_expression = Kratos.Expression.ConditionExpression(model_part) + +collective_expression = KratosOA.CollectiveExpression() + +# adds a nodal expression and condition expression +collective_expression.Add(nodal_expression) +collective_expression.Add(cond_expression) + +# retrieves expressions in the order they were added +for exp in collective_expression.GetContainerExpressions(): + print(exp) + +# clears all the expressions +collective_expression.Clear() +``` + +## Source files +* [Doxygen](TODO) TODO +* [applications/OptimizationApplication/tests/test_collective_expressions.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/tests/test_collective_expressions.py) diff --git a/docs/pages/Applications/Optimization_Application/General/Control.md b/docs/pages/Applications/Optimization_Application/General/Control.md new file mode 100644 index 000000000000..094c7d6d296c --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Control.md @@ -0,0 +1,34 @@ +--- +title: Control +keywords: +tags: [control, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +```Control``` is used to regularize the design variables updates, which are given by the ```Algorithm``` as illustrated in Figure 1. It also updates the properties of the ```model_part```. This is also used to transform data between physical and control spaces. ++ +
+Figure 1: Control data flow
+ +## Working space + +As explained above ```Control``` will work in the control space and physical space. + +## Data flow and work flow + +```Control``` is responsible for updating the ```model_part```and its properties (i.e. mesh, domain values) with the new design given by the ```Algorithm```. First it will map the control space design (i.e. $$\underline{\hat{\phi}}$$) to physical space (i.e. $$\underline{\phi}$$) using the ```Filtering```. Then these physical space values are used to update the mesh or the domain values. + +```Control``` is also responsible for mapping physical space gradients (i.e. $$\frac{dJ_1}{d\underline{\phi}}$$) to control space (i.e. $$\frac{dJ_1}{d\underline{\hat{\phi}}}$$) using the ```Filtering``` method as illustrated in the Figure 1. + +## Notes + +1. A control should only work in one domain (or ```Kratos::ModelPart```). If more than one domain is required control (or ```Kratos::ModelPart```) then, they should made to one domain using union utilities. + +## Source files +* [applications/OptimizationApplication/python_scripts/controls/control.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/controls/control.py) +* [Doxygen](TODO) TODO + diff --git a/docs/pages/Applications/Optimization_Application/General/Execution_Policy.md b/docs/pages/Applications/Optimization_Application/General/Execution_Policy.md new file mode 100644 index 000000000000..7cfd61bf9e05 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Execution_Policy.md @@ -0,0 +1,25 @@ +--- +title: Execution Policy +keywords: +tags: [execution policy, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +Execution policies are used to execute an analysis which will be used to compute response values +and/or gradients. Overview of available ```ExecutionPolicy```s can be found [here](../Execution_Policies/Overview.html). + +These analysis may be: +* Kratos static analysis +* Kratos dynamic analysis +* External analysis + +Depending on the analysis, you may have to develop your won ```ExecutionPolicy``` to be used with optimization analysis. + +All the information about new design updates are passed via ```Kratos::ModelPart```, hence no additional information will be passed to this except for ```OptimizationProblem``` data container. + +## Source files +* [applications/OptimizationApplication/python_scripts/execution_policies/execution_policy.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/execution_policies/execution_policy.py) +* [Doxygen](TODO) TODO diff --git a/docs/pages/Applications/Optimization_Application/General/Master_Control.md b/docs/pages/Applications/Optimization_Application/General/Master_Control.md new file mode 100644 index 000000000000..c1caf596a019 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Master_Control.md @@ -0,0 +1,38 @@ +--- +title: Master Control +keywords: +tags: [master control, control, optimization] +sidebar: optimization_application +summary: +--- +## Introduction + +```MasterControl``` is a collection of ```Control```s used by an ```Algorithm```. It is owned by ```Algorithm``` and shared among all the ```ResponseRoutine```s used by that ```Algorithm```. It does not own any of the ```Control```s, it just links to appropriate ```Control```s found in ```OptimizationProblem```. Thereafter, ```MasterControl``` can govern over these ```Control```s. + +## Working space + +As explained above ```MasterControl``` will work in the control space and physical space. + +## Data flow and work flow + +It is responsible for converting control space designs (i.e. $$\underline{\hat{\phi}}$$) to physical space designs (i.e. $$\underline{\phi}$$). This is done via the ```MasterControl::Update``` method as illustrated in Figure 1. It disassemble the control domain ```CollectiveExpression``` (i.e. $$\underline{\hat{\phi}}$$) passed to the master control, to smaller ```ContainerExpressions``` control domains (i.e. $$\underline{\hat{\phi}}_1$$, $$\underline{\hat{\phi}}_2$$) and then use respective ```Control``` to transform to smaller physical domains ```ContainerExpressions``` (i.e. $$\underline{\phi}_1$$, $$\underline{\phi}_1$$). Then another ```CollectiveExpression``` is built aggregating all the smaller physical domains to a larger physical domain (i.e $$\underline{\phi}$$) to get the final physical domain. + ++ +
+Figure 1: Update method of Master Control
+ +It is also responsible for converting physical domain gradients given in a ```CollectiveExpression``` (i.e. $$\frac{dJ_1}{d\underline{\phi}}$$) to the control domain gradients given by again a ```CollectiveExpression``` (i.e. $$\frac{dJ_1}{d\underline{\hat{\phi}}}$$) by calling ```MasterControl::MapGradient``` as illustrated in Figure 2. There, the passed ```CollectiveExpression``` is disassembled to smaller physical domain ```ContainerExpressions``` (i.e. $$\frac{dJ_1}{d\underline{\phi}_1}$$, $$\frac{dJ_1}{d\underline{\phi}_2}$$). Thereafter, these are passed through their respective ```Control```s to convert to control domain ```ContainerExpressions``` (i.e. $$\frac{dJ_1}{d\underline{\hat{\phi}}_1}$$, $$\frac{dJ_1}{d\underline{\hat{\phi}}_2}$$). Thereafter, final gradient is computed as a ```CollectiveExpression``` by aggregating all the control domain gradients (i.e. $$\frac{dJ_1}{d\underline{\hat{\phi}}}$$). ++ +
+Figure 2: MapGradient method of Master Control
+ +## Notes + +1. ```MasterControl``` does not own any of the ```Control```s, but once assigned, these ```Control```s are governed by ```MasterControl```. +2. There should be only one ```MasterControl``` for an optimization analysis. + +## Source files +* [applications/OptimizationApplication/python_scripts/controls/master_control.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/controls/master_control.py) +* [Doxygen](TODO) TODO \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/General/Optimization_Problem.md b/docs/pages/Applications/Optimization_Application/General/Optimization_Problem.md new file mode 100644 index 000000000000..ad932ae9bb0a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Optimization_Problem.md @@ -0,0 +1,77 @@ +--- +title: Optimization Problem +keywords: +tags: [optimization problem, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +The ```OptimizationProblem``` is a data container which is used to pass information between components used in the ```OptimizationAnalysis```. There is only one ```OptimizationProblem``` per ```OptimizationAnalysis``` + +## Data storage + +It has two types of data containers. +1. Static data storage. +2. Historical data storage. +3. Component storage. + +### Static data storage + +Static data storage can only have one value for the whole optimization analysis. Overwriting is not allowed. If required to overwrite, then one should first delete the exiting data, and then write new data. This uses an instance of [BufferedDict](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/utilities/buffered_dict.py). + +### Historical data storage + +Historical data storage can have different values for different iterations of the whole optimization analysis. Overwriting is not allowed by default (it can be specified). This uses an instance of [BufferedDict](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/utilities/buffered_dict.py). + +### Component storage + +```OptimizationProblem``` will also store all the instances of ```ExecutionPolicy```s, ```ResponseFunction```s and ```Control```s. Each of the component can have its own data storage within the ```OptimizationProblem```. + +The component specific storage can be accessed by the use of [```ComponentDataView```](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/utilities/component_data_view.py). Following python code snippet illustrates a use case +```python +import KratosMultiphysics as Kratos +from KratosMultiphysics.OptimizationApplication.utilities.optimization_problem import OptimizationProblem +from KratosMultiphysics.OptimizationApplication.execution_policies.execution_policy_decorator import ExecutionPolicyDecorator +from KratosMultiphysics.OptimizationApplication.utilities.component_data_view import ComponentDataView + +model = Kratos.Model() + +echo_level = 1 +opt_problem = OptimizationProblem(echo_level) + +parameters = Kratos.Parameters("""{ + "name" : "test", + "type" : "independent_analysis_execution_policy", + "settings": { + "analysis_type" : "orchestrators.SequentialOrchestrator", + "analysis_settings": { + "orchestrator": { + "settings": { + "stage_checkpoints": false + } + }, + "stages":[] + } + } +}""") +execution_policy = ExecutionPolicyDecorator(model, parameters, opt_problem) + +## add the component to opt problem +opt_problem.AddComponent(execution_policy) + +# retrieve the component specific data container from opt_problem +data_view = ComponentDataView(execution_policy, opt_problem) + +## set buffer to store data for 2 iterations in memory +data_view.SetDataBuffer(2) + +## get the historical BufferedDict +historical_data = data_view.GetBufferedData() +print(historical_data) + +## get the static BufferedDict +static_data = data_view.GetUnBufferedData() +print(static_data) +``` \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/General/Overview.md b/docs/pages/Applications/Optimization_Application/General/Overview.md new file mode 100644 index 000000000000..7e33bac5441a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +keywords: +tags: [Overview.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/General/Response_Function.md b/docs/pages/Applications/Optimization_Application/General/Response_Function.md new file mode 100644 index 000000000000..094023700450 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Response_Function.md @@ -0,0 +1,21 @@ +--- +title: Response Function +keywords: +tags: [response function, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +Response function is used to compute the objective/constraint values and their respective gradients. It purely lives within the physical space, hence all the computed values will be in the physical space. + +## Notes +* It will have methods to compute gradients for variables as requested. If a variable is requested, and the gradient computation is not implemented, then it should throw an error. +* ResponseFunction should implement all the variables it depends on. If something is hard to be implemented at the moment of the ```ResponseFunction``` development, then put that variable and throw and error saying not yet implemented. +* ```ResponseFunction``` may or may not use ```ExecutionPolicies```. If it required to have an primal analysis, it must use ```ExecutionPolicy``` to obtain the primal analysis. In this case ```ResponseFunction```. In this case, the ```ResponseFunction::GetEvaluatedModelPart``` will be the domain on which the response is evaluated on and ```ResponseFunction::GetAnalysisModelPart``` will be the domain on which the adjoints may be computed [If no adjoints are used, this method returns None]. + +## Source files +* [applications/OptimizationApplication/python_scripts/responses/response_function.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/responses/response_function.py) +* [Doxygen](TODO) TODO + diff --git a/docs/pages/Applications/Optimization_Application/General/Response_Routine.md b/docs/pages/Applications/Optimization_Application/General/Response_Routine.md new file mode 100644 index 000000000000..9fa0f0681461 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Response_Routine.md @@ -0,0 +1,37 @@ +--- +title: Response Routine +keywords: +tags: [response routine, response function, optimization] +sidebar: optimization_application +summary: +--- +## Introduction + +Figure 1 illustrates how a ```ResponseRoutine``` operates. + ++ +
+Figure 1: Response routine
+ +## Working space. + +As illustrated in the Figure 1, ```ResponseRoutine``` will work in the control space and physical space. It uses ```MasterControl``` to transform control space to physical space and wise versa. + +## Supporting components + +Each ```ResponseRoutine``` will not create its own ```ResponseFunction```s. It should use ```ResponseFunction```s given by the ```OptimizationProblem``` data container. Once assigned, ```ResponseRoutine``` has the authority on how to control the ```ResponseFunction``` (such as calling methods for ```ResponseFunction```). + +**```ResponseRoutine``` does not own the ```MasterControl```. It should merely use the shared ```MasterControl```.** + +## Data flow and work flow + +```ResponseRoutine``` will receive new design in the control space (i.e. $$\underline{\hat{\phi}}$$). Then it should use the ```MasterControl``` to convert the new design to physical space (i.e. $$\underline{\phi}$$) and update the mesh. Thereafter, it will request the new objective/constraint values (i.e. $$J_1$$) and their gradients in the physical space (i.e. $$\frac{dJ_1}{d\underline{\phi}}$$). Thereafter, it will convert the physical space gradients to control space gradients (i.e. $$\frac{dJ_1}{d\underline{\hat{\phi}}}$$). Finally it will return the standardized objective/constraint values (i.e. $$\tilde{J}_1$$) and their gradients (i.e. $$\frac{d\tilde{J}_1}{d\underline{\hat{\phi}}}$$) + +## Notes +* One of the major duties of the ```ResponseRoutine``` is to request the physical control variables +used in the ```MasterControl``` for each domain, and find out what gradients should be requested from the ```ResponseFunction```s. + +## Source files +* [applications/OptimizationApplication/python_scripts/responses/response_routine.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/responses/response_routine.py) +* [Doxygen](TODO) TODO \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/General/Work_Flow.md b/docs/pages/Applications/Optimization_Application/General/Work_Flow.md new file mode 100644 index 000000000000..4cc228149c72 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/Work_Flow.md @@ -0,0 +1,218 @@ +--- +title: Work Flow +keywords: +tags: [optimization, work flow] +sidebar: optimization_application +summary: +--- + +## Introduction + +An optimization problem is run by calling ```OptimizationAnalysis::Run``` method. Following python code snippet illustrates how to run an optimization problem. +```python +import KratosMultiphysics as Kratos +from KratosMultiphysics.OptimizationApplication.optimization_analysis import OptimizationAnalysis + +# open the optimization parameters json file +with open("OptimizationParameters.json", "r") as params_file: + parameters = Kratos.Parameters(params_file.read()) + +# creates the Kratos::Model +model = Kratos.Model() + +# creates the OptimizationAnalysis +opt_analysis = OptimizationAnalysis(model, parameters) + +# run the optimization analysis +opt_analysis.Run() +``` + +Even though the ```OptimizationAnalysis``` is not derived from ```AnalysisStage```, it has a similar interface to replicate the methods in ```AnalysisStage```. Therefore, ```OptimizationAnalysis``` can also used in ```Ochestrator```. + +## Json settings +Following json snippet illustrates basic settings which can be found in a json settings file used by ```OptimizationAnalysis```. +```json +{ + "problem_data" : {}, + "model_parts" : [], + "analyses" : [], + "responses" : [], + "controls" : [], + "algorithm_settings": {}, + "processes" : { + "kratos_processes" : {}, + "optimization_data_processes": {} + } +} +``` + +### Problem data + +```problem_data``` section of the json settings can be used to add data to identify the optimization problem. The only mandatory sub-setting is ```echo_level```, which is used to indicate overall echo level to be used in the optimization analysis. Higher the value, more verbose the output. Following json-snippet illustrate an example use case. +```json +{ + "name" : "optimization_problem_name", + "echo_level": 1 +} +``` + +### Model parts + +```model_parts``` section of the json settings can be used to read/create meshes. This sections is **not a must** to be used in an optimization analysis. If a central place is required to read/create all the meshes which will be used in the optimization analysis, this can be used. Otherwise, the meshes can be read in their respective places making this section empty. Following code snippet illustrate an example use case of one single entry in the list. + +Following ```ModelPartController``` does not need to be within Kratos. You can write your own ```ModelPartController```, and put it within your working directory. If that is the case then, change ```module``` to blank. +```json +{ + "type": "mdpa_model_part_controller", // type of the ModelPartController + "module": "KratosMultiphysics.OptimizationApplication.model_part_controllers", // Where to find the ModelPartController + "settings": { // ModelPartController specific settings + "model_part_name": "Structure", + "domain_size": 3, + "input_filename": "mdpa_file_name" + } +} +``` + +### Analyses + +```analyses``` section is used to list all the analyses which will be used in the optimization analysis. These analyses can be any type of analysis from Kratos or from an external solver. Analyses are added using the ```ExecutionPolicy``` objects. In the case of an external solver, an ```ExecutionPolicy``` may be developed to use it within the ```OptimizationAnalysis```. ```ExecutionPolicy``` can also be custom and found in your working directory of the problem. In this case, ```module``` should be a blank string. + +**```name``` field should be a unique string entry for the whole optimization problem** + +Following json snippet illustrates one use case. +```json +{ + "name": "Structure_static", // Name of the analysis. needs to be unique. + "type": "kratos_analysis_execution_policy", // Type of the execution policy. + "module": "KratosMultiphysics.OptimizationApplication.execution_policies", // Where to find the ExecutionPolicy. + "settings": { // Execution policy specific settings. + "model_part_names": [ + "Structure" + ], + "analysis_module": "KratosMultiphysics.StructuralMechanicsApplication", + "analysis_type": "StructuralMechanicsAnalysis", + "analysis_settings": { + "@include_json": "PrimalParametersCase2A.json" + } + } +} +``` + +### Responses +```responses``` section is to list all the responses which will be used by the algorithm. All the objectives and constraints should be listed in here. As mentioned in other sections, custom responses can be defines as well and put in to the working directory. In that case the ```module``` should be a blank string. + +**```name``` field should be a unique string entry for the whole optimization problem** + +Following json-snippet illustrates an example use case. +```json +{ + "name": "mass", + "type": "mass_response_function", + "module": "KratosMultiphysics.OptimizationApplication.responses", + "settings": { + "evaluated_model_part_names": [ + "Structure" + ] + } +} +``` + +### Controls +```controls``` section is to list all of the controls to be used by the algorithm. + +**```name``` field should be a unique string entry for the whole optimization problem** + +Following code-snippet illustrates an example use case. +```json +{ + "name": "thickness_control", + "type": "thickness.shell_thickness_control", + "settings": { + "controlled_model_part_names": [ + "Structure.Parts_Shell_structure" + ], + "filter_settings": { + "type": "implicit", + "radius": 0.2, + "linear_solver_settings": { + "solver_type": "LinearSolversApplication.amgcl" + } + }, + "output_all_fields": false, + "beta_value": 25.0, + "initial_physical_thickness": 0.15, + "physical_thicknesses": [ + 0.1, + 0.2 + ] + } +} +``` + +### Algorithm settings + +```algorithm_settings``` section holds all the necessary information for algorithms such as which controls, which responses to be used, what type of convergence criteria, etc. + + +### Processes +```processes``` section is allowed to have two type of processes. One is, processes you find anywhere in Kratos which is not in hte OptimizationApplication. If these processes are required to be used in the optimization analysis to input or output data, then they should go in the ```kratos_processes```. + +There are some specific processes which are implemented in OptimizationApplication which requires not only ```Kratos::Model``` and ```Kratos::Parameters```, but also ```OptimizationProblem``` to construct an object. These processes needs to be included under ```optimization_data_processes```. + + +## Work flow + ++ +
+Figure 1: Overall execution flow
+ +Figure 1 illustrates the overall execution of an optimization problem. + +### Construction of components + +This step will construct all following components in the listed order. +1. ```OptimizationProblem``` data container. +2. [```ModelPartControllers```](#model-parts) +3. [```Analyses```](#analyses) +4. [```Controls```](#controls) +5. [```Responses```](#responses) +6. [```Algorithm```](#algorithm-settings) +7. [```Processes```](#processes) + +Each type of component will read its respective part of the json to create the component. + +### Initialization of components + +Initialization of components will be done in the following listed order. + +1. Fill in the model parts specified by [```ModelPartControllers```](#model-parts) by calling ```ModelPartController::ImportModelPart```. +2. Initialize ```ModelPartController``` by calling ```ModelPartController::Initialize``` +3. Initialize Processes. +4. Initialize ```Algorithm``` + +Initialization of ```ResponseFunction``` and ```Controls``` are done within the ```Algorithm::Initialize```. + +### Checking of components + +Checking of components will be done in the following listed order. + +1. Checks processes +2. Check ```Algorithm``` + +Checking of ```ResponseFunction``` and ```Controls``` are done within the ```Algorithm::Check```. + + +### Running optimization algorithm + +This step will call [```Algorithm::Solve```](Algorithm.html) method. + + +### Finalizing of components + +Finalization of components will be done in the following listed order. + +1. Initialize ```Algorithm```. +2. Initialize Processes. + +Finalization of ```ResponseFunction``` and ```Controls``` are done within the ```Algorithm::Finalize```. \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/General/menu_info.json b/docs/pages/Applications/Optimization_Application/General/menu_info.json new file mode 100644 index 000000000000..7ea0064469af --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/menu_info.json @@ -0,0 +1,14 @@ +{ + "custom_entries": [ + "Overview.md", + "Work_Flow.md", + "Algorithm.md", + "Response_Routine.md", + "Response_Function.md", + "Execution_Policy.md", + "Master_Control.md", + "Control.md", + "Collective_Expressions.md", + "Optimization_Problem.md" + ] +} \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/General/overall_execution.drawio b/docs/pages/Applications/Optimization_Application/General/overall_execution.drawio new file mode 100644 index 000000000000..749a4d87104f --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/General/overall_execution.drawio @@ -0,0 +1,51 @@ +$$ J = \frac{1}{2}\sum_{\forall \Omega_i \in \Omega} \underline{u}^T_i \mathbf{K}_i \underline{u}_i $$
+ +## Json settings +Following code snippet illustrates json settings used in this response function. +```json +{ + "name": "strain_energy", + "type": "linear_strain_energy_response_function", + "settings": { + "evaluated_model_part_names": [ + "Structure" + ], + "primal_analysis_name": "Structure_static", + "perturbation_size": 1e-8 + } +} +``` + +| Option | Allowed values | +| ------------- | ------------- | +| name | A unique string | +| type | "linear_strain_energy_response_function" | +| evaluated_model_part_names | List of model part names to compute strain energy | +| primal_analysis_name | Name of the analysis from the list of analysis to be used for strain energy computation | +| perturbation_size | Perturbation size to be used in the semi-analytic method | + +## Source files + +* [applications/OptimizationApplication/python_scripts/responses/linear_strain_energy_response_function.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/responses/linear_strain_energy_response_function.py) +* [Doxygen](doxygen) TODO diff --git a/docs/pages/Applications/Optimization_Application/Responses/Mass_Response_Function.md b/docs/pages/Applications/Optimization_Application/Responses/Mass_Response_Function.md new file mode 100644 index 000000000000..48a5ee95e81b --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Responses/Mass_Response_Function.md @@ -0,0 +1,41 @@ +--- +title: Mass Response Function +keywords: +tags: [mass, response function, optimization] +sidebar: optimization_application +summary: +--- + +## Introduction + +This response function computes the mass of the given list of model parts. + +## Formulation + +Following formulation is used. +$$ J = \sum_{\forall \Omega_i \in \Omega} m_i $$
+ +## Json settings +Following code snippet illustrates json settings used in this response function. +```json +{ + "name": "mass", + "type": "mass_response_function", + "settings": { + "evaluated_model_part_names": [ + "Structure" + ] + } +} +``` + +| Option | Allowed values | +| ------------- | ------------- | +| name | A unique string | +| type | "mass_response_function" | +| evaluated_model_part_names | List of model part names to compute mass | + +## Source files + +* [applications/OptimizationApplication/python_scripts/responses/mass_response_function.py](https://github.com/KratosMultiphysics/Kratos/blob/master/applications/OptimizationApplication/python_scripts/responses/mass_response_function.py) +* [Doxygen](doxygen) TODO \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/Responses/Overview.md b/docs/pages/Applications/Optimization_Application/Responses/Overview.md new file mode 100644 index 000000000000..7e33bac5441a --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Responses/Overview.md @@ -0,0 +1,7 @@ +--- +title: Overview +keywords: +tags: [Overview.md] +sidebar: optimization_application +summary: +--- diff --git a/docs/pages/Applications/Optimization_Application/Responses/menu_info.json b/docs/pages/Applications/Optimization_Application/Responses/menu_info.json new file mode 100644 index 000000000000..0cc207564821 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/Responses/menu_info.json @@ -0,0 +1,5 @@ +{ + "custom_entries": [ + "Overview.md" + ] +} \ No newline at end of file diff --git a/docs/pages/Applications/Optimization_Application/menu_info.json b/docs/pages/Applications/Optimization_Application/menu_info.json new file mode 100644 index 000000000000..ff73ba4b4326 --- /dev/null +++ b/docs/pages/Applications/Optimization_Application/menu_info.json @@ -0,0 +1,17 @@ +{ + "side_bar_name": "optimization_application", + "landing_page": "General/Overview.md", + "additional_menu_options": { + "product": "Optimization Application", + "title": "sidebar" + }, + "custom_entries": [ + "General", + "Algorithms", + "Responses", + "Controls", + "Filtering", + "Model_Part_Controllers", + "Processes" + ] +} \ No newline at end of file