35 : constViscosity_(t.constViscosity)
38 template <
class CG,
class Node,
class Quad,
class LocalFct,
class Mat>
39 void assemble(CG
const& contextGeo, Node
const& tree, Node
const& ,
40 Quad
const& quad, LocalFct
const& localFct, Mat& elementMatrix)
const
42 static_assert(static_size_v<typename LocalFct::Range> == 1,
43 "Viscosity must be of scalar type.");
45 using VelocityNode = Dune::TypeTree::Child<Node,0>;
46 using VelocityCompNode = Dune::TypeTree::Child<Node,0,0>;
47 using PressureNode = Dune::TypeTree::Child<Node,1>;
49 static_assert(Dune::TypeTree::Concept::UniformInnerTreeNode<VelocityNode> && Dune::TypeTree::Concept::LeafTreeNode<PressureNode>,
"");
51 using namespace Dune::Indices;
53 std::size_t numVelocityLocalFE = tree.child(_0,0).size();
54 std::size_t numPressureLocalFE = tree.child(_1).size();
56 using RangeFieldType =
typename Dune::TypeTree::Child<VelocityNode,0>::LocalBasis::Traits::RangeFieldType;
57 using WorldVector = Dune::FieldVector<RangeFieldType,CG::dow>;
58 std::vector<WorldVector> gradients;
60 for (
auto const& qp : quad) {
62 auto&& local = contextGeo.coordinateInElement(qp.position());
65 const auto jacobian = contextGeo.elementGeometry().jacobianInverseTransposed(local);
68 const auto factor = contextGeo.integrationElement(qp.position()) * qp.weight();
69 const auto vel_factor = localFct(local) * factor;
71 auto const& shapeGradients = tree.child(_0,0).localBasisJacobiansAt(local);
74 gradients.resize(shapeGradients.size());
75 for (std::size_t i = 0; i < gradients.size(); ++i)
76 jacobian.mv(shapeGradients[i][0], gradients[i]);
78 auto const& pressureValues = tree.child(_1).localBasisValuesAt(local);
81 for (std::size_t i = 0; i < numVelocityLocalFE; ++i) {
82 const auto value_ii = vel_factor * (gradients[i] * gradients[i]);
83 for (std::size_t k = 0; k < CG::dow; ++k) {
84 const auto local_ki = tree.child(_0,k).localIndex(i);
85 elementMatrix[local_ki][local_ki] += value_ii;
88 for (std::size_t j = i+1; j < numVelocityLocalFE; ++j) {
89 const auto value = vel_factor * (gradients[i] * gradients[j]);
90 for (std::size_t k = 0; k < CG::dow; ++k) {
91 const auto local_ki = tree.child(_0,k).localIndex(i);
92 const auto local_kj = tree.child(_0,k).localIndex(j);
93 elementMatrix[local_ki][local_kj] += value;
94 elementMatrix[local_kj][local_ki] += value;
99 if (!constViscosity_) {
101 for (std::size_t i = 0; i < numVelocityLocalFE; ++i) {
102 for (std::size_t kj = 0; kj < CG::dow; ++kj) {
103 const auto value_i_kj = vel_factor * gradients[i][kj];
104 for (std::size_t j = 0; j < numVelocityLocalFE; ++j) {
105 for (std::size_t ki = 0; ki < CG::dow; ++ki) {
106 const auto local_ki = tree.child(_0,ki).localIndex(i);
107 const auto local_kj = tree.child(_0,kj).localIndex(j);
108 elementMatrix[local_ki][local_kj] += value_i_kj * gradients[j][ki];
116 for (std::size_t i = 0; i < numVelocityLocalFE; ++i) {
117 for (std::size_t j = 0; j < numPressureLocalFE; ++j) {
118 const auto value = factor * pressureValues[j];
119 for (std::size_t k = 0; k < CG::dow; ++k) {
120 const auto local_v = tree.child(_0,k).localIndex(i);
121 const auto local_p = tree.child(_1).localIndex(j);
123 elementMatrix[local_v][local_p] += gradients[i][k] * value;
124 elementMatrix[local_p][local_v] += gradients[i][k] * value;