Newer
Older
/**
* \file
* \copyright
* Copyright (c) 2012-2019, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "MathLib/LinAlg/Eigen/EigenMapTools.h"
#include "MeshLib/Elements/FaceRule.h"
#include "NumLib/DOF/DOFTableUtil.h"
#include "ProcessLib/Parameter/Parameter.h"
#include "GenericNaturalBoundaryConditionLocalAssembler.h"
namespace ProcessLib
{
namespace NormalTractionBoundaryCondition
{
template <typename ShapeMatricesTypeDisplacement, int GlobalDim, int NPoints>
struct IntegrationPointData final
{
IntegrationPointData(
typename ShapeMatricesTypeDisplacement::template VectorType<
NPoints * GlobalDim> const& Nu_times_n_,
double const integration_weight_)
: Nu_times_n(Nu_times_n_), integration_weight(integration_weight_)
{
}
// Shape matrix (for displacement) times element's normal vector.
typename ShapeMatricesTypeDisplacement::template VectorType<
NPoints * GlobalDim> const Nu_times_n;
double const integration_weight;
};
class NormalTractionBoundaryConditionLocalAssemblerInterface
{
public:
virtual void assemble(
std::size_t const id,
NumLib::LocalToGlobalIndexMap const& dof_table_boundary, double const t,
const GlobalVector& /*x*/, GlobalMatrix& /*K*/, GlobalVector& b,
GlobalMatrix* /*Jac*/) = 0;
virtual ~NormalTractionBoundaryConditionLocalAssemblerInterface() = default;
};
template <typename ShapeFunctionDisplacement, typename IntegrationMethod,
unsigned GlobalDim>
class NormalTractionBoundaryConditionLocalAssembler final
: public NormalTractionBoundaryConditionLocalAssemblerInterface
{
public:
using ShapeMatricesTypeDisplacement =
ShapeMatrixPolicyType<ShapeFunctionDisplacement, GlobalDim>;
using GlobalDimVectorType =
typename ShapeMatrixPolicyType<ShapeFunctionDisplacement,
GlobalDim>::GlobalDimVectorType;
NormalTractionBoundaryConditionLocalAssembler(
MeshLib::Element const& e,
std::size_t const local_matrix_size,
bool const is_axially_symmetric,
unsigned const integration_order,
Parameter<double> const& pressure)
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
: _integration_method(integration_order), _pressure(pressure)
{
_local_rhs.setZero(local_matrix_size);
unsigned const n_integration_points =
_integration_method.getNumberOfPoints();
_ip_data.reserve(n_integration_points);
auto const shape_matrices_u =
initShapeMatrices<ShapeFunctionDisplacement,
ShapeMatricesTypeDisplacement, IntegrationMethod,
GlobalDim>(e, is_axially_symmetric,
_integration_method);
GlobalDimVectorType element_normal(GlobalDim);
// TODO Extend to rotated 2d meshes and line elements.
if (e.getGeomType() == MeshLib::MeshElemType::LINE)
{
auto v1 = (*e.getNode(1)) - (*e.getNode(0));
element_normal[0] = -v1[1];
element_normal[1] = v1[0];
element_normal.normalize();
}
else
{
auto const element_normal_vector =
MeshLib::FaceRule::getSurfaceNormal(&e).getNormalizedVector();
std::copy_n(element_normal_vector.getCoords(), GlobalDim,
element_normal.data());
}
for (unsigned ip = 0; ip < n_integration_points; ip++)
{
typename ShapeMatricesTypeDisplacement::template MatrixType<
GlobalDim, displacement_size>
N_u = ShapeMatricesTypeDisplacement::template MatrixType<
GlobalDim, displacement_size>::Zero(GlobalDim,
displacement_size);
for (int i = 0; i < static_cast<int>(GlobalDim); ++i)
N_u.template block<1, displacement_size / GlobalDim>(
i, i * displacement_size / GlobalDim)
.noalias() = shape_matrices_u[ip].N;
double const integration_weight =
_integration_method.getWeightedPoint(ip).getWeight() *
shape_matrices_u[ip].integralMeasure *
shape_matrices_u[ip].detJ;
_ip_data.emplace_back(N_u.transpose() * element_normal,
integration_weight);
}
}
void assemble(std::size_t const id,
NumLib::LocalToGlobalIndexMap const& dof_table_boundary,
double const t, const GlobalVector& /*x*/,
GlobalMatrix& /*K*/, GlobalVector& local_rhs,
GlobalMatrix* /*Jac*/) override
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
{
_local_rhs.setZero();
unsigned const n_integration_points =
_integration_method.getNumberOfPoints();
SpatialPosition pos;
pos.setElementID(id);
for (unsigned ip = 0; ip < n_integration_points; ip++)
{
pos.setIntegrationPoint(ip);
auto const& w = _ip_data[ip].integration_weight;
auto const& Nu_times_n = _ip_data[ip].Nu_times_n;
_local_rhs.noalias() -=
Nu_times_n.transpose() * _pressure(t, pos)[0] * w;
}
auto const indices = NumLib::getIndices(id, dof_table_boundary);
local_rhs.add(indices, _local_rhs);
}
private:
IntegrationMethod const _integration_method;
Parameter<double> const& _pressure;
static const int displacement_size =
ShapeFunctionDisplacement::NPOINTS * GlobalDim;
std::vector<IntegrationPointData<ShapeMatricesTypeDisplacement, GlobalDim,
ShapeFunctionDisplacement::NPOINTS>,
Eigen::aligned_allocator<IntegrationPointData<
ShapeMatricesTypeDisplacement, GlobalDim,
ShapeFunctionDisplacement::NPOINTS>>>
_ip_data;
typename ShapeMatricesTypeDisplacement::template VectorType<
displacement_size>
_local_rhs;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
};
} // namespace NormalTractionBoundaryCondition
} // namespace ProcessLib