Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
poisson-periodic.cc

Commented version of this example This example on gitlab

1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3
4// SPDX-FileCopyrightText: Copyright © DUNE-FUFEM Project contributors, see file AUTHORS.md
5// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception OR LGPL-3.0-or-later
6
7#include <config.h>
8
9#include <vector>
10#include <cmath>
11#include <numbers>
12#include <thread>
13
20
21#include <dune/geometry/type.hh>
22
23#include <dune/grid/uggrid.hh>
24
25#include <dune/istl/bvector.hh>
28#include <dune/istl/solvers.hh>
29
35
36#include <dune/vtk/vtkwriter.hh>
37#include <dune/vtk/datacollectors/lagrangedatacollector.hh>
38
39#include <dune/assembler/backends/istlvectorbackend.hh>
40#include <dune/assembler/backends/istlmatrixbackend.hh>
41#include <dune/assembler/defaultglobalassembler.hh>
42
43#include <dune/assembler/parallel/gridcoloring.hh>
44#include <dune/assembler/parallel/coloredrangeexecutor.hh>
45
46#include <dune/fufem/logger.hh>
55
56#include "utilities.hh"
57
58int main (int argc, char *argv[]) try
59{
60
61 auto log = Dune::Fufem::makeLogger(std::cout, "[% 8.3f] [% 8.3f] ");
62
63 auto parameters = Dune::ParameterTree();
64 Dune::ParameterTreeParser::readOptions(argc, argv, parameters);
65
66 auto refinements = parameters.get<std::size_t>("refinements", 3);
67 auto threadCount = parameters.get<std::size_t>("threads", std::thread::hardware_concurrency());
68 auto tol = parameters.get<double>("tol", 1e-4);
69 auto maxIter = parameters.get<std::size_t>("maxIter", 1000);
70 auto verbosity = parameters.get<std::size_t>("verbosity", 2);
71
72 log("Command line processed");
73
74 Dune::MPIHelper::instance(argc, argv);
75
76 log("MPI initialized");
77 auto dirichletIndicator = [&](auto x) {
78 return (x[1] <= 0.25) or (x[1] > 0.75);
79 };
80
81 auto dirichletValues = [](const auto& x){ return 0; };
82
83 auto rightHandSide = [] (const auto& x) { return 20*(x[0]>=.5);};
84 using Grid = Dune::UGGrid<2>;
85
86 auto factory = Dune::GridFactory<Grid>();
87 for(unsigned int k : Dune::range(9))
88 factory.insertVertex({0.5*(k%3), 0.5*(k/3)});
89 factory.insertElement(Dune::GeometryTypes::cube(2), {0, 1, 3, 4});
90 factory.insertElement(Dune::GeometryTypes::cube(2), {1, 2, 4, 5});
91 factory.insertElement(Dune::GeometryTypes::simplex(2), {3, 4, 6});
92 factory.insertElement(Dune::GeometryTypes::simplex(2), {4, 7, 6});
93 factory.insertElement(Dune::GeometryTypes::simplex(2), {4, 5, 7});
94 factory.insertElement(Dune::GeometryTypes::simplex(2), {5, 8, 7});
95 factory.insertBoundarySegment({0, 3});
96 factory.insertBoundarySegment({3, 6});
97 factory.insertBoundarySegment({2, 5});
98 factory.insertBoundarySegment({5, 8});
99 constexpr int leftID = 0;
100 constexpr int rightID = 1;
101 auto boundaryIDs = std::vector({leftID, leftID, rightID, rightID});
102 auto periodicRightToLeft = [](auto x) {
103 x[0] -= 1.0;
104 return x;
105 };
106 auto gridPtr = std::unique_ptr(factory.createGrid());
107 auto& grid = *gridPtr;
108
109 log("Grid created");
110 auto boundaryData = Dune::Fufem::BoundaryData(boundaryIDs, factory, grid);
111 grid.globalRefine(refinements);
112
113 log(Dune::formatString("Grid refined %d times", refinements));
114
115 auto gridView = grid.leafGridView();
116 auto dirichletPatch = Dune::Fufem::BoundaryPatch(gridView);
117 auto periodicLeftPatch = Dune::Fufem::BoundaryPatch(gridView);
118 auto periodicRightPatch = Dune::Fufem::BoundaryPatch(gridView);
119 for (const auto& intersection : Dune::Fufem::Boundary(gridView))
120 {
121 if (dirichletIndicator(intersection.geometry().center()))
122 dirichletPatch.insertFace(intersection);
123 if (boundaryData(intersection) == leftID)
124 periodicLeftPatch.insertFace(intersection);
125 if (boundaryData(intersection) == rightID)
126 periodicRightPatch.insertFace(intersection);
127 }
128
129 log("Boundary patches set up");
130 auto coloredRange = Dune::Assembler::Experimental::coloredElementRange(gridView);
131
132 log("Grid coloring computed");
133
134 auto executor = Dune::Assembler::Experimental::ColoredRangeExecutor(coloredRange, threadCount);
135
136 log(Dune::formatString("Using parallelism with %d threads", threadCount));
137 using namespace Dune::Functions::BasisFactory;
138 auto basis = makeBasis(gridView, lagrange<2>());
139
140 log(Dune::formatString("Basis created with dimension %d", basis.dimension()));
143
144 auto sol = Vector();
145 auto rhs = Vector();
146 auto stiffnessMatrix = Matrix();
147 auto constraints = Dune::Fufem::makeAffineConstraints(basis);
148
149 Dune::Fufem::computeBoundaryConstraints(constraints, basis, dirichletValues, dirichletPatch);
150
151 log("Boundary constraints computed");
152
153 Dune::Fufem::computePeriodicConstraints(constraints, basis, periodicLeftPatch, periodicRightPatch, periodicRightToLeft);
154
155 log("Periodic constraints computed");
156 using namespace Dune::Fufem::Forms;
157
158 auto u = trialFunction(basis);
159 auto v = testFunction(basis);
160 auto f = Coefficient(Dune::Functions::makeGridViewFunction(rightHandSide, gridView));
161
162 auto a = integrate(dot(grad(u), grad(v)));
163 auto l = integrate(f*v);
164 auto matrixBackend = Dune::Assembler::ISTLMatrixBackend(stiffnessMatrix);
165 auto rhsBackend = Dune::Assembler::ISTLVectorBackend(rhs);
166 auto assembler = Dune::Assembler::Assembler(basis, basis, executor);
167
168 log("Assembler set up");
169 auto patternBuilder = matrixBackend.patternBuilder();
170
171 patternBuilder.resize(basis, basis);
172
173 assembler.assembleMatrixPattern(a, patternBuilder);
174
175 constraints.extendMatrixPattern(patternBuilder, basis);
176
177 log("Matrix pattern assembled");
178 patternBuilder.setupMatrix();
179
180 log("Matrix set up");
181
182 assembler.assembleMatrixEntries(a, matrixBackend);
183
184 log("Matrix assembled");
185 rhsBackend.resize(basis);
186 rhsBackend.setZero();
187
188 assembler.assembleVectorEntries(l, rhsBackend);
189
190 log("RHS assembled");
191 constraints.constrainLinearSystem(stiffnessMatrix, rhs);
192
193 log("Boundary condition incorporated into system");
194 Dune::Assembler::ISTLVectorBackend(sol).resize(basis);
195 Dune::Assembler::ISTLVectorBackend(sol).setZero();
196 auto matrixOperator = Dune::MatrixAdapter<Matrix,Vector,Vector>(stiffnessMatrix);
197
198 auto preconditioner = makeAMGPreconditioner<Vector>(stiffnessMatrix);
199
200 log("Preconditioner created");
201
202 auto solver = Dune::CGSolver<Vector>(
203 matrixOperator,
204 preconditioner,
205 tol,
206 maxIter,
207 verbosity
208 );
209
210 log("Solver created");
211
212 auto solverStatistics = Dune::InverseOperatorResult();
213
214 solver.apply(sol, rhs, solverStatistics);
215
216 log("Linear system solved");
217 constraints.interpolate(sol);
218
219 log("Constrained solution interpolated");
220 auto vtkWriter = Dune::Vtk::UnstructuredGridWriter(Dune::Vtk::LagrangeDataCollector(basis.gridView(), 2));
221 vtkWriter.addPointData(u|sol, Dune::VTK::FieldInfo("sol", Dune::VTK::FieldInfo::Type::scalar, 1));
222 vtkWriter.write("poisson-periodic");
223
224 log("Solution written to vtk file");
225}
226catch (Dune::Exception& e)
227{
228 std::cout << e.what() << std::endl;
229 return 1;
230}
int main(int argc, char **argv)
field_type dot(const type &newv) const
Y & rhs()
std::decay_t< F > makeGridViewFunction(F &&f, const GridView &gridView)
auto makeBasis(const GridView &gridView, PreBasisFactory &&preBasisFactory)
static std::string formatString(const std::string &s, const T &... args)
const char * what() const noexcept override
void computePeriodicConstraints(AffineConstraints< BV, V, MI, C > &constraints, const PrimaryBasis &primaryBasis, const PrimaryPatch &primaryPatch, const SecondaryBasis &secondaryBasis, const SecondaryPatch &secondaryPatch, const SecondaryToPrimary &secondaryToPrimary)
Compute constraints for periodic boundary conditions.
Definition periodicconstraints.hh:64
void computeBoundaryConstraints(AffineConstraints< BV, V, MI, C > &constraints, const Basis &basis, Function &&f, const IntersectionSet &intersectionSet)
Compute constraints for essential boundary conditions.
Definition boundaryconstraints.hh:51
auto makeAffineConstraints(const Basis &basis)
Create and initialize an AffineConstraints object for a basis.
Definition affineconstraints.hh:825
auto testFunction(const Basis &basis)
Create unary identity operator on test function space.
Definition userfunctions.hh:694
auto trialFunction(const Basis &basis)
Create unary identity operator on trial function space.
Definition userfunctions.hh:773
auto grad(const Op &op)
Obtain the gradient of an operator.
Definition userfunctions.hh:1186
::value auto integrate(MultilinearOperator op, const Domain &domain)
Integrate a k-linear operator to obtain a k-linear form.
Definition integrate.hh:53
auto makeLogger(std::ostream &stream, std::string format)
Create a simple logger callback.
Definition logger.hh:42
Definition baseclass.hh:22
const Grid & grid() const
static DUNE_EXPORT MPIHelper & instance(int &argc, char **&argv)
static void readOptions(int argc, char *argv[], ParameterTree &pt)
LeafGridView leafGridView() const
void globalRefine(int refCount)
Encapsulate a subset of the boundary intersections of a GridView.
Definition domains/boundarypatch.hh:37
Coefficient function.
Definition coefficient.hh:42
Class for storing data associated to boundary segments.
Definition boundarydata.hh:44
T endl(T... args)
T hardware_concurrency(T... args)
T log(T... args)