Dune-Fufem 2.11-git
Loading...
Searching...
No Matches
linear-elasticity.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 <array>
10#include <cmath>
11#include <cstddef>
12#include <iostream>
13#include <string>
14#include <vector>
15
22
23#include <dune/grid/utility/structuredgridfactory.hh>
24#include <dune/grid/yaspgrid.hh>
25
27#include <dune/istl/bvector.hh>
28#include <dune/istl/cholmod.hh>
31#include <dune/istl/solvers.hh>
32
36
37#include <dune/vtk/datacollectors/discontinuouslagrangedatacollector.hh>
38#include <dune/vtk/vtkwriter.hh>
39
40#include <dune/assembler/backends/istlmatrixbackend.hh>
41#include <dune/assembler/backends/istlvectorbackend.hh>
42#include <dune/assembler/defaultglobalassembler.hh>
43#include <dune/assembler/parallel/coloredrangeexecutor.hh>
44#include <dune/assembler/parallel/gridcoloring.hh>
45
51#include <dune/fufem/logger.hh>
52
53int main (int argc, char *argv[]) try
54{
55 auto log = Dune::Fufem::makeLogger(std::cout, "[% 8.3f] [% 8.3f] ");
56
57 auto parameters = Dune::ParameterTree();
58 Dune::ParameterTreeParser::readOptions(argc, argv, parameters);
59
60 auto refinements = parameters.get<std::size_t>("refinements", 1);
61 auto threadCount = parameters.get<std::size_t>("threads", std::thread::hardware_concurrency());
62#if not(HAVE_SUITESPARSE_CHOLMOD)
63 auto tol = parameters.get<double>("tol", 1e-4);
64 auto maxIter = parameters.get<std::size_t>("maxIter", 1000);
65 auto verbosity = parameters.get<std::size_t>("verbosity", 2);
66#endif
67
68 log("Command line processed");
69
70 Dune::MPIHelper::instance(argc, argv);
71
72 log("MPI initialized");
73 const int dim = 3;
74
75 using LocalVector = Dune::FieldVector<double,dim>;
76 using LocalMatrix = Dune::FieldMatrix<double,dim,dim>;
77 double E_Young = 200e9; // in Pa = N/m^2 = 10^9 GPa
78 double nu = 0.3;
79
80 double lambda = E_Young*nu/((1.-2.*nu) * (1.+nu));
81 double mu = E_Young/(2*(1+nu));
82
83 double rho = 7.85e3; // in kg/m^3 = 10^3 g/cm^3
84 double g_n = 9.80665; // in m/s^2 = N/kg
85 auto g = LocalVector({0.0, -g_n*rho, 0.0});
86 double thickness = .01;
87 double length = 1.0;
88
89 auto dirichletIndicator = [](auto x) { return x[0] <= 1e-10; };
90 auto dirichletValues = [](const auto& x){ return LocalVector(0.0); };
91 using Grid = Dune::YaspGrid<dim>;
92
93 auto lowerCorner = LocalVector({0, 0, 0});
94 auto upperCorner = LocalVector({length, thickness, thickness});
95 auto elementCount = std::array{(unsigned int)(length/thickness), 1u, 1u};
96
97 auto gridPtr = Dune::StructuredGridFactory<Grid>::createCubeGrid(lowerCorner, upperCorner, elementCount);
98 auto& grid = *gridPtr;
99
100 log("Grid created");
101
102 grid.globalRefine(refinements);
103
104 log(Dune::formatString("Grid refined %d times", refinements));
105
106 auto gridView = grid.leafGridView();
107 auto dirichletPatch = Dune::Fufem::BoundaryPatch(gridView);
108 for (const auto& intersection : Dune::Fufem::Boundary(gridView))
109 if (dirichletIndicator(intersection.geometry().center()))
110 dirichletPatch.insertFace(intersection);
111
112 log("Boundary patch set up");
113 auto coloredRange = Dune::Assembler::Experimental::coloredElementRange(gridView);
114
115 log("Grid coloring computed");
116
117 auto executor = Dune::Assembler::Experimental::ColoredRangeExecutor(coloredRange, threadCount);
118
119 log(Dune::formatString("Using parallelism with %d threads", threadCount));
120 const int order = 2;
121
122 using namespace Dune::Functions::BasisFactory;
123 auto basis = makeBasis(gridView, power<dim>(lagrange<order>(), blockedInterleaved()));
124
125 log(Dune::formatString("Basis created with dimension %d", basis.dimension()));
127 using BitVector = std::vector<std::array<char,dim>>;
129
130 auto sol = Vector();
131 auto rhs = Vector();
132 auto stiffnessMatrix = Matrix();
133 auto constraints = Dune::Fufem::makeAffineConstraints<BitVector, Vector>(basis);
134
135 Dune::Fufem::computeBoundaryConstraints(constraints, basis, dirichletValues, dirichletPatch);
136
137 log("Boundary constraints computed");
138 using namespace Dune::Fufem::Forms;
139
140 auto u = trialFunction(basis);
141 auto v = testFunction(basis);
142
144
145 auto E = [&](const auto& v) {
146 return symmetrize(grad(v));
147 };
148
149 auto sigma = 2*mu*E(u) + lambda*Id*trace(E(u));
150
151 auto a = integrate(dot(sigma, E(v)));
152 auto l = integrate(dot(g,v));
153 auto matrixBackend = Dune::Assembler::ISTLMatrixBackend(stiffnessMatrix);
154 auto rhsBackend = Dune::Assembler::ISTLVectorBackend(rhs);
155 auto assembler = Dune::Assembler::Assembler(basis, basis, executor);
156
157 log("Assembler set up");
158 auto patternBuilder = matrixBackend.patternBuilder();
159
160 patternBuilder.resize(basis, basis);
161
162 assembler.assembleMatrixPattern(a, patternBuilder);
163
164 log("Matrix pattern assembled");
165 patternBuilder.setupMatrix();
166
167 log("Matrix set up");
168
169 assembler.assembleMatrixEntries(a, matrixBackend);
170
171 log("Matrix assembled");
172 rhsBackend.resize(basis);
173 rhsBackend.setZero();
174
175 assembler.assembleVectorEntries(l, rhsBackend);
176
177 log("RHS assembled");
178 constraints.constrainLinearSystem(stiffnessMatrix, rhs);
179
180 log("Boundary condition incorporated into system");
181 Dune::Assembler::ISTLVectorBackend(sol).resize(basis);
182 Dune::Assembler::ISTLVectorBackend(sol).setZero();
183#if HAVE_SUITESPARSE_CHOLMOD
184 auto solver = Dune::Cholmod<Vector>();
185 solver.setMatrix(stiffnessMatrix);
186#else
187 auto matrixOperator = Dune::MatrixAdapter<Matrix,Vector,Vector>(stiffnessMatrix);
188 auto preconditioner = Dune::SeqILDL<Matrix,Vector,Vector>(stiffnessMatrix, 1.0);
189
190 log("Preconditioner created");
191
192 auto solver = Dune::CGSolver<Vector>(
193 matrixOperator,
194 preconditioner,
195 tol,
196 maxIter,
197 verbosity
198 );
199#endif
200
201 log("Solver created");
202
203 auto solverStatistics = Dune::InverseOperatorResult();
204
205 solver.apply(sol, rhs, solverStatistics);
206
207 log("Linear system solved");
208 auto sigma_vol = 1./3. * trace(sigma);
209 auto sigma_dev = sigma - sigma_vol*Id;
210 auto sqrt = RangeOperator([](const auto& z) { return std::sqrt(z); });
211 auto sigma_von_Mises_sol = sqrt(3./2.*Dune::Fufem::Forms::dot(sigma_dev|sol, sigma_dev|sol));
212 auto vtkWriter = Dune::Vtk::UnstructuredGridWriter(Dune::Vtk::DiscontinuousLagrangeDataCollector(gridView, order));
213 vtkWriter.addPointData(u|sol, Dune::VTK::FieldInfo("u", Dune::VTK::FieldInfo::Type::vector, dim));
214 vtkWriter.addPointData(E(u)|sol, Dune::VTK::FieldInfo("Eu", Dune::VTK::FieldInfo::Type::tensor, dim*dim));
215 vtkWriter.addPointData(sigma|sol, Dune::VTK::FieldInfo("sigma", Dune::VTK::FieldInfo::Type::tensor, dim*dim));
216 vtkWriter.addPointData(sigma_dev|sol, Dune::VTK::FieldInfo("sigma_dev", Dune::VTK::FieldInfo::Type::tensor, dim*dim));
217 vtkWriter.addPointData(sigma_vol|sol, Dune::VTK::FieldInfo("sigma_vol", Dune::VTK::FieldInfo::Type::scalar, 1));
218 vtkWriter.addPointData(sigma_von_Mises_sol, Dune::VTK::FieldInfo("sigma_von_Mises", Dune::VTK::FieldInfo::Type::scalar, 1));
219 vtkWriter.write("linear-elasticity");
220
221 log("Solution written to vtk file");
222}
223catch (Dune::Exception& e) {
224 std::cout << e.what() << std::endl;
225 return 1;
226}
int main(int argc, char **argv)
field_type dot(const type &newv) const
Y & rhs()
constexpr BlockedInterleaved blockedInterleaved()
auto makeBasis(const GridView &gridView, PreBasisFactory &&preBasisFactory)
static std::string formatString(const std::string &s, const T &... args)
size_type dim() const
const char * what() const noexcept override
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 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
auto dot(const L &l, const R &r)
Exterior product of two multilinear operators based on pointwise dot-product.
Definition userfunctions.hh:458
auto trace(const Op &op)
Transform an operator by pointwise computation of the matrix trace.
Definition userfunctions.hh:595
auto symmetrize(const Op &op)
Transform an operator by pointwise matrix symmetrization.
Definition userfunctions.hh:577
::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
ALBERTA REAL_B LocalVector
static DUNE_EXPORT MPIHelper & instance(int &argc, char **&argv)
static void readOptions(int argc, char *argv[], ParameterTree &pt)
static void createCubeGrid(GridFactory< GridType > &factory, const FieldVector< ctype, dimworld > &lowerLeft, const FieldVector< ctype, dimworld > &upperRight, const std::array< unsigned int, dim > &elements)
LeafGridView leafGridView() const
void globalRefine(int refCount)
Encapsulate a subset of the boundary intersections of a GridView.
Definition domains/boundarypatch.hh:37
Adaptor for making a callback compatible with Dune::Fufem::Forms.
Definition userfunctions.hh:510
T endl(T... args)
T hardware_concurrency(T... args)
T log(T... args)
T sqrt(T... args)