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
991 stars 244 forks source link

[GeoMechanicsApplication] Include variable prediction in all newmark schemes #11957

Open rfaasse opened 6 months ago

rfaasse commented 6 months ago

As a Kratos user, I would like to have prediction methods in the newmark schemes, such that convergence is quicker when using these schemes.

Successor item: [GeoMechanicsApplication] Include variable prediction in the backward euler schemes

Background During the scheme refactoring, it was found that the dynamic newmark scheme has an override for the 'Predict' method. This method predicts the values of certain variables before doing a solution step, to improve the rate of convergence.

However, there are two things missing here:

  1. The Predict method could move to the generalized newmark baseclass for all newmark schemes, such that all of them profit from the predictions.
  2. The predictions are currently only done for the displacements and rotations (in other words the second order vector variables). For the first order scalar variables (such as water pressure or temperature), the prediction is missing and should be added to speed up pressure/temperature convergence

Acceptance Criteria Given a user specifies any newmark scheme When a simulation is run Then the first and second order variables are predicted

Note: It might be interesting to document a few cases here and compare run times with/without predicts.

rfaasse commented 6 months ago

After a brief look at the code with @WPK4FEM, it seems that the first order prediction could be done by adding the following piece of code to the PredictVariablesForNode function (it is a simple first order Taylor expansion around the variable value).

        for (const auto& r_first_order_scalar_variable : this->GetFirstOrderScalarVariables())
        {
            if (!rNode.SolutionStepsDataHas(r_first_order_scalar_variable.instance) || rNode.IsFixed(r_first_order_scalar_variable.instance))
                continue;

            const double previous_variable =
                rNode.FastGetSolutionStepValue(r_first_order_scalar_variable.instance, 1);
            const double previous_first_time_derivative =
                rNode.FastGetSolutionStepValue(r_first_order_scalar_variable.first_time_derivative, 1);

            rNode.FastGetSolutionStepValue(r_first_order_scalar_variable.instance) =
                previous_variable + this->GetDeltaTime() * previous_first_time_derivative;
        }
rfaasse commented 6 months ago

For the Predict of the instance of the second order variables (e.g. displacement/rotation), we probably need to change the formulation from:

rNode.FastGetSolutionStepValue(instance_component) =
    previous_variable + this->GetDeltaTime() * previous_first_time_derivative +
    0.5 * this->GetDeltaTime() * this->GetDeltaTime() * previous_second_time_derivative;

to:

rNode.FastGetSolutionStepValue(instance_component) =
    previous_variable + this->GetDeltaTime() * previous_first_time_derivative +
    (0.5-this->GetBeta()) * this->GetDeltaTime() * this->GetDeltaTime() * previous_second_time_derivative;

See also https://ethz.ch/content/dam/ethz/special-interest/baug/ibk/structural-mechanics-dam/education/femII/presentation_05_dynamics_v3.pdf