26#include <dune/grid/common/gridfactory.hh>
42#include <dune/assembler/backends/istlmatrixbackend.hh>
43#include <dune/assembler/backends/istlvectorbackend.hh>
44#include <dune/assembler/defaultglobalassembler.hh>
46#include <dune/vtk/datacollectors/discontinuouslagrangedatacollector.hh>
47#include <dune/vtk/datacollectors/lagrangedatacollector.hh>
48#include <dune/vtk/vtkwriter.hh>
59int main (
int argc,
char *argv[])
try
66 log(
"MPI initialized");
70 auto nu = parameters.get<
double>(
"viscosity", 1.0);
71 auto K = parameters.get<
double>(
"permeability", 1.0e-2);
72 auto alpha_BJS = parameters.get<
double>(
"alpha_BJS", 1.0);
73 auto g = parameters.get<
double>(
"gravity", 1.0);
74 auto meshFile = parameters.get<
std::string>(
"meshFile",
"stokes-darcy.msh");
75 auto StokesID = parameters.get<
int>(
"StokesID", 1);
76 auto DarcyID = parameters.get<
int>(
"DarcyID", 2);
77 auto refinements = parameters.get<
std::size_t>(
"refinements", 2);
79 log(
"Command line processed");
82 auto stokesVelocityDirichletValues = [](
auto x)
87 auto darcyDirichletValues = [](
auto x)
95 auto gridPtr = factory.createGrid();
96 auto& grid = *gridPtr;
103 elementData.update(gridView);
110 for(
auto&& element : elements(gridView))
111 if (elementData(element) == StokesID)
112 stokesDomain.insertElement(element);
114 log(
Dune::formatString(
"Stokes domain contains %d elements", stokesDomain.indexSet().size(0)));
117 for(
auto&& element : elements(gridView))
118 if (elementData(element) == DarcyID)
119 darcyDomain.insertElement(element);
121 log(
Dune::formatString(
"Darcy domain contains %d elements", darcyDomain.indexSet().size(0)));
124 log(
"Interface created");
126 for (
const auto& intersection :
Dune::Fufem::Boundary(gridView))
127 if (boundaryData(intersection) == StokesID)
128 stokesDirichletBoundary.insertFace(intersection);
131 for (
const auto& intersection :
Dune::Fufem::Boundary(gridView))
132 if (boundaryData(intersection) == DarcyID)
133 darcyDirichletBoundary.insertFace(intersection);
135 log(
"Dirichlet boundaries created");
140 auto basis = makeBasis(gridView,
144 power<dim>(lagrange<maxOrder>(), flatInterleaved()),
145 lagrange<maxOrder-1>(),
148 restrict(lagrange<maxOrder+1>(), darcyDomain),
164 auto stiffnessMatrix =
Matrix();
166 computeBoundaryConstraints(constraints, stokesVelocityBasis, stokesVelocityDirichletValues, stokesDirichletBoundary);
167 computeBoundaryConstraints(constraints, darcyBasis, darcyDirichletValues, darcyDirichletBoundary);
169 log(
"Boundary constraints computed");
172 auto u = trialFunction(stokesVelocityBasis);
173 auto p = trialFunction(stokesPressureBasis);
174 auto phi = trialFunction(darcyBasis);
176 auto v = testFunction(stokesVelocityBasis);
177 auto q = testFunction(stokesPressureBasis);
178 auto psi = testFunction(darcyBasis);
179 auto E = [&](
const auto& v) {
180 return symmetrize(grad(v));
184 auto P_tangent =
compose([&](
auto n) {
188 T[i][j] = (i==j) - n[i]*n[j];
198 auto assembler = Dune::Assembler::Assembler(basis, basis);
200 log(
"Assembler set up");
201 auto matrixBackend = Dune::Assembler::ISTLMatrixBackend(stiffnessMatrix);
202 auto rhsBackend = Dune::Assembler::ISTLVectorBackend(
rhs);
203 auto patternBuilder = matrixBackend.patternBuilder();
204 patternBuilder.resize(basis, basis);
205 assembler.assembleMatrixPattern(A, patternBuilder);
207 log(
"Matrix pattern assembled");
209 patternBuilder.setupMatrix();
211 log(
"Matrix set up");
212 assembler.assembleMatrixEntries(A, matrixBackend);
214 log(
"Matrix assembled");
215 rhsBackend.resize(basis);
216 rhsBackend.setZero();
218 log(
"RHS assembled");
219 constraints.constrainLinearSystem(stiffnessMatrix,
rhs);
221 log(
"Boundary condition incorporated into system");
222 auto solBackend = Dune::Assembler::ISTLVectorBackend(sol);
223 solBackend.resize(basis);
224 solBackend.setZero();
227 solver.setMatrix(stiffnessMatrix);
240 log(
"Solver created");
244 solver.apply(sol,
rhs, solverStatistics);
246 log(
"Linear system solved");
247 constraints.interpolate(sol);
249 log(
"Constrained solution interpolated");
250 auto vtkWriter = Dune::Vtk::UnstructuredGridWriter(Dune::Vtk::DiscontinuousLagrangeDataCollector(basis.gridView(), maxOrder));
251 vtkWriter.addPointData(u|sol,
Dune::VTK::FieldInfo(
"stokes_velocity", Dune::VTK::FieldInfo::Type::vector,
dim));
252 vtkWriter.addPointData(p|sol,
Dune::VTK::FieldInfo(
"stokes_pressure", Dune::VTK::FieldInfo::Type::scalar, 1));
253 vtkWriter.addPointData(phi|sol,
Dune::VTK::FieldInfo(
"darcy_pressure", Dune::VTK::FieldInfo::Type::scalar, 1));
255 vtkWriter.addPointData((p+phi)|sol,
Dune::VTK::FieldInfo(
"pressure", Dune::VTK::FieldInfo::Type::scalar, 1));
257 vtkWriter.write(
"stokes-darcy");
259 log(
"Solution written to vtk file");
int main(int argc, char **argv)
field_type dot(const type &newv) const
auto subspaceBasis(const RootBasis &rootBasis, const TypeTree::TreePath< PrefixTreeIndices... > &prefixPath)
static std::string formatString(const std::string &s, const T &... args)
const char * what() const noexcept override
auto makeAffineConstraints(const Basis &basis)
Create and initialize an AffineConstraints object for a basis.
Definition affineconstraints.hh:825
auto outside(const Op &op)
Construct outside version of a given operator.
Definition userfunctions.hh:862
auto faceNormal(const GridView &gridView)
Construct operator representing the face normals.
Definition userfunctions.hh:965
auto jacobian(const FEFunctionOperator< B, TP, argIndex > &op)
Obtain the jacobian of an operator.
Definition userfunctions.hh:1063
auto grad(const Op &op)
Obtain the gradient of an operator.
Definition userfunctions.hh:1186
auto compose(const OuterOp &outerOp, const InnerOp &innerOp)
Generic composition of a multilinear operators with a pointwise outer operator.
Definition userfunctions.hh:483
::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
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
Class for storing data associated to boundary segments.
Definition boundarydata.hh:44
Class for storing data associated to elements.
Definition elementdata.hh:47