Skip to content
Snippets Groups Projects
Commit f9820906 authored by Dmitri Naumov's avatar Dmitri Naumov
Browse files

[PL] Move interpolation algorithm to NumLib.

parent 2293da2f
No related branches found
No related tags found
No related merge requests found
......@@ -12,6 +12,9 @@
#include<array>
#include<cassert>
#include "NumLib/Fem/CoordinatesMapping/NaturalNodeCoordinates.h"
#include "NumLib/Fem/FiniteElement/TemplateIsoparametric.h"
namespace NumLib
{
......@@ -85,4 +88,52 @@ void shapeFunctionInterpolate(
interpolated_values...);
}
/// Interpolates \c node_values given in lower order element nodes (e.g. the
/// base nodes) to higher order element's nodes (e.g. quadratic nodes) and
/// writes the result into the global property vector.
///
/// The base nodes' values are copied. For each higher order node the shape
/// matrices are evaluated for the lower order element (the base nodes), and
/// used for the the scalar quantity interpolation.
template <typename LowerOrderShapeFunction, typename HigherOrderMeshElementType,
int GlobalDim, typename EigenMatrixType>
void interpolateToHigherOrderNodes(
MeshLib::Element const& element, bool const is_axially_symmetric,
Eigen::MatrixBase<EigenMatrixType> const& node_values,
MeshLib::PropertyVector<double>& interpolated_values_global_vector)
{
using SF = LowerOrderShapeFunction;
using ShapeMatricesType = ShapeMatrixPolicyType<SF, GlobalDim>;
using ShapeMatrices = typename ShapeMatricesType::ShapeMatrices;
using FemType = TemplateIsoparametric<SF, ShapeMatricesType>;
FemType fe(*static_cast<const typename SF::MeshElement*>(&element));
int const number_base_nodes = element.getNumberOfBaseNodes();
int const number_all_nodes = element.getNumberOfNodes();
// Copy the values for linear nodes.
for (int n = 0; n < number_base_nodes; ++n)
{
std::size_t const global_index = element.getNodeIndex(n);
interpolated_values_global_vector[global_index] = node_values[n];
}
// Shape matrices storage reused in the interpolation loop.
ShapeMatrices shape_matrices{SF::DIM, GlobalDim, SF::NPOINTS};
// Interpolate values for higher order nodes.
for (int n = number_base_nodes; n < number_all_nodes; ++n)
{
// Evaluated at higher order nodes' coordinates.
fe.template computeShapeFunctions<ShapeMatrixType::N>(
NaturalCoordinates<HigherOrderMeshElementType>::coordinates[n]
.data(),
shape_matrices, GlobalDim, is_axially_symmetric);
std::size_t const global_index = element.getNodeIndex(n);
interpolated_values_global_vector[global_index] =
shape_matrices.N * node_values;
}
}
} // namespace NumLib
......@@ -15,7 +15,6 @@
#include "MaterialLib/SolidModels/SelectSolidConstitutiveRelation.h"
#include "MathLib/KelvinVector.h"
#include "NumLib/Fem/CoordinatesMapping/NaturalNodeCoordinates.h"
#include "NumLib/Function/Interpolation.h"
#include "ProcessLib/CoupledSolutionsForStaggeredScheme.h"
......@@ -23,53 +22,6 @@ namespace ProcessLib
{
namespace RichardsMechanics
{
/// For each higher order node evaluate the shape matrices for the lower order
/// element (the base nodes)
template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
int DisplacementDim, typename EigenMatrixType>
void interpolate_p(MeshLib::Element const& element,
bool const is_axially_symmetric,
Eigen::MatrixBase<EigenMatrixType> const& p_L,
MeshLib::PropertyVector<double>& pressure_interpolated)
{
using ShapeMatricesTypePressure =
ShapeMatrixPolicyType<ShapeFunctionPressure, DisplacementDim>;
using FemType = NumLib::TemplateIsoparametric<ShapeFunctionPressure,
ShapeMatricesTypePressure>;
FemType fe(*static_cast<const typename ShapeFunctionPressure::MeshElement*>(
&element));
int const number_base_nodes = element.getNumberOfBaseNodes();
int const number_all_nodes = element.getNumberOfNodes();
// Copy the values for linear nodes.
for (int n = 0; n < number_base_nodes; ++n)
{
std::size_t const global_index = element.getNodeIndex(n);
pressure_interpolated[global_index] = p_L[n];
}
// Interpolate values for higher order nodes.
for (int n = number_base_nodes; n < number_all_nodes; ++n)
{
// Evaluated at higher order nodes' coordinates.
typename ShapeMatricesTypePressure::ShapeMatrices shape_matrices_p{
ShapeFunctionPressure::DIM, DisplacementDim,
ShapeFunctionPressure::NPOINTS};
fe.template computeShapeFunctions<NumLib::ShapeMatrixType::N>(
NumLib::NaturalCoordinates<
typename ShapeFunctionDisplacement::MeshElement>::coordinates[n]
.data(),
shape_matrices_p, DisplacementDim, is_axially_symmetric);
auto const& N_p = shape_matrices_p.N;
std::size_t const global_index = element.getNodeIndex(n);
pressure_interpolated[global_index] = N_p * p_L;
}
}
template <typename ShapeFunctionDisplacement, typename ShapeFunctionPressure,
typename IntegrationMethod, int DisplacementDim>
RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
......@@ -881,9 +833,10 @@ void RichardsMechanicsLocalAssembler<ShapeFunctionDisplacement,
(*_process_data.element_saturation)[_element.getID()] = saturation_avg;
interpolate_p<ShapeFunctionDisplacement, ShapeFunctionPressure,
DisplacementDim>(_element, _is_axially_symmetric, p_L,
*_process_data.pressure_interpolated);
NumLib::interpolateToHigherOrderNodes<
ShapeFunctionPressure, typename ShapeFunctionDisplacement::MeshElement,
DisplacementDim>(_element, _is_axially_symmetric, p_L,
*_process_data.pressure_interpolated);
}
} // namespace RichardsMechanics
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment