Added reflection functionality for ip data output
-
Tests covering your feature were added?
This MR adds code facilitating IP data output.
Currently, for this task we have to write the following
struct LocalAssemblerInterface
{
...
std::vector<double> getSigma() const
{
constexpr int kelvin_vector_size =
MathLib::KelvinVector::kelvin_vector_dimensions(DisplacementDim);
return transposeInPlace<kelvin_vector_size>(
[this](std::vector<double>& values)
{ return getIntPtSigma(0, {}, {}, values); });
}
std::vector<double> const& getIntPtSigma(
const double /*t*/,
std::vector<GlobalVector*> const& /*x*/,
std::vector<NumLib::LocalToGlobalIndexMap const*> const& /*dof_table*/,
std::vector<double>& cache) const
{
return ProcessLib::getIntegrationPointKelvinVectorData<DisplacementDim>(
current_states_, [](auto const& cs) -> auto const& {
return cs.s_mech_data.sigma_eff;
},
cache);
}
// and so on for all IP data...
};
void SomeProcess::init()
{
...
_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, &LocalAssemblerIF::getSigma));
_integration_point_writer.emplace_back(
std::make_unique<MeshLib::IntegrationPointWriter>(
"epsilon_ip",
static_cast<int>(mesh.getDimension() == 2 ? 4 : 6) /*n components*/,
integration_order, _local_assemblers,
&LocalAssemblerIF::getEpsilon));
}
// and so on for all IP data ...
...
add_secondary_variable("sigma",
MathLib::KelvinVector::KelvinVectorType<
DisplacementDim>::RowsAtCompileTime,
&LocalAssemblerIF::getIntPtSigma);
add_secondary_variable("epsilon",
MathLib::KelvinVector::KelvinVectorType<
DisplacementDim>::RowsAtCompileTime,
&LocalAssemblerIF::getIntPtEpsilon);
// and so on for all secondary variables ...
};
With this MR this is reduced to roughly:
template <int DisplacementDim>
struct StrainData
{
KelvinVector<DisplacementDim> eps = KVzero<DisplacementDim>();
static auto reflect()
{
using Self = StrainData<DisplacementDim>;
// reflection data has to be provided for all variables we want to output
return ProcessLib::Reflection::reflectWithName("epsilon", &Self::eps);
}
};
struct LocalAssemblerInterface
{
...
// only needed once
static auto getReflectionDataForOutput()
{
using Self = LocalAssemblerInterface<DisplacementDim>;
return ProcessLib::Reflection::reflectWithoutName(
&Self::current_states_, &Self::output_data_);
}
};
void SomeProcess::init()
{
...
// only needed once
ProcessLib::Reflection::addReflectedIntegrationPointWriters<
DisplacementDim>(LocalAssemblerIF::getReflectionDataForOutput(),
_integration_point_writer, integration_order,
local_assemblers_);
...
// only needed once
ProcessLib::Reflection::addReflectedSecondaryVariables<DisplacementDim>(
LocalAssemblerIF::getReflectionDataForOutput(), _secondary_variables,
getExtrapolator(), local_assemblers_);
};
- This MR saves ~200 lines of code in the TRM process, similar savings are possible for all other processes
- Setting IP data from VTU files is also possible with the reflection data (subsequent MR)
- The major/hard part of this MR are ~400 lines of implementation in
ProcessLib/Reflection/ReflectionIPData.h
and ~500 lines of unit test.