37template <
class LocalView,
class MatrixType>
38void getLocalMatrix(
const LocalView& localView, MatrixType& elementMatrix)
41 typedef typename LocalView::Element Element;
42 const Element& element = localView.element();
44 const int dim = Element::dimension;
45 auto geometry = element.geometry();
48 const auto& localFiniteElement = localView.tree().finiteElement();
51 elementMatrix.setSize(localFiniteElement.localBasis().size(),localFiniteElement.localBasis().size());
55 int order = 2*(
dim*localFiniteElement.localBasis().order()-1);
59 for (
size_t pt=0; pt < quad.size(); pt++) {
65 const auto& jacobianInverse = geometry.jacobianInverse(quadPos);
68 const double integrationElement = geometry.integrationElement(quadPos);
72 localFiniteElement.localBasis().evaluateJacobian(quadPos, referenceJacobians);
76 for (
size_t i=0; i<jacobians.size(); i++)
77 jacobians[i] = referenceJacobians[i] * jacobianInverse;
80 for (
size_t i=0; i<elementMatrix.N(); i++)
81 for (
size_t j=0; j<elementMatrix.M(); j++ )
82 elementMatrix[i][j] += (jacobians[i] * transpose(jacobians[j]))[0][0] * quad[pt].weight() * integrationElement;
91template <
class LocalView,
class LocalVolumeTerm>
92void getVolumeTerm(
const LocalView& localView,
94 LocalVolumeTerm&& localVolumeTerm)
97 typedef typename LocalView::Element Element;
98 const Element& element = localView.element();
100 const int dim = Element::dimension;
103 const auto& localFiniteElement = localView.tree().finiteElement();
106 localRhs.
resize(localFiniteElement.localBasis().size());
110 int order =
dim*localFiniteElement.localBasis().order();
114 for (
size_t pt=0; pt < quad.size(); pt++ ) {
120 const double integrationElement = element.geometry().integrationElement(quadPos);
122 double functionValue = localVolumeTerm(quadPos);
126 localFiniteElement.localBasis().evaluateFunction(quadPos, shapeFunctionValues);
129 for (
size_t i=0; i<localRhs.size(); i++)
130 localRhs[i] += shapeFunctionValues[i] * functionValue * quad[pt].weight() * integrationElement;
139template <
class FEBasis>
140void getOccupationPattern(
const FEBasis& feBasis,
MatrixIndexSet& nb)
143 auto n = feBasis.
size();
148 auto localView = feBasis.localView();
151 for(
const auto& e :
elements(feBasis.gridView()))
157 for (
size_t i=0; i<localView.tree().
size(); i++) {
159 for (
size_t j=0; j<localView.tree().
size(); j++) {
161 auto iIdx = localView.index(i);
162 auto jIdx = localView.index(j);
178template <
class FEBasis,
class VolumeTerm>
179void assembleLaplaceMatrix(
const FEBasis& feBasis,
182 VolumeTerm&& volumeTerm)
185 typedef typename FEBasis::GridView
GridView;
186 GridView gridView = feBasis.gridView();
188 auto localVolumeTerm = localFunction(Functions::makeGridViewFunction(volumeTerm, gridView));
196 getOccupationPattern(feBasis, occupationPattern);
202 rhs.resize(feBasis.size());
209 auto localView = feBasis.localView();
212 for(
const auto& e :
elements(gridView))
221 getLocalMatrix(localView, elementMatrix);
224 for (
size_t i=0; i<elementMatrix.
N(); i++) {
227 auto row = localView.index(i);
229 for (
size_t j=0; j<elementMatrix.
M(); j++ ) {
232 auto col = localView.index(j);
241 localVolumeTerm.bind(e);
242 getVolumeTerm(localView, localRhs, localVolumeTerm);
244 for (
size_t i=0; i<localRhs.size(); i++) {
247 auto row = localView.index(i);
248 rhs[row] += localRhs[i];
266template <
class FEBasis>
267void boundaryTreatment (
const FEBasis& feBasis,
std::vector<char>& dirichletNodes )
269 dirichletNodes.
clear();
270 dirichletNodes.
resize(feBasis.size(),
false);
272 Functions::forEachBoundaryDOF(feBasis, [&] (
auto&&
index) {
273 dirichletNodes[
index] =
true;
279auto createMixedGrid()
283 for(
unsigned int k :
Dune::range(9))
284 factory.insertVertex({0.5*(k%3), 0.5*(k/3)});
285 factory.
insertElement(Dune::GeometryTypes::cube(2), {0, 1, 3, 4});
286 factory.
insertElement(Dune::GeometryTypes::cube(2), {1, 2, 4, 5});
287 factory.
insertElement(Dune::GeometryTypes::simplex(2), {3, 4, 6});
288 factory.
insertElement(Dune::GeometryTypes::simplex(2), {4, 7, 6});
289 factory.
insertElement(Dune::GeometryTypes::simplex(2), {4, 5, 7});
290 factory.
insertElement(Dune::GeometryTypes::simplex(2), {5, 8, 7});
296int main (
int argc,
char *argv[])
try
299 MPIHelper::instance(argc, argv);
307 auto grid = createMixedGrid();
312 using GridView =
decltype(gridView);
321 FEBasis feBasis(gridView);
333 MatrixType stiffnessMatrix;
341 auto rightHandSide = [] (
const auto& x) {
return 10;};
344 assembleLaplaceMatrix(feBasis, stiffnessMatrix,
rhs, rightHandSide);
350 VectorType x(feBasis.size());
355 boundaryTreatment(feBasis, dirichletNodes);
361 auto dirichletValueFunction = [pi](
const auto& x){
return std::sin(2*pi*x[0]); };
364 interpolate(feBasis, x, dirichletValueFunction, dirichletNodes);
373 stiffnessMatrix.mmv(x,
rhs);
376 for (
size_t i=0; i<stiffnessMatrix.N(); i++) {
377 if (dirichletNodes[i]) {
380 for (
auto&& [entry, idx] :
sparseRange(stiffnessMatrix[i]))
381 entry = (i==idx) ? 1.0 : 0.0;
385 for (
auto&& [entry, idx] :
sparseRange(stiffnessMatrix[i]))
386 if (dirichletNodes[idx])
412 cg.apply(x,
rhs, statistics);
418 auto xFunction = Functions::makeDiscreteGlobalBasisFunction<double>(feBasis, x);
425 vtkWriter.addVertexData(xFunction,
VTK::FieldInfo(
"x", VTK::FieldInfo::Type::scalar, 1));
426 vtkWriter.write(
"poisson-pq2");
int main(int argc, char **argv)
OperatorHierarchy::ParallelMatrixHierarchy::ConstIterator matrix
RefinementIntervals refinementLevels(int levels)
void interpolate(const B &basis, C &&coeff, const F &f, const BV &bv, const NTRE &nodeToRangeEntry)
Interpolate given function in discrete function space.
Definition interpolate.hh:205
auto sparseRange(Range &&range)
std::ptrdiff_t index() const
const char * what() const noexcept override
const Grid & grid() const
IteratorRange<... > elements(const GV &gv)
void resize(size_type size)
void resize(size_type rows, size_type cols)
void exportIdx(MatrixType &matrix) const
void add(size_type row, size_type col)
double elapsed() const noexcept
LeafGridView leafGridView() const
void globalRefine(int refCount)
virtual void insertElement(const GeometryType &type, const std::vector< unsigned int > &vertices)
virtual std::unique_ptr< GridType > createGrid()
Global basis for given pre-basis.
Definition defaultglobalbasis.hh:53