KratosMultiphysics / Kratos

Kratos Multiphysics (A.K.A Kratos) is a framework for building parallel multi-disciplinary simulation software. Modularity, extensibility and HPC are the main objectives. Kratos has BSD license and is written in C++ with extensive Python interface.
https://kratosmultiphysics.github.io/Kratos/
Other
1.01k stars 244 forks source link

[Core] ResponseFunction #2337

Closed msandre closed 6 years ago

msandre commented 6 years ago

Several months ago we defined the response function interface (see https://github.com/KratosMultiphysics/Kratos/wiki/Adjoint-API#response-functions). Now we have at least two (rather large) branches which use this (for @KratosMultiphysics/structural-mechanics in #1804 and from the fluid side in https://github.com/KratosMultiphysics/Kratos/tree/migrate-response-function-to-core).

Below I've started a list of issues to be resolved so that we can bring these developments closer together and ease merging them into the master. As a first step I propose we add a ResponseFunction base class as the response function interface to the core (as a separate PR) and update our branches to use this. For example, this will help us to use the structural response functions with the adjoint solvers in the other branch.

MyScheme::Initialize(ModelPart& rModelPart)
{
    // mResponseFunction.Initialize(); // Does ResponseFunction initialize with rModelPart???
    mResponseFunction.Initialized(rModelPart); // Here it is consistent with the scheme's model part.
}
RiccardoRossi commented 6 years ago

Hi @msandre a quick question:

msandre commented 6 years ago

Hi @RiccardoRossi thanks for the comments.

The rationale was mainly the proximity to the schemes in the core (the dependency points from adjoint scheme to response function). In this sense, the dependency is local to solving_strategies directory.

msandre commented 6 years ago

I am pasting the results of the first iteration (bold still needs to be resolved):

Q: Where should the ResponseFunction path be located? A: In kratos/solving_strategies/response_functions. Possible scheme dependencies on response function are then contained in kratos/solving_strategies.

Q: What should be implemented in the ResponseFunction base class? A: General assembly of sensitivities from adjoint and partial derivatives. Only the functions that depend on the type of response function, are implemented in the derived class. These include CalculateValue() and CalculatePartialSensitivity(). The base implementation will be based on AdjointStructuralResponseFunction.

Q: Where should we call UpdateSensitivities()? At first we thought in FinalizeSolutionStep() since a scheme is not always present to call UpdateSensitivities. Then interpreting @RiccardoRossi's comment with @jcotela and @sunethwarna, we thought there would be a potential problem with complicated analyses (such as plasticity) where the order in which different processes and strategies execute FinalizeSolutionStep() could cause incorrect program behavior. The new proposal is to call UpdateSensitivities() in the python level from the python solver (which is now also the owner of the response function) separately from the usual FinalizeSolutionStep block.

Q: Should the ModelPart be passed as a function parameter or accessed as a member variable in the ResponseFunction? A: Member variable. This way the model part does not have to accompany the response function and the response function can avoid performing checks on the validity of the model part for every function call.

Q: Should CalculateValue() be pure virtual. A: Yes. It is safer than having a meaningless default return value. It should always be defined.

Q: NEW How should we name the optimizer's response function python interface and the response function in c++ The c++ response function is responsible for defining the drag, strain energy, etc. and their partial sensitivities. The optimizer's response function python interface is used to update the solution (e.g., solve the primal/adjoint solutions) and return the new response function value or sensitivities. We are proposing to handle the python class as a stage. Thus, it would have a name like OptimizationStage or ResponseStage and share the interface of a stage.

There is enough convergence here that we can add the c++ response function to the core as long as there are no further concerns and we can agree to keep the name ResponseFunction.

armingeiser commented 6 years ago

Q: Where should we call UpdateSensitivities()? I think calling it directly from python is a nice idea to have full flexibility. It will also work for our special case of the strain energy response. @MFusseder any objections?

Q: NEW How should we name the optimizer's response function python interface and the response function in c++ Thinking about the response python interfaces as a stage (that itself has primal and adjoint analysis stage) is what I also had in mind when i created them. So in the optimization we would have a list of ResponseStages ( i don't like OptimizationStage). @dbaumgaertner what do you think?

dbaumgaertner commented 6 years ago

I would also call it ResponseStage or ResponseFunctionStage. OptimizationStage is clearly the wrong name here as the actual optimization has a whole lot more things around the actual response function.

msandre commented 6 years ago

Ok, I think we can move forward with the response function and defer decisions about the stage until later. I will close this issue then. Thanks.