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] Adopt structural truss element with reset displacement #12531

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
de688de
Changed geo struss element to structural truss element
rfaasse Jul 10, 2024
c761c43
Added the experimental reset displacement process
rfaasse Jul 10, 2024
aff7e42
Cleaned truss constitutive matrix
rfaasse Jul 10, 2024
738fe5f
Reformatted a header file using clang-format
avdg81 Jul 10, 2024
26487fb
Replaced using `SetInitialStateProcess` by a more generic approach
avdg81 Jul 10, 2024
67b861d
Cleaned up the list of `#include`s for `ResetDisplacementProcess`
avdg81 Jul 10, 2024
bc04d72
Replaced two for loops by list comprehensions
avdg81 Jul 10, 2024
4e3a1b9
No longer update the nodal positions using the displacement field
avdg81 Jul 10, 2024
a41948a
Refactored the reset parameters test code
avdg81 Jul 10, 2024
5fe7582
Attempt at fixing test run on TC
rfaasse Jul 10, 2024
e24927d
Removed redundant mdpa files
rfaasse Jul 12, 2024
f5146fc
Renamed mdpa, since it holds for all stages now
rfaasse Jul 12, 2024
c2f6e8f
Changed the README of the test, since the way of doing the reset disp…
rfaasse Jul 12, 2024
c7ca4f6
Added some details to the README.md of the custom_processes
rfaasse Jul 12, 2024
fc3efcf
Merge remote-tracking branch 'origin/master' into geo/12496-adopt-str…
rfaasse Jul 15, 2024
1e3aeba
Added unit tests for the new process and added a check function, sinc…
rfaasse Jul 15, 2024
5cf54c1
Merge remote-tracking branch 'origin/master' into geo/12496-adopt-str…
rfaasse Jul 15, 2024
8d97f3b
Processing review comments
rfaasse Jul 16, 2024
8464a53
Processing review comments
rfaasse Jul 18, 2024
394bf15
Merge remote-tracking branch 'origin/master' into geo/12496-adopt-str…
rfaasse Sep 5, 2024
e3fc32e
Fixed the truss reset displacement test
rfaasse Sep 17, 2024
00a92dc
Minor clean-up
rfaasse Sep 17, 2024
ef86dd0
Moved reset displacement test to new custom_processes folder in cpp_t…
rfaasse Sep 27, 2024
c316255
Processing review comments
rfaasse Sep 27, 2024
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
11 changes: 11 additions & 0 deletions applications/GeoMechanicsApplication/custom_processes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ This folder contains the custom processes that are used in the GeoMechanicsAppli
Documented processes:
- $c-\phi$ reduction process
- [GeoExtrapolateIntegrationPointValuesToNodesProcess](#extrapolation-of-integration-values-to-nodes)
- [ResetDisplacementProcess](#reset-displacement-process)

## $c-\phi$ reduction process
For the assessment of a safety factor to characterize slope stability, a Mohr-Coulomb material based $c-\phi$ reduction
Expand Down Expand Up @@ -59,5 +60,15 @@ Where the `model_part_name` should contain the name of the model part where the

When this process is added to the `ProjectParameters.json`, the variables specified in `list_of_variables` can be exported as nodal output (e.g. as `nodal_results` in the `GiDOutputProcess`).

## Reset displacement process
The `ResetDisplacementProcess` can be used to change the reference point of the displacements to the displacement at the start of that stage.

### Requirements
For this process to work, the following requirements have to be met:
1. The elements in the model part that the process is applied to should have an implementation for `CalculateOnIntegrationPoints` that calculates the PK2_STRESS_VECTOR as well as an overload of `CalculateOnIntegrationPoints` that returns a list of ConstitutiveLaw::Pointer objects for each integration point.
2. The input type of the model can only be "rest" (short for restarted), to ensure that the state of the model is retained from the previous stage. The reason for this, is that the constitutive laws are used at the start of a state to calculate the initial stresses based on the history. If the model is not 'restarted', the constitutive laws will be cleared and the initial stresses can not be calculated correctly.
3. The ConstitutiveLaw used in the elements this process is applied to should use the `InitialState` to apply the initial stresses to the calculated stresses.
Copy link
Contributor

Choose a reason for hiding this comment

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

Are the initial strains ( or strain like variables ) independent of this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have to define something for the initial strains, since if they aren't defined, we get a hard crash (the issue we saw after bringing this branch up to date with master). At this moment, I hardcode the initial strains to be zero vectors. We could discuss if this is always the desired behavior.



## References
<a id="1">[1]</a> Brinkgreve, R.B.J., Bakker, H.L., 1991. Non-linear finite element analysis of safety factors, Computer Methods and Advances in Geomechanics, Beer, Booker & Carterr (eds), Balkema, Rotterdam.
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// KRATOS___
// // ) )
// // ___ ___
// // ____ //___) ) // ) )
// // / / // // / /
// ((____/ / ((____ ((___/ / MECHANICS
//
// License: geo_mechanics_application/license.txt
//
// Main authors: Richard Faasse
//

#include "reset_displacement_process.h"
#include "includes/initial_state.h"
#include "includes/kratos_parameters.h"
#include "includes/model_part.h"
#include "includes/ublas_interface.h"
#include "includes/variables.h"

#include <vector>

namespace Kratos
{

ResetDisplacementProcess::ResetDisplacementProcess(ModelPart& rModelPart, const Parameters&)
: mrModelPart(rModelPart)
{
}

void ResetDisplacementProcess::ExecuteInitialize()
{
block_for_each(mrModelPart.Elements(), [this](Element& rElement) {
std::vector<Vector> stresses_on_integration_points;
rElement.CalculateOnIntegrationPoints(PK2_STRESS_VECTOR, stresses_on_integration_points,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

As discussed, for now the PK2_STRESS_VECTOR is the right choice for structural elements (please correct me if I'm wrong @WPK4FEM)

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes.

mrModelPart.GetProcessInfo());
std::vector<ConstitutiveLaw::Pointer> constitutive_laws;
rElement.CalculateOnIntegrationPoints(CONSTITUTIVE_LAW, constitutive_laws, mrModelPart.GetProcessInfo());

Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we check here whether stresses_on_integration_points and constitutive_laws have the same size and that they aren't empty? E.g.:

KRATOS_ERROR_IF(stresses_on_integration_points.size() != constitutive_laws.size()) << "Number of retrieved stress vectors does not match the number of integration points" << std::endl;
KRATOS_ERROR_IF(stresses_on_integration_points.empty()) << "No stress vectors could be retrieved" << std::endl;

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agreed, added some checks

CheckRetrievedElementData(constitutive_laws, stresses_on_integration_points, rElement.GetId());

for (auto i = std::size_t{0}; i < constitutive_laws.size(); ++i) {
auto p_initial_state = make_intrusive<InitialState>();
p_initial_state->SetInitialStressVector(stresses_on_integration_points[i]);
p_initial_state->SetInitialStrainVector(ZeroVector{constitutive_laws[i]->GetStrainSize()});
constitutive_laws[i]->SetInitialState(p_initial_state);
}
});
}

int ResetDisplacementProcess::Check()
{
KRATOS_ERROR_IF_NOT(mrModelPart.GetProcessInfo()[IS_RESTARTED])
<< "The IS_RESTARTED flag must be set to true in the ProcessInfo of the "
"model part. Please use the \"rest\" option for the model input type";

return 0;
}

void ResetDisplacementProcess::CheckRetrievedElementData(const std::vector<ConstitutiveLaw::Pointer>& rConstitutiveLaws,
const std::vector<Vector>& rStressesOnIntegrationPoints,
IndexType ElementId)
{
KRATOS_ERROR_IF(rConstitutiveLaws.empty())
<< "The constitutive laws on the integration points could not be retrieved for element "
<< ElementId << std::endl;
KRATOS_ERROR_IF(rStressesOnIntegrationPoints.empty())
<< "The stress vectors on the integration points could not be retrieved for element "
<< ElementId << std::endl;
KRATOS_ERROR_IF(rStressesOnIntegrationPoints.size() != rConstitutiveLaws.size())
<< "Number of retrieved stress vectors (" << rStressesOnIntegrationPoints.size()
<< ") does not match the number of constitutive laws (" << rConstitutiveLaws.size()
<< ") for element " << ElementId << std::endl;
}

} // namespace Kratos
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// KRATOS___
// // ) )
// // ___ ___
// // ____ //___) ) // ) )
// // / / // // / /
// ((____/ / ((____ ((___/ / MECHANICS
//
// License: geo_mechanics_application/license.txt
//
// Main authors: Richard Faasse
//

#pragma once

#include "includes/constitutive_law.h"
#include "processes/process.h"

namespace Kratos
{

class ModelPart;
class Parameters;
class Element;

class KRATOS_API(GEO_MECHANICS_APPLICATION) ResetDisplacementProcess : public Process
{
public:
KRATOS_CLASS_POINTER_DEFINITION(ResetDisplacementProcess);
ResetDisplacementProcess(ModelPart& rModelPart, const Parameters&);
~ResetDisplacementProcess() override = default;

ResetDisplacementProcess(const ResetDisplacementProcess&) = delete;
ResetDisplacementProcess& operator=(const ResetDisplacementProcess&) = delete;

void ExecuteInitialize() override;
int Check() override;

private:
ModelPart& mrModelPart;

static void CheckRetrievedElementData(const std::vector<ConstitutiveLaw::Pointer>& rConstitutiveLaws,
const std::vector<Vector>& rStressesOnIntegrationPoints,
IndexType ElementId);
};

} // namespace Kratos
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "custom_processes/deactivate_conditions_on_inactive_elements_process.hpp"
#include "custom_processes/find_neighbour_elements_of_conditions_process.hpp"
#include "custom_processes/geo_extrapolate_integration_point_values_to_nodes_process.h"
#include "custom_processes/reset_displacement_process.h"
#include "custom_processes/set_absorbing_boundary_parameters_process.hpp"
#include "custom_processes/set_multiple_moving_loads.h"
#include "custom_processes/set_parameter_field_process.hpp"
Expand Down Expand Up @@ -176,6 +177,10 @@ void AddCustomProcessesToPython(pybind11::module& m)
py::class_<CalculateIncrementalDisplacementProcess, CalculateIncrementalDisplacementProcess::Pointer, Process>(
m, "CalculateIncrementalDisplacementProcess")
.def(py::init<ModelPart&, const Parameters&>());

py::class_<ResetDisplacementProcess, ResetDisplacementProcess::Pointer, Process>(
m, "ResetDisplacementProcess")
.def(py::init<ModelPart&, const Parameters&>());
}

} // Namespace Kratos::Python.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import KratosMultiphysics.StructuralMechanicsApplication as StructuralMechanicsApplication
import KratosMultiphysics.GeoMechanicsApplication as GeoMechanicsApplication

import json

def CreateSolver(model, custom_settings):
return GeoMechanicalSolver(model, custom_settings)

Expand Down Expand Up @@ -205,6 +207,14 @@ def PrepareModelPart(self):
self.settings["nodal_smoothing"].GetBool())

self.main_model_part.ProcessInfo.SetValue(KratosMultiphysics.STEP, 0)
self.computing_model_part_name = "porous_computational_model_part"

sub_model_part_names = [f"sub_{name.GetString()}" for name in self.settings["body_domain_sub_model_part_list"]]
self.body_domain_sub_sub_model_part_list = KratosMultiphysics.Parameters(json.dumps(sub_model_part_names))

sub_model_part_names = [f"sub_{name.GetString()}" for name in self.settings["loads_sub_model_part_list"]]
self.loads_sub_sub_model_part_list = KratosMultiphysics.Parameters(json.dumps(sub_model_part_names))

if not self.main_model_part.ProcessInfo[KratosMultiphysics.IS_RESTARTED]:
## Executes the check and prepare model process (Create computing_model_part and set constitutive law)
self._ExecuteCheckAndPrepare()
Comment on lines 218 to 220
Copy link
Contributor

Choose a reason for hiding this comment

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

This is the switch that is important ( retain the previous constitutive law for a while ). Please explain that in the readme file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added it to the readme, please let me know if it's clear

Expand Down Expand Up @@ -402,22 +412,6 @@ def _GetLinearSolver(self):
return self.linear_solver

def _ExecuteCheckAndPrepare(self):

self.computing_model_part_name = "porous_computational_model_part"

# Create list of sub sub model parts (it is a copy of the standard lists with a different name)
import json

self.body_domain_sub_sub_model_part_list = []
for i in range(self.settings["body_domain_sub_model_part_list"].size()):
self.body_domain_sub_sub_model_part_list.append("sub_"+self.settings["body_domain_sub_model_part_list"][i].GetString())
self.body_domain_sub_sub_model_part_list = KratosMultiphysics.Parameters(json.dumps(self.body_domain_sub_sub_model_part_list))

self.loads_sub_sub_model_part_list = []
for i in range(self.settings["loads_sub_model_part_list"].size()):
self.loads_sub_sub_model_part_list.append("sub_"+self.settings["loads_sub_model_part_list"][i].GetString())
self.loads_sub_sub_model_part_list = KratosMultiphysics.Parameters(json.dumps(self.loads_sub_sub_model_part_list))

# Auxiliary parameters object for the CheckAndPepareModelProcess
params = KratosMultiphysics.Parameters("{}")
params.AddEmptyValue("computing_model_part_name").SetString(self.computing_model_part_name)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import KratosMultiphysics as Core
import KratosMultiphysics.GeoMechanicsApplication as Geo


def Factory(settings, model):
if not isinstance(settings, Core.Parameters):
raise TypeError("expected input shall be a Parameters object, encapsulating a json string")

model_part = model[settings["Parameters"]["model_part_name"].GetString()]
return Geo.ResetDisplacementProcess(model_part, settings["Parameters"])
Loading
Loading