Skip to content

Commit

Permalink
[GeoMechanicsApplication] Fix inactive element workflow in time integ…
Browse files Browse the repository at this point in the history
…ration schemes (#12864)

Make the EquationId and GetDofList function unconditional in the scheme (also return values when element/condition is inactive) to comply with expectations from core components
  • Loading branch information
rfaasse authored Nov 20, 2024
1 parent ed3bae3 commit ce2649a
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 136 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,46 +77,6 @@ class GeoMechanicsTimeIntegrationScheme : public Scheme<TSparseSpace, TDenseSpac
KRATOS_CATCH("")
}

void GetDofList(const Element& rElement, Element::DofsVectorType& rDofList, const ProcessInfo& rCurrentProcessInfo) override
{
GetDofListImpl(rElement, rDofList, rCurrentProcessInfo);
}

void GetDofList(const Condition& rCondition, Condition::DofsVectorType& rDofList, const ProcessInfo& rCurrentProcessInfo) override
{
GetDofListImpl(rCondition, rDofList, rCurrentProcessInfo);
}

template <typename T>
void GetDofListImpl(const T& rElementOrCondition, typename T::DofsVectorType& rDofList, const ProcessInfo& rCurrentProcessInfo)
{
if (IsActive(rElementOrCondition))
rElementOrCondition.GetDofList(rDofList, rCurrentProcessInfo);
}

void EquationId(const Element& rElement,
Element::EquationIdVectorType& rEquationId,
const ProcessInfo& rCurrentProcessInfo) override
{
EquationIdImpl(rElement, rEquationId, rCurrentProcessInfo);
}

void EquationId(const Condition& rCondition,
Condition::EquationIdVectorType& rEquationId,
const ProcessInfo& rCurrentProcessInfo) override
{
EquationIdImpl(rCondition, rEquationId, rCurrentProcessInfo);
}

template <typename T>
void EquationIdImpl(const T& rElementOrCondition,
typename T::EquationIdVectorType& rEquationId,
const ProcessInfo& rCurrentProcessInfo)
{
if (IsActive(rElementOrCondition))
rElementOrCondition.EquationIdVector(rEquationId, rCurrentProcessInfo);
}

void Predict(ModelPart& rModelPart, DofsArrayType&, TSystemMatrixType&, TSystemVectorType&, TSystemVectorType&) override
{
this->UpdateVariablesDerivatives(rModelPart);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,7 @@ class ConcreteGeoMechanicsTimeIntegrationScheme
}

protected:
void UpdateVariablesDerivatives(ModelPart& rModelPart) override
{
// Intentionally left empty
}
MOCK_METHOD(void, UpdateVariablesDerivatives, (ModelPart&), (override));
};

class GeoMechanicsSchemeTester
Expand All @@ -57,31 +54,32 @@ class GeoMechanicsSchemeTester
}

template <class T>
void TestFunctionCalledOnComponent_IsOnlyCalledWhenComponentIsActive()
void TestFunctionCalledOnComponent_IsCalledOnActiveAndInactiveComponents()
{
typename T::EquationIdVectorType r_equation_id_vector;
ProcessInfo r_process_info;
typename T::DofsVectorType r_dofs_vector;

auto functions_and_checks = CreateFunctionsAndChecksCalledOnASingleComponent<T>(
r_equation_id_vector, r_process_info, r_dofs_vector);
Setup();
auto active_component = Kratos::make_intrusive<T>();
active_component->SetId(0);
active_component->Set(ACTIVE, true);

for (const auto& [function_on_component, function_has_been_called_on_component] : functions_and_checks) {
Setup();
auto active_component = Kratos::make_intrusive<T>();
active_component->SetId(0);
active_component->Set(ACTIVE, true);
auto inactive_component = Kratos::make_intrusive<T>();
inactive_component->SetId(1);
inactive_component->Set(ACTIVE, false);

auto inactive_component = Kratos::make_intrusive<T>();
inactive_component->SetId(1);
inactive_component->Set(ACTIVE, false);
EXPECT_CALL(*active_component, EquationIdVector(testing::_, testing::_)).Times(1);
mScheme.EquationId(*active_component.get(), r_equation_id_vector, r_process_info);

function_on_component(active_component);
function_on_component(inactive_component);
EXPECT_CALL(*inactive_component, EquationIdVector(testing::_, testing::_)).Times(1);
mScheme.EquationId(*inactive_component.get(), r_equation_id_vector, r_process_info);

KRATOS_EXPECT_TRUE(function_has_been_called_on_component(active_component))
KRATOS_EXPECT_FALSE(function_has_been_called_on_component(inactive_component))
}
EXPECT_CALL(*active_component, GetDofList(testing::_, testing::_)).Times(1);
mScheme.GetDofList(*active_component.get(), r_dofs_vector, r_process_info);

EXPECT_CALL(*inactive_component, GetDofList(testing::_, testing::_)).Times(1);
mScheme.GetDofList(*inactive_component.get(), r_dofs_vector, r_process_info);
}

template <class T>
Expand Down Expand Up @@ -160,33 +158,6 @@ class GeoMechanicsSchemeTester
return functions_and_checks;
}

template <typename T>
std::vector<std::pair<std::function<void(const Kratos::intrusive_ptr<T> Component)>, std::function<bool(const Kratos::intrusive_ptr<T> rElement)>>> CreateFunctionsAndChecksCalledOnASingleComponent(
typename T::EquationIdVectorType& rEquationIdVector, ProcessInfo& rProcessInfo, typename T::DofsVectorType& rDofsVector)
{
std::vector<std::pair<std::function<void(const Kratos::intrusive_ptr<T> Component)>, std::function<bool(const Kratos::intrusive_ptr<T> Component)>>> functions_and_checks;

auto equation_id = [this, &rEquationIdVector, &rProcessInfo](const Kratos::intrusive_ptr<T> Component) {
mScheme.EquationId(*Component.get(), rEquationIdVector, rProcessInfo);
};

auto equation_id_check = [](const Kratos::intrusive_ptr<T> Component) {
return Component->IsEquationIdRetrieved();
};

auto get_dofs_list = [this, &rDofsVector, &rProcessInfo](const Kratos::intrusive_ptr<T> Component) {
mScheme.GetDofList(*Component.get(), rDofsVector, rProcessInfo);
};

auto get_dofs_list_check = [](const Kratos::intrusive_ptr<T> Component) {
return Component->IsGetDofListCalled();
};

functions_and_checks.push_back({equation_id, equation_id_check});
functions_and_checks.push_back({get_dofs_list, get_dofs_list_check});
return functions_and_checks;
}

void AddComponent(ModelPart::ElementType::Pointer element)
{
GetModelPart().AddElement(element);
Expand All @@ -213,16 +184,17 @@ KRATOS_TEST_CASE_IN_SUITE(FunctionCallsOnAllConditions_AreOnlyCalledForActiveCon
tester.TestFunctionCallOnAllComponents_AreOnlyCalledForActiveComponents<SpyCondition>();
}

KRATOS_TEST_CASE_IN_SUITE(FunctionCalledOnCondition_IsOnlyCalledWhenConditionIsActive, KratosGeoMechanicsFastSuiteWithoutKernel)
KRATOS_TEST_CASE_IN_SUITE(FunctionCalledOnCondition_IsCalledOnActiveAndInactiveConditions,
KratosGeoMechanicsFastSuiteWithoutKernel)
{
GeoMechanicsSchemeTester tester;
tester.TestFunctionCalledOnComponent_IsOnlyCalledWhenComponentIsActive<SpyCondition>();
tester.TestFunctionCalledOnComponent_IsCalledOnActiveAndInactiveComponents<SpyCondition>();
}

KRATOS_TEST_CASE_IN_SUITE(FunctionCalledOnElement_IsOnlyCalledWhenElementIsActive, KratosGeoMechanicsFastSuiteWithoutKernel)
KRATOS_TEST_CASE_IN_SUITE(FunctionCalledOnElement_IsCalledOnActiveAndInactiveElements, KratosGeoMechanicsFastSuiteWithoutKernel)
{
GeoMechanicsSchemeTester tester;
tester.TestFunctionCalledOnComponent_IsOnlyCalledWhenComponentIsActive<SpyElement>();
tester.TestFunctionCalledOnComponent_IsCalledOnActiveAndInactiveComponents<SpyElement>();
}

KRATOS_TEST_CASE_IN_SUITE(ForInvalidBufferSize_CheckGeoMechanicsTimeIntegrationScheme_Throws,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@ void SpyCondition::FinalizeNonLinearIteration(const ProcessInfo& rCurrentProcess
mNonLinIterationFinalized = true;
}

void SpyCondition::EquationIdVector(Condition::EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const
{
mIsEquationIdRetrieved = true;
}

void SpyCondition::GetDofList(Condition::DofsVectorType& rElementalDofList, const ProcessInfo& rCurrentProcessInfo) const
{
mIsGetDofListCalled = true;
}

bool SpyCondition::IsSolutionStepInitialized() const { return mSolutionStepInitialized; }

bool SpyCondition::IsSolutionStepFinalized() const { return mSolutionStepFinalized; }
Expand All @@ -52,8 +42,4 @@ bool SpyCondition::IsNonLinIterationInitialized() const { return mNonLinIteratio

bool SpyCondition::IsNonLinIterationFinalized() const { return mNonLinIterationFinalized; }

bool SpyCondition::IsEquationIdRetrieved() const { return mIsEquationIdRetrieved; }

bool SpyCondition::IsGetDofListCalled() const { return mIsGetDofListCalled; }

} // namespace Kratos::Testing
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#pragma once

#include "includes/condition.h"
#include <gmock/gmock.h>

namespace Kratos::Testing
{
Expand All @@ -25,9 +26,8 @@ class SpyCondition : public Condition
void InitializeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) override;
void FinalizeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) override;

void EquationIdVector(EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const override;

void GetDofList(DofsVectorType& rElementalDofList, const ProcessInfo& rCurrentProcessInfo) const override;
MOCK_METHOD(void, EquationIdVector, (EquationIdVectorType&, const ProcessInfo&), (const, override));
MOCK_METHOD(void, GetDofList, (DofsVectorType&, const ProcessInfo&), (const, override));

bool IsSolutionStepInitialized() const;
bool IsSolutionStepFinalized() const;
Expand All @@ -37,12 +37,10 @@ class SpyCondition : public Condition
bool IsGetDofListCalled() const;

private:
bool mSolutionStepInitialized = false;
bool mSolutionStepFinalized = false;
bool mNonLinIterationInitialized = false;
bool mNonLinIterationFinalized = false;
mutable bool mIsEquationIdRetrieved = false;
mutable bool mIsGetDofListCalled = false;
bool mSolutionStepInitialized = false;
bool mSolutionStepFinalized = false;
bool mNonLinIterationInitialized = false;
bool mNonLinIterationFinalized = false;
};

} // namespace Kratos::Testing
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,6 @@ void SpyElement::FinalizeNonLinearIteration(const ProcessInfo& rCurrentProcessIn
mNonLinIterationFinalized = true;
}

void SpyElement::EquationIdVector(Element::EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const
{
mIsEquationIdRetrieved = true;
}

void SpyElement::GetDofList(Element::DofsVectorType& rElementalDofList, const ProcessInfo& rCurrentProcessInfo) const
{
mIsGetDofListCalled = true;
}

bool SpyElement::IsSolutionStepInitialized() const { return mSolutionStepInitialized; }

bool SpyElement::IsSolutionStepFinalized() const { return mSolutionStepFinalized; }
Expand All @@ -52,8 +42,4 @@ bool SpyElement::IsNonLinIterationInitialized() const { return mNonLinIterationI

bool SpyElement::IsNonLinIterationFinalized() const { return mNonLinIterationFinalized; }

bool SpyElement::IsEquationIdRetrieved() const { return mIsEquationIdRetrieved; }

bool SpyElement::IsGetDofListCalled() const { return mIsGetDofListCalled; }

} // namespace Kratos::Testing
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#pragma once

#include "includes/element.h"
#include <gmock/gmock.h>

namespace Kratos::Testing
{
Expand All @@ -23,8 +24,9 @@ class SpyElement : public Element
void FinalizeSolutionStep(const ProcessInfo& rCurrentProcessInfo) override;
void InitializeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) override;
void FinalizeNonLinearIteration(const ProcessInfo& rCurrentProcessInfo) override;
void EquationIdVector(EquationIdVectorType& rResult, const ProcessInfo& rCurrentProcessInfo) const override;
void GetDofList(DofsVectorType& rElementalDofList, const ProcessInfo& rCurrentProcessInfo) const override;

MOCK_METHOD(void, EquationIdVector, (EquationIdVectorType&, const ProcessInfo&), (const, override));
MOCK_METHOD(void, GetDofList, (DofsVectorType&, const ProcessInfo&), (const, override));

bool IsSolutionStepInitialized() const;
bool IsSolutionStepFinalized() const;
Expand All @@ -34,12 +36,10 @@ class SpyElement : public Element
bool IsGetDofListCalled() const;

private:
bool mSolutionStepInitialized = false;
bool mSolutionStepFinalized = false;
bool mNonLinIterationInitialized = false;
bool mNonLinIterationFinalized = false;
mutable bool mIsEquationIdRetrieved = false;
mutable bool mIsGetDofListCalled = false;
bool mSolutionStepInitialized = false;
bool mSolutionStepFinalized = false;
bool mNonLinIterationInitialized = false;
bool mNonLinIterationFinalized = false;
};

} // namespace Kratos::Testing

0 comments on commit ce2649a

Please sign in to comment.