Skip to content

Commit

Permalink
initial stress for phase field process
Browse files Browse the repository at this point in the history
  • Loading branch information
Mostafa Mollaali authored and endJunction committed Aug 22, 2024
1 parent 0f84d3c commit dbc396f
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 1 deletion.
6 changes: 6 additions & 0 deletions ProcessLib/PhaseField/CreatePhaseFieldProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "ParameterLib/Utils.h"
#include "PhaseFieldProcess.h"
#include "PhaseFieldProcessData.h"
#include "ProcessLib/Common/HydroMechanics/CreateInitialStress.h"
#include "ProcessLib/Output/CreateSecondaryVariables.h"
#include "ProcessLib/Utils/ProcessUtils.h"

Expand Down Expand Up @@ -210,6 +211,10 @@ std::unique_ptr<Process> createPhaseFieldProcess(
phasefield_model_string.c_str());
}();

// Initial stress conditions
auto initial_stress = ProcessLib::createInitialStress<DisplacementDim>(
config, parameters, mesh);

auto const softening_curve = [&]
{
auto const softening_curve_string =
Expand Down Expand Up @@ -284,6 +289,7 @@ std::unique_ptr<Process> createPhaseFieldProcess(
crack_resistance,
crack_length_scale,
solid_density,
initial_stress,
specific_body_force,
pressurized_crack,
propagating_pressurized_crack,
Expand Down
8 changes: 8 additions & 0 deletions ProcessLib/PhaseField/LocalAssemblerInterface.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ struct PhaseFieldLocalAssemblerInterface
: public ProcessLib::LocalAssemblerInterface,
public NumLib::ExtrapolatableElement
{
virtual std::size_t setIPDataInitialConditions(
std::string_view const name, double const* values,
int const integration_order) = 0;

virtual std::vector<double> getSigma() const = 0;

virtual std::vector<double> getEpsilon() const = 0;

virtual std::vector<double> const& getIntPtSigma(
const double t,
std::vector<GlobalVector*> const& x,
Expand Down
68 changes: 68 additions & 0 deletions ProcessLib/PhaseField/PhaseFieldFEM-impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,5 +415,73 @@ void PhaseFieldLocalAssembler<ShapeFunction, DisplacementDim>::computeEnergy(
surface_energy += element_surface_energy;
pressure_work += element_pressure_work;
}

template <typename ShapeFunctionDisplacement, int DisplacementDim>
std::size_t PhaseFieldLocalAssembler<
ShapeFunctionDisplacement,
DisplacementDim>::setIPDataInitialConditions(std::string_view const name,
double const* values,
int const integration_order)
{
if (integration_order !=
static_cast<int>(_integration_method.getIntegrationOrder()))
{
OGS_FATAL(
"Setting integration point initial conditions; The integration "
"order of the local assembler for element {:d} is different from "
"the integration order in the initial condition.",
_element.getID());
}

if (name == "sigma")
{
if (_process_data.initial_stress.value != nullptr)
{
OGS_FATAL(
"Setting initial conditions for stress from integration "
"point data and from a parameter '{:s}' is not possible "
"simultaneously.",
_process_data.initial_stress.value->name);
}

return ProcessLib::setIntegrationPointKelvinVectorData<DisplacementDim>(
values, _ip_data, &IpData::sigma);
}

return 0;
}

template <typename ShapeFunctionDisplacement, int DisplacementDim>
std::vector<double> PhaseFieldLocalAssembler<ShapeFunctionDisplacement,
DisplacementDim>::getSigma() const
{
return ProcessLib::getIntegrationPointKelvinVectorData<DisplacementDim>(
_ip_data, &IpData::sigma);
}

template <typename ShapeFunctionDisplacement, int DisplacementDim>
std::vector<double> PhaseFieldLocalAssembler<
ShapeFunctionDisplacement, DisplacementDim>::getEpsilon() const
{
auto const kelvin_vector_size =
MathLib::KelvinVector::kelvin_vector_dimensions(DisplacementDim);
unsigned const n_integration_points =
_integration_method.getNumberOfPoints();

std::vector<double> ip_epsilon_values;
auto cache_mat = MathLib::createZeroedMatrix<Eigen::Matrix<
double, Eigen::Dynamic, kelvin_vector_size, Eigen::RowMajor>>(
ip_epsilon_values, n_integration_points, kelvin_vector_size);

for (unsigned ip = 0; ip < n_integration_points; ++ip)
{
auto const& eps = _ip_data[ip].eps;
cache_mat.row(ip) =
MathLib::KelvinVector::kelvinVectorToSymmetricTensor(eps);
}

return ip_epsilon_values;
}

} // namespace PhaseField
} // namespace ProcessLib
35 changes: 34 additions & 1 deletion ProcessLib/PhaseField/PhaseFieldFEM.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ class PhaseFieldLocalAssembler : public PhaseFieldLocalAssemblerInterface
}
}

/// Returns number of read integration points.
std::size_t setIPDataInitialConditions(
std::string_view const name,
double const* values,
int const integration_order) override;

void assemble(double const /*t*/, double const /*dt*/,
std::vector<double> const& /*local_x*/,
std::vector<double> const& /*local_x_prev*/,
Expand All @@ -287,7 +293,27 @@ class PhaseFieldLocalAssembler : public PhaseFieldLocalAssemblerInterface

for (unsigned ip = 0; ip < n_integration_points; ip++)
{
_ip_data[ip].pushBackState();
auto& ip_data = _ip_data[ip];

ParameterLib::SpatialPosition const x_position{
std::nullopt, _element.getID(), ip,
MathLib::Point3d(
NumLib::interpolateCoordinates<ShapeFunction,
ShapeMatricesType>(
_element, ip_data.N))};

/// Set initial stress from parameter.
if (_process_data.initial_stress.value)
{
ip_data.sigma =
MathLib::KelvinVector::symmetricTensorToKelvinVector<
DisplacementDim>((*_process_data.initial_stress.value)(
std::numeric_limits<
double>::quiet_NaN() /* time independent */,
x_position));
}

ip_data.pushBackState();
}
}

Expand Down Expand Up @@ -327,6 +353,13 @@ class PhaseFieldLocalAssembler : public PhaseFieldLocalAssemblerInterface
return Eigen::Map<const Eigen::RowVectorXd>(N.data(), N.size());
}

// TODO (naumov) This method is same as getIntPtSigma but for arguments and
// the ordering of the cache_mat.
// There should be only one.
std::vector<double> getSigma() const override;

std::vector<double> getEpsilon() const override;

private:
std::vector<double> const& getIntPtSigma(
const double /*t*/,
Expand Down
11 changes: 11 additions & 0 deletions ProcessLib/PhaseField/PhaseFieldProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include "PhaseFieldFEM.h"
#include "ProcessLib/Process.h"
#include "ProcessLib/SmallDeformation/CreateLocalAssemblers.h"
#include "ProcessLib/Utils/SetIPDataInitialConditions.h"

namespace ProcessLib
{
Expand Down Expand Up @@ -47,6 +48,13 @@ PhaseFieldProcess<DisplacementDim>::PhaseFieldProcess(

_nodal_forces = MeshLib::getOrCreateMeshProperty<double>(
mesh, "NodalForces", MeshLib::MeshItemType::Node, DisplacementDim);

_integration_point_writer.emplace_back(
std::make_unique<MeshLib::IntegrationPointWriter>(
"sigma_ip",
static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
integration_order, _local_assemblers,
&LocalAssemblerInterface::getSigma));
}

template <int DisplacementDim>
Expand Down Expand Up @@ -159,6 +167,9 @@ void PhaseFieldProcess<DisplacementDim>::initializeConcreteProcess(
getExtrapolator(), _local_assemblers,
&LocalAssemblerInterface::getIntPtEpsilonTensile));

setIPDataInitialConditions(_integration_point_writer, mesh.getProperties(),
_local_assemblers);

// Initialize local assemblers after all variables have been set.
GlobalExecutor::executeMemberOnDereferenced(
&LocalAssemblerInterface::initialize, _local_assemblers,
Expand Down
5 changes: 5 additions & 0 deletions ProcessLib/PhaseField/PhaseFieldProcessData.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

#include "MeshLib/PropertyVector.h"
#include "ParameterLib/Parameter.h"
#include "ProcessLib/Common/HydroMechanics/InitialStress.h"

namespace MaterialLib
{
Expand Down Expand Up @@ -209,6 +210,10 @@ struct PhaseFieldProcessData
ParameterLib::Parameter<double> const& crack_resistance;
ParameterLib::Parameter<double> const& crack_length_scale;
ParameterLib::Parameter<double> const& solid_density;
/// Optional, initial stress field. A symmetric tensor, short vector
/// representation of length 4 or 6, ParameterLib::Parameter<double>.
InitialStress const initial_stress;

Eigen::Matrix<double, DisplacementDim, 1> const specific_body_force;
bool pressurized_crack = false;
bool propagating_pressurized_crack = false;
Expand Down

0 comments on commit dbc396f

Please sign in to comment.