Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[GeoMechanicsApplication] Geo/time step loop #11677

Merged
merged 26 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8c1fa6a
WPK first attempt time loop executor
WPK4FEM Sep 29, 2023
294c2ff
also complementary to WPK first attempt time loop executor
WPK4FEM Sep 29, 2023
bdcadbc
Removed yet unused things. Added first unit test: TimeLoopReturnsPerf…
WPK4FEM Oct 9, 2023
9f47ad5
Added a StrategyWrapper with an always converging solver strategy for…
WPK4FEM Oct 9, 2023
0bfebf1
Added constructor with convergence argument to DummySolverStrategy. A…
WPK4FEM Oct 9, 2023
afb17c5
Give time loop executor a TimeStepEndState to start from. Keep track …
WPK4FEM Oct 9, 2023
81000b3
Use the time step executor. ( only one available so default construct…
WPK4FEM Oct 10, 2023
767fb7c
Keep track of used number of cycles. Added tests using a test time in…
WPK4FEM Oct 10, 2023
5476cbd
Removed a few unused dummy classes for testing
avdg81 Oct 10, 2023
e74ad60
Test the time loop executor using a prescribed time incrementor
avdg81 Oct 10, 2023
3f491e8
Added the strategy wrapper as a member of the time loop executor
avdg81 Oct 10, 2023
712c6c0
When running the time loop, increment the step number
avdg81 Oct 10, 2023
79147cd
Added test for and implementation of CloneTimeStep, in the strategy w…
WPK4FEM Oct 11, 2023
916242f
Added method and tests for RestorePositionsAndDOFVectorToStartOfStep …
WPK4FEM Oct 11, 2023
9753302
SaveTotalDisplacementFieldAtStartOfStage and AccumulateTotalDisplacem…
WPK4FEM Oct 12, 2023
9ba7a26
OutputProcess implementation and unit test added to time_loop_executor.
WPK4FEM Oct 12, 2023
f98bb53
FinalizeSolutionStep should be called outside the cycle loop. This ch…
WPK4FEM Oct 12, 2023
19d600f
Small things from review by Richard adapted.
WPK4FEM Oct 12, 2023
90a341d
Pass on process observables from TimeLoopExecutor to TimeStepExecutor.
WPK4FEM Oct 12, 2023
46b2597
Less code repetition in test_time_loop_executor
WPK4FEM Oct 12, 2023
c071354
interface class for TimeLoopExecutor as requested in review by Richard.
WPK4FEM Oct 12, 2023
16eb498
merge from master
WPK4FEM Oct 12, 2023
b832147
forgotten interface.h
WPK4FEM Oct 12, 2023
588b0ed
Code smell remarks from SonarCloud almost all resolved
WPK4FEM Oct 13, 2023
dfcdffb
Implemented suggestions from review by Anne.
WPK4FEM Oct 13, 2023
e8d0b77
Last? SonarCloud code smell fixed
WPK4FEM Oct 13, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

#include "custom_workflow_factory.h"
#include "dgeosettlement.h"
#include "time_loop_executor.h"
#include "time_loop_executor.hpp"
WPK4FEM marked this conversation as resolved.
Show resolved Hide resolved

#include "custom_utilities/file_input_utility.h"
#include "custom_utilities/json_process_info_parser.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
//
#include "dgeosettlement.h"
#include "input_output/logger.h"
#include "time_loop_executor.h"
#include "time_loop_executor_interface.h"

#include "utilities/variable_utils.h"

Expand All @@ -30,10 +30,10 @@ namespace Kratos

KratosGeoSettlement::KratosGeoSettlement(std::unique_ptr<InputUtility> pInputUtility,
std::unique_ptr<ProcessInfoParser> pProcessInfoParser,
std::unique_ptr<TimeLoopExecutor> pTimeLoopExecutor) :
std::unique_ptr<TimeLoopExecutorInterface> pTimeLoopExecutorInterface) :
mpInputUtility{std::move(pInputUtility)},
mpProcessInfoParser{std::move(pProcessInfoParser)},
mpTimeLoopExecutor{std::move(pTimeLoopExecutor)}
mpTimeLoopExecutor{std::move(pTimeLoopExecutorInterface)}
{
KRATOS_INFO("KratosGeoSettlement") << "Setting up Kratos" << std::endl;
KRATOS_ERROR_IF_NOT(mpInputUtility) << "Invalid Input Utility";
Expand Down Expand Up @@ -127,9 +127,8 @@ int KratosGeoSettlement::RunStage(const std::filesystem::path& rWorki
std::vector<std::shared_ptr<Process>> processes = GetProcesses(project_parameters);
std::vector<std::weak_ptr<Process>> process_observables(processes.begin(), processes.end());

if (mpTimeLoopExecutor)
{
mpTimeLoopExecutor->SetProcessReferences(process_observables);
if (mpTimeLoopExecutor) {
mpTimeLoopExecutor->SetProcessObservables(process_observables);
}

FlushLoggingOutput(rLogCallback, logger_output, kratos_log_buffer);
Expand Down Expand Up @@ -205,8 +204,8 @@ LoggerOutput::Pointer KratosGeoSettlement::CreateLoggingOutput(std::stringstream
return logger_output;
}

void KratosGeoSettlement::FlushLoggingOutput(const std::function<void(const char*)>& rLogCallback,
LoggerOutput::Pointer pLoggerOutput,
void KratosGeoSettlement::FlushLoggingOutput(const std::function<void(const char*)>& rLogCallback,
LoggerOutput::Pointer pLoggerOutput,
const std::stringstream& rKratosLogBuffer) const
{
rLogCallback(rKratosLogBuffer.str().c_str());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ namespace Kratos
class ProcessFactory;
class InputUtility;
class ProcessInfoParser;
class TimeLoopExecutor;
WPK4FEM marked this conversation as resolved.
Show resolved Hide resolved
class Process;
class TimeLoopExecutorInterface;

class KRATOS_API(GEO_MECHANICS_APPLICATION) KratosGeoSettlement
{
public:
KratosGeoSettlement(std::unique_ptr<InputUtility> pInputUtility,
std::unique_ptr<ProcessInfoParser> pProcessInfoParser,
std::unique_ptr<TimeLoopExecutor> pTimeLoopExecutor);
std::unique_ptr<TimeLoopExecutorInterface> pTimeLoopExecutorInterface);

~KratosGeoSettlement();

Expand Down Expand Up @@ -64,7 +64,7 @@ class KRATOS_API(GEO_MECHANICS_APPLICATION) KratosGeoSettlement
std::unique_ptr<ProcessFactory> mProcessFactory = std::make_unique<ProcessFactory>();
std::unique_ptr<InputUtility> mpInputUtility;
std::unique_ptr<ProcessInfoParser> mpProcessInfoParser;
std::unique_ptr<TimeLoopExecutor> mpTimeLoopExecutor;
std::unique_ptr<TimeLoopExecutorInterface> mpTimeLoopExecutor;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,20 @@ namespace Kratos
public:
virtual ~StrategyWrapper() = default;

[[nodiscard]] virtual TimeStepEndState::ConvergenceState GetConvergenceState() = 0;
[[nodiscard]] virtual TimeStepEndState::ConvergenceState GetConvergenceState() const = 0;
[[nodiscard]] virtual std::size_t GetNumberOfIterations() const = 0;
[[nodiscard]] virtual double GetEndTime() const = 0;
virtual void SetEndTime(double EndTime) = 0;
[[nodiscard]] virtual double GetTimeIncrement() const = 0;
virtual void SetTimeIncrement(double TimeIncrement) = 0;
[[nodiscard]] virtual std::size_t GetStepNumber() const = 0;
virtual void IncrementStepNumber() = 0;
virtual void CloneTimeStep() = 0;
virtual void RestorePositionsAndDOFVectorToStartOfStep() = 0;
virtual void SaveTotalDisplacementFieldAtStartOfTimeLoop() = 0;
virtual void AccumulateTotalDisplacementField() = 0;
virtual void OutputProcess() = 0;

virtual void Initialize() = 0;
virtual void InitializeSolutionStep() = 0;
virtual void Predict() = 0;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
// KRATOS___
// // ) )
// // ___ ___
// // ____ //___) ) // ) )
// // / / // // / /
// ((____/ / ((____ ((___/ / MECHANICS
//
// License: geo_mechanics_application/license.txt
//
// Main authors: Richard Faasse
// Anne van de Graaf
// Wijtze Pieter Kikstra
//

#pragma once

#include <vector>
#include <memory>

#include "time_loop_executor_interface.h"
#include "time_step_end_state.hpp"
#include "time_incrementor.h"
#include "time_step_executor.h"
#include "strategy_wrapper.hpp"

namespace Kratos
{

class Process;

class TimeLoopExecutor : public TimeLoopExecutorInterface{
public :
void SetProcessObservables(const std::vector<std::weak_ptr<Process>>& rProcessObservables) override
{
mTimeStepExecutor->SetProcessObservables(rProcessObservables);
}

void SetTimeIncrementor(std::unique_ptr<TimeIncrementor> pTimeIncrementor) override
{
mTimeIncrementor = std::move(pTimeIncrementor);
}

void SetSolverStrategyWrapper(std::shared_ptr<StrategyWrapper> pStrategyWrapper) override
{
mStrategyWrapper = std::move(pStrategyWrapper);
mTimeStepExecutor->SetSolverStrategy(mStrategyWrapper);
}

std::vector<TimeStepEndState> Run(const TimeStepEndState& EndState) override
{
mStrategyWrapper->SaveTotalDisplacementFieldAtStartOfTimeLoop();
std::vector<TimeStepEndState> result;
TimeStepEndState NewEndState = EndState;
while (mTimeIncrementor->WantNextStep(NewEndState)) {
mStrategyWrapper->IncrementStepNumber();
// clone without end time, the end time is overwritten anyway
mStrategyWrapper->CloneTimeStep();
NewEndState = RunCycleLoop(NewEndState);
mStrategyWrapper->AccumulateTotalDisplacementField();
mStrategyWrapper->FinalizeSolutionStep();
mStrategyWrapper->OutputProcess();
result.emplace_back(NewEndState);
}
return result;
}

private:
TimeStepEndState RunCycle(double PreviousTime)
{
// Setting the time and time increment may be needed for the processes
const auto time_increment = mTimeIncrementor->GetIncrement();
mStrategyWrapper->SetTimeIncrement(time_increment);
const auto end_time = PreviousTime + time_increment;
mStrategyWrapper->SetEndTime(end_time);

auto end_state = mTimeStepExecutor->Run(end_time);
mTimeIncrementor->PostTimeStepExecution(end_state);
return end_state;
}

TimeStepEndState RunCycleLoop(const TimeStepEndState& previous_state)
{
auto cycle_number = 0;
auto end_state = previous_state;
while (mTimeIncrementor->WantRetryStep(cycle_number, end_state)) {
if (cycle_number > 0) mStrategyWrapper->RestorePositionsAndDOFVectorToStartOfStep();
end_state = RunCycle(previous_state.time);
++cycle_number;
}

end_state.num_of_cycles = cycle_number;
return end_state;
}

std::unique_ptr<TimeIncrementor> mTimeIncrementor;
std::unique_ptr<TimeStepExecutor> mTimeStepExecutor = std::make_unique<TimeStepExecutor>();
std::shared_ptr<StrategyWrapper> mStrategyWrapper;
};

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// KRATOS___
// // ) )
// // ___ ___
// // ____ //___) ) // ) )
// // / / // // / /
// ((____/ / ((____ ((___/ / MECHANICS
//
// License: geo_mechanics_application/license.txt
//
// Main authors: Richard Faasse
// Anne van de Graaf
// Wijtze Pieter Kikstra
//

#pragma once

#include <vector>
#include <memory>

#include "time_step_end_state.hpp"
#include "time_incrementor.h"
#include "strategy_wrapper.hpp"

namespace Kratos
{

class Process;

class TimeLoopExecutorInterface{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@avdg81 We discussed we didn't want Interface in the name, but @WPK4FEM and I could not think of a suitable pair of names for the interface + implementation of the time loop executor. If you have a suggestion, please let us know!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I don't have a better suggestion either. Let's keep the class names as they are now.

public :
virtual ~TimeLoopExecutorInterface() = default;
virtual void SetProcessObservables(const std::vector<std::weak_ptr<Process>>& rProcessObservables) = 0;
virtual void SetTimeIncrementor(std::unique_ptr<TimeIncrementor> pTimeIncrementor) = 0;
virtual void SetSolverStrategyWrapper(std::shared_ptr<StrategyWrapper> pStrategyWrapper) = 0;
virtual std::vector<TimeStepEndState> Run(const TimeStepEndState& EndState) = 0;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ struct TimeStepEndState

double time = 0.0;
ConvergenceState convergence_state = ConvergenceState::non_converged;
std::size_t num_of_cycles = 0;
std::size_t num_of_iterations = 0;

[[nodiscard]] bool Converged() const {return convergence_state == ConvergenceState::converged;}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,31 +21,31 @@ void TimeStepExecutor::SetSolverStrategy(std::shared_ptr<StrategyWrapper> Solver
mStrategyWrapper = std::move(SolverStrategy);
}

void TimeStepExecutor::SetProcessReferences(ProcessRefVec ProcessRefs)
void TimeStepExecutor::SetProcessObservables(const std::vector<std::weak_ptr<Process>>& rProcessObservables)
{
mProcessRefs = std::move(ProcessRefs);
mProcessObservables = rProcessObservables;
}

TimeStepEndState TimeStepExecutor::Run(double Time)
{
mStrategyWrapper->Initialize();
mStrategyWrapper->InitializeSolutionStep();

for (const auto& process : mProcessRefs)
for (const auto& process_observable : mProcessObservables)
{
process.get().ExecuteInitializeSolutionStep();
auto process = process_observable.lock();
if (process) process->ExecuteInitializeSolutionStep();
}

mStrategyWrapper->Predict();
mStrategyWrapper->SolveSolutionStep();

for (const auto& process : mProcessRefs)
for (const auto& process_observable : mProcessObservables)
{
process.get().ExecuteFinalizeSolutionStep();
auto process = process_observable.lock();
if (process) process->ExecuteFinalizeSolutionStep();
}

mStrategyWrapper->FinalizeSolutionStep();

TimeStepEndState result;
result.time = Time;
result.convergence_state = mStrategyWrapper->GetConvergenceState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ class TimeStepExecutor
using ProcessRefVec = std::vector<ProcessRef>;

void SetSolverStrategy(std::shared_ptr<StrategyWrapper> SolverStrategy);
void SetProcessReferences(ProcessRefVec ProcessRefs);
void SetProcessObservables(const std::vector<std::weak_ptr<Process>>& rProcessObservables);
TimeStepEndState Run(double Time);

private:
std::shared_ptr<StrategyWrapper> mStrategyWrapper;
ProcessRefVec mProcessRefs;
std::vector<std::weak_ptr<Process>> mProcessObservables;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,28 @@ StubTimeLoopExecutor::StubTimeLoopExecutor(std::size_t NumberOfExpectedProcesses
{
}

void StubTimeLoopExecutor::SetProcessReferences(const std::vector<std::weak_ptr<Process>>& rProcessRefs)
void StubTimeLoopExecutor::SetProcessObservables(const std::vector<std::weak_ptr<Process>>& rProcessObservables)
{
KRATOS_EXPECT_EQ(rProcessRefs.size(), mNumberOfExpectedProcesses);
for (const auto& process_ref : rProcessRefs)
KRATOS_EXPECT_EQ(rProcessObservables.size(), mNumberOfExpectedProcesses);
for (const auto& process_observable : rProcessObservables)
{
KRATOS_EXPECT_FALSE(process_ref.expired())
KRATOS_EXPECT_FALSE(process_observable.expired())

std::shared_ptr<Process> process = process_ref.lock();
std::shared_ptr<Process> process = process_observable.lock();
KRATOS_EXPECT_EQ(process->Check(), 0);
}
}

void StubTimeLoopExecutor::SetTimeIncrementor(std::unique_ptr<TimeIncrementor> pTimeIncrementor) {
// intentionally empty
}

void StubTimeLoopExecutor::SetSolverStrategyWrapper(std::shared_ptr<StrategyWrapper> pStrategyWrapper) {
// intentionally empty
}

std::vector<TimeStepEndState> StubTimeLoopExecutor::Run(const TimeStepEndState& EndState) {
return {};
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,21 @@

#pragma once

#include "custom_workflows/time_loop_executor.h"
#include "custom_workflows/time_loop_executor_interface.h"

namespace Kratos {

class StubTimeLoopExecutor : public TimeLoopExecutor
class StubTimeLoopExecutor : public TimeLoopExecutorInterface
{
public:
explicit StubTimeLoopExecutor(size_t NumberOfExpectedProcesses = 0);
void SetProcessReferences(const std::vector<std::weak_ptr<Process>>& rProcessRefs) override;
void SetProcessObservables(const std::vector<std::weak_ptr<Process>>& rProcessObservables) override;

void SetTimeIncrementor(std::unique_ptr<TimeIncrementor> pTimeIncrementor) override;

void SetSolverStrategyWrapper(std::shared_ptr<StrategyWrapper> pStrategyWrapper) override;

std::vector<TimeStepEndState> Run(const TimeStepEndState& EndState) override;

private:
std::size_t mNumberOfExpectedProcesses;
Expand Down
Loading