HArD::Core3D
Hybrid Arbitrary Degree::Core 3D - Library to implement 3D schemes with vertex, edge, face and cell polynomials as unknowns
Loading...
Searching...
No Matches
sddr-stokes.hpp
Go to the documentation of this file.
1// Implementation of the discrete de Rham sequence for the Stokes problem in curl-curl formulation.
2//
3// Author: Jerome Droniou (jerome.droniou@monash.edu)
4//
5
6
7#ifndef SDDR_STOKES_HPP
8#define SDDR_STOKES_HPP
9
10#include <iostream>
11
12#include <boost/math/constants/constants.hpp>
13
14#include <Eigen/Sparse>
15#include <unsupported/Eigen/SparseExtra>
16
17#include <mesh.hpp>
18#include <mesh_builder.hpp>
20
21#include <sxgrad.hpp>
22#include <sxcurl.hpp>
23#include <sxdiv.hpp>
24
30namespace HArDCore3D
31{
32
39 struct StokesNorms
40 {
42 StokesNorms(double norm_u, double norm_curl_u, double norm_p, double norm_grad_p):
43 u(norm_u),
45 p(norm_p),
47 hcurl_u( std::sqrt( std::pow(norm_u, 2) + std::pow(norm_curl_u, 2) ) ),
48 hgrad_p( std::sqrt( std::pow(norm_p, 2) + std::pow(norm_grad_p, 2) ) )
49 {
50 // do nothing
51 };
52
53 // Constructor without arguments
54 StokesNorms() : StokesNorms(0., 0., 0., 0.) {};
55
56 double u;
57 double curl_u;
58 double p;
59 double grad_p;
60 double hcurl_u;
61 double hgrad_p;
62
63 };
64
66 struct Stokes
67 {
68 typedef Eigen::SparseMatrix<double> SystemMatrixType;
69
70 typedef std::function<Eigen::Vector3d(const Eigen::Vector3d &)> ForcingTermType;
71 typedef std::function<Eigen::Vector3d(const Eigen::Vector3d &)> VelocityType;
72 typedef std::function<Eigen::Vector3d(const Eigen::Vector3d &)> VorticityType;
73 typedef std::function<double(const Eigen::Vector3d &)> PressureType;
74 typedef std::function<Eigen::Vector3d(const Eigen::Vector3d &)> PressureGradientType;
76
79 const DDRCore & ddrcore,
80 bool use_threads,
81 std::ostream & output = std::cout
82 );
83
86 const ForcingTermType & f,
87 const VelocityType & u,
88 const VorticityType & omega,
89 const ViscosityType & nu
90 );
91
93 inline size_t dimensionSpace() const
94 {
95 return m_sxcurl.dimension() + m_sxgrad.dimension();
96 }
97
99 inline size_t nbSCDOFs_u() const
100 {
101 return m_nloc_sc_u.sum();
102 }
103
105 inline size_t nbSCDOFs_p() const
106 {
107 return m_nloc_sc_p.sum();
108 }
109
111 inline size_t nbSCDOFs() const
112 {
113 return nbSCDOFs_u() + nbSCDOFs_p();
114 }
115
117 inline size_t sizeSystem() const
118 {
119 return dimensionSpace() + 1 - nbSCDOFs();
120 }
121
123 inline const SXGrad & sxGrad() const
124 {
125 return m_sxgrad;
126 }
127
129 inline const SXCurl & sxCurl() const
130 {
131 return m_sxcurl;
132 }
133
135 inline const SXDiv & sxDiv() const
136 {
137 return m_sxdiv;
138 }
139
141 inline const SystemMatrixType & systemMatrix() const {
142 return m_A;
143 }
144
147 return m_A;
148 }
149
151 inline const Eigen::VectorXd & systemVector() const {
152 return m_b;
153 }
154
156 inline Eigen::VectorXd & systemVector() {
157 return m_b;
158 }
159
161 inline const SystemMatrixType & scMatrix() const {
162 return m_sc_A;
163 }
164
166 inline Eigen::VectorXd & scVector() {
167 return m_sc_b;
168 }
169
171 inline const double & stabilizationParameter() const {
172 return m_stab_par;
173 }
174
176 inline double & stabilizationParameter() {
177 return m_stab_par;
178 }
179
181 std::vector<StokesNorms> computeStokesNorms(
182 const std::vector<Eigen::VectorXd> & list_dofs
183 ) const;
184
186 std::pair<StokesNorms, StokesNorms> computeContinuousErrorsNorms(
187 const Eigen::VectorXd & v,
188 const VelocityType & u,
189 const VorticityType & curl_u,
190 const PressureType & p,
191 const PressureGradientType & grad_p
192 ) const;
193
194
195 private:
197 std::pair<Eigen::MatrixXd, Eigen::VectorXd>
198 _compute_local_contribution(
199 size_t iT,
200 const Eigen::VectorXd & interp_f,
201 const ViscosityType & nu
202 );
203
205 LocalStaticCondensation _compute_static_condensation(const size_t & iT) const;
206
208 void _assemble_local_contribution(
209 size_t iT,
210 const std::pair<Eigen::MatrixXd, Eigen::VectorXd> & lsT,
211 std::list<Eigen::Triplet<double> > & A1,
212 Eigen::VectorXd & b1,
213 std::list<Eigen::Triplet<double> > & A2,
214 Eigen::VectorXd & b2
215 );
216
217 const DDRCore & m_ddrcore;
218 bool m_use_threads;
219 std::ostream & m_output;
220 SerendipityProblem m_ser_pro;
221 const SXGrad m_sxgrad;
222 const SXCurl m_sxcurl;
223 const SXDiv m_sxdiv;
224 const Eigen::VectorXi m_nloc_sc_u; // Nb of statically condensed DOFs for velocity in each cell (cell unknowns)
225 const Eigen::VectorXi m_nloc_sc_p; // Nb of statically condensed DOFs for pressure in each cell (cell unknowns)
226 SystemMatrixType m_A; // Matrix and RHS of statically condensed system
227 Eigen::VectorXd m_b;
228 SystemMatrixType m_sc_A; // Static condensation operator and RHS (to recover statically condensed DOFs)
229 Eigen::VectorXd m_sc_b;
230 double m_stab_par;
231 };
232
233 //------------------------------------------------------------------------------
234 // Exact solutions
235 //------------------------------------------------------------------------------
236
237 static const double PI = boost::math::constants::pi<double>();
238 using std::sin;
239 using std::cos;
240 using std::pow;
241
242 //------------------------------------------------------------------------------
243 // Trigonometric solution
244 //------------------------------------------------------------------------------
245
246 double pressure_scaling = 1.;
248 trigonometric_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
249 return Eigen::Vector3d(
250 0.5 * sin(2. * PI * x(0)) * cos(2. * PI * x(1)) * cos(2. * PI * x(2)),
251 0.5 * cos(2. * PI * x(0)) * sin(2. * PI * x(1)) * cos(2. * PI * x(2)),
252 -cos(2. * PI * x(0)) * cos(2. * PI * x(1)) * sin(2. * PI * x(2))
253 );
254 };
255
257 trigonometric_curl_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
258 return 3. * PI * Eigen::Vector3d(
259 cos(2. * PI * x(0)) * sin(2. * PI * x(1)) * sin(2. * PI * x(2)),
260 -sin(2. * PI * x(0)) * cos(2. * PI * x(1)) * sin(2. * PI * x(2)),
261 0.
262 );
263 };
264
266 trigonometric_p = [](const Eigen::Vector3d & x) -> double {
267 return pressure_scaling * sin(2. * PI * x(0)) * sin(2. * PI * x(1)) * sin(2. * PI * x(2));
268 };
269
271 trigonometric_grad_p = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
272 return pressure_scaling * 2. * PI * Eigen::Vector3d(
273 cos(2. * PI * x(0)) * sin(2. * PI * x(1)) * sin(2. * PI * x(2)),
274 sin(2. * PI * x(0)) * cos(2. * PI * x(1)) * sin(2. * PI * x(2)),
275 sin(2. * PI * x(0)) * sin(2. * PI * x(1)) * cos(2. * PI * x(2))
276 );
277 };
278
280 trigonometric_f = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
281 return 6. * std::pow(PI, 2) * Eigen::Vector3d(
282 sin(2. * PI * x(0)) * cos(2. * PI * x(1)) * cos(2. * PI * x(2)),
283 cos(2. * PI * x(0)) * sin(2. * PI * x(1)) * cos(2. * PI * x(2)),
284 -2. * cos(2. * PI * x(0)) * cos(2. * PI * x(1)) * sin(2. * PI * x(2))
285 )
287 };
288
291
292 //------------------------------------------------------------------------------
293 // Linear solution
294 //------------------------------------------------------------------------------
295
297 linear_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
298 return Eigen::Vector3d(x(0), -x(1), 0.);
299 };
300
302 linear_curl_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
303 return Eigen::Vector3d::Zero();
304 };
305
307 linear_p = [](const Eigen::Vector3d & x) -> double {
308 return pressure_scaling * (x(0) - x(1));
309 };
310
312 linear_grad_p = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
313 return pressure_scaling * Eigen::Vector3d(1., -1., 0.);
314 };
315
317 linear_f = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
318 return linear_grad_p(x);
319 };
320
323
324
325 //------------------------------------------------------------------------------
326 // Solution derived from a field
327 //------------------------------------------------------------------------------
328 // Setting f(x,y,z)= (sin(pi x) sin(pi y) sin(pi z))^3, we take
329 // U=(-d_y f, d_x f, 0), p=0
330 // Calculations are made symbolically in matlab
331
333 field_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
334 double ux = PI*cos(PI*x(1))*pow(sin(PI*x(0)),3.0)*pow(sin(PI*x(1)),2.0)*pow(sin(PI*x(2)),3.0)*3.0;
335 double uy = PI*cos(PI*x(0))*pow(sin(PI*x(0)),2.0)*pow(sin(PI*x(1)),3.0)*pow(sin(PI*x(2)),3.0)*(-3.0);
336 return Eigen::Vector3d(ux, uy, 0.);
337 };
338
340 field_curl_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
341 double cux = (PI*PI)*cos(PI*x(0))*cos(PI*x(2))*pow(sin(PI*x(0)),2.0)*pow(sin(PI*x(1)),3.0)*pow(sin(PI*x(2)),2.0)*9.0;
342 double cuy = (PI*PI)*cos(PI*x(1))*cos(PI*x(2))*pow(sin(PI*x(0)),3.0)*pow(sin(PI*x(1)),2.0)*pow(sin(PI*x(2)),2.0)*9.0;
343 double cuz = (PI*PI)*pow(sin(PI*x(0)),3.0)*pow(sin(PI*x(1)),3.0)*pow(sin(PI*x(2)),3.0)*6.0-(PI*PI)*pow(cos(PI*x(0)),2.0)*sin(PI*x(0))*pow(sin(PI*x(1)),3.0)*pow(sin(PI*x(2)),3.0)*6.0-(PI*PI)*pow(cos(PI*x(1)),2.0)*pow(sin(PI*x(0)),3.0)*sin(PI*x(1))*pow(sin(PI*x(2)),3.0)*6.0;
344
345 return Eigen::Vector3d(cux, cuy, cuz);
346 };
347
349 field_p = [](const Eigen::Vector3d & x) -> double {
350 return 0.;
351 };
352
354 field_grad_p = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
355 return Eigen::Vector3d(0., 0., 0.);
356 };
357
359 field_f = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
360 double fx = (PI*PI*PI)*pow(cos(PI*x(1)),3.0)*pow(sin(PI*x(0)),3.0)*pow(sin(PI*x(2)),3.0)*-6.0+(PI*PI*PI)*cos(PI*x(1))*pow(sin(PI*x(0)),3.0)*pow(sin(PI*x(1)),2.0)*pow(sin(PI*x(2)),3.0)*3.9E+1-(PI*PI*PI)*pow(cos(PI*x(0)),2.0)*cos(PI*x(1))*sin(PI*x(0))*pow(sin(PI*x(1)),2.0)*pow(sin(PI*x(2)),3.0)*1.8E+1-(PI*PI*PI)*cos(PI*x(1))*pow(cos(PI*x(2)),2.0)*pow(sin(PI*x(0)),3.0)*pow(sin(PI*x(1)),2.0)*sin(PI*x(2))*1.8E+1;
361
362 double fy = (PI*PI*PI)*pow(cos(PI*x(0)),3.0)*pow(sin(PI*x(1)),3.0)*pow(sin(PI*x(2)),3.0)*6.0-(PI*PI*PI)*cos(PI*x(0))*pow(sin(PI*x(0)),2.0)*pow(sin(PI*x(1)),3.0)*pow(sin(PI*x(2)),3.0)*3.9E+1+(PI*PI*PI)*cos(PI*x(0))*pow(cos(PI*x(1)),2.0)*pow(sin(PI*x(0)),2.0)*sin(PI*x(1))*pow(sin(PI*x(2)),3.0)*1.8E+1+(PI*PI*PI)*cos(PI*x(0))*pow(cos(PI*x(2)),2.0)*pow(sin(PI*x(0)),2.0)*pow(sin(PI*x(1)),3.0)*sin(PI*x(2))*1.8E+1;
363
364 double fz = 0.;
365 return Eigen::Vector3d(fx, fy, fz);
366 };
367
370
371 //------------------------------------------------------------------------------
372
373 //------------------------------------------------------------------------------
374 // Vertical flow
375 //------------------------------------------------------------------------------
376
378 vertical_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
379 return Eigen::Vector3d( cos(PI*x.y()), cos(PI*x.x()), 1.);
380 };
381
383 vertical_curl_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
384 return Eigen::Vector3d(0, 0, -PI*sin(PI*x.x()) + PI*sin(PI*x.y()) );
385 };
386
389
392
394 vertical_curl_u_cross_u = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
395 return Eigen::Vector3d (
396 -(-PI*sin(PI*x.x()) + PI*sin(PI*x.y()))*cos(PI*x.x()),
397 (-PI*sin(PI*x.x()) + PI*sin(PI*x.y()))*cos(PI*x.y()),
398 0.
399 );
400 };
401
403 vertical_f = [](const Eigen::Vector3d & x) -> Eigen::Vector3d {
404 return Eigen::Vector3d(pow(PI, 2)*cos(PI*x.y()), pow(PI, 2)*cos(PI*x.x()), 0.)
405 + vertical_grad_p(x);
406 };
407
408
409} // end of namespace HArDCore3D
410
411#endif
Construct all polynomial spaces for the DDR sequence.
Definition ddrcore.hpp:62
Discrete Serendipity Hcurl space: local operators, L2 product and global interpolator.
Definition sxcurl.hpp:21
Discrete Serendipity Hdiv space: local operators, L2 product and global interpolator.
Definition sxdiv.hpp:18
Discrete Serendipity Hgrad space: local operators, L2 product and global interpolator.
Definition sxgrad.hpp:20
Construct all polynomial spaces for the DDR sequence.
Definition serendipity_problem.hpp:40
@ Matrix
Definition basis.hpp:67
size_t dimension() const
Returns the dimension of the global space (all DOFs for all geometric entities)
Definition variabledofspace.hpp:158
static const double PI
Definition ddr-magnetostatics.hpp:187
static Magnetostatics::SolutionPotentialType linear_u
Definition ddr-magnetostatics.hpp:214
static Magnetostatics::SolutionPotentialType trigonometric_u
Definition ddr-magnetostatics.hpp:238
static Magnetostatics::ForcingTermType trigonometric_f
Definition ddr-magnetostatics.hpp:256
static Magnetostatics::ForcingTermType linear_f
Definition ddr-magnetostatics.hpp:228
static NavierStokes::PressureType vertical_p
Definition sddr-navier-stokes.hpp:607
static NavierStokes::ForcingTermType vertical_curl_u_cross_u
Definition sddr-navier-stokes.hpp:613
static NavierStokes::PressureType linear_p
Definition sddr-navier-stokes.hpp:577
static NavierStokes::PressureGradientType linear_grad_p
Definition sddr-navier-stokes.hpp:582
static NavierStokes::ForcingTermType vertical_f
Definition sddr-navier-stokes.hpp:623
static NavierStokes::VorticityType trigonometric_curl_u
Definition sddr-navier-stokes.hpp:482
static NavierStokes::PressureGradientType trigonometric_grad_p
Definition sddr-navier-stokes.hpp:496
static NavierStokes::PressureType trigonometric_p
Definition sddr-navier-stokes.hpp:491
static NavierStokes::VorticityType linear_curl_u
Definition sddr-navier-stokes.hpp:567
static NavierStokes::VorticityType vertical_curl_u
Definition sddr-navier-stokes.hpp:602
static NavierStokes::PressureGradientType vertical_grad_p
Definition sddr-navier-stokes.hpp:610
static NavierStokes::VelocityType vertical_u
Definition sddr-navier-stokes.hpp:597
double pressure_scaling
Definition sddr-navier-stokes.hpp:464
double grad_p
Norm of grad of pressure.
Definition sddr-navier-stokes.hpp:81
static Stokes::ForcingTermType field_f
Definition ddr-stokes.hpp:365
static Stokes::ViscosityType field_nu
Definition ddr-stokes.hpp:375
size_t nbSCDOFs_u() const
Returns the number of statically condensed DOFs (velocity)
Definition ddr-stokes.hpp:100
static Stokes::ViscosityType trigonometric_nu
Definition ddr-stokes.hpp:296
Eigen::SparseMatrix< double > SystemMatrixType
Definition ddr-stokes.hpp:69
double hgrad_p
Hgrad norm of p.
Definition sddr-navier-stokes.hpp:83
static Stokes::VelocityType field_u
Definition ddr-stokes.hpp:339
size_t nbSCDOFs_p() const
Returns the number of statically condensed DOFs (pressure)
Definition ddr-stokes.hpp:106
static Stokes::PressureGradientType field_grad_p
Definition ddr-stokes.hpp:360
double hcurl_u
Hcurl norm of u.
Definition sddr-navier-stokes.hpp:82
static Stokes::ViscosityType linear_nu
Definition ddr-stokes.hpp:328
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> VelocityType
Definition ddr-stokes.hpp:72
size_t nbSCDOFs() const
Returns the number of statically condensed DOFs (both velocity and pressure)
Definition ddr-stokes.hpp:112
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> PressureGradientType
Definition ddr-stokes.hpp:75
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> VorticityType
Definition ddr-stokes.hpp:73
double u
Norm of velocity.
Definition sddr-navier-stokes.hpp:78
std::function< double(const Eigen::Vector3d &)> PressureType
Definition ddr-stokes.hpp:74
IntegralWeight ViscosityType
Definition ddr-stokes.hpp:76
double p
Norm of pressure.
Definition sddr-navier-stokes.hpp:80
static Stokes::VorticityType field_curl_u
Definition ddr-stokes.hpp:346
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> ForcingTermType
Definition ddr-stokes.hpp:71
double curl_u
Norm of curl of velocity (vorticity)
Definition sddr-navier-stokes.hpp:79
static Stokes::PressureType field_p
Definition ddr-stokes.hpp:355
bool use_threads
Definition HHO_DiffAdvecReac.hpp:47
size_t dimensionSpace() const
Returns the global problem dimension (without Lagrange multiplier, just velocity & pressure)
Definition sddr-stokes.hpp:93
double & stabilizationParameter()
Returns the stabilization parameter.
Definition sddr-stokes.hpp:176
size_t nbSCDOFs_u() const
Returns the number of statically condensed DOFs (velocity)
Definition sddr-stokes.hpp:99
Eigen::SparseMatrix< double > SystemMatrixType
Definition sddr-stokes.hpp:68
size_t nbSCDOFs_p() const
Returns the number of statically condensed DOFs (pressure)
Definition sddr-stokes.hpp:105
const double & stabilizationParameter() const
Returns the stabilization parameter.
Definition sddr-stokes.hpp:171
const SystemMatrixType & systemMatrix() const
Returns the linear system matrix.
Definition sddr-stokes.hpp:141
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> VelocityType
Definition sddr-stokes.hpp:71
std::vector< StokesNorms > computeStokesNorms(const std::vector< Eigen::VectorXd > &list_dofs) const
Compute the discrete L2 norms, for a family of Eigen::VectorXd representing velocities & pressures,...
size_t nbSCDOFs() const
Returns the number of statically condensed DOFs (both velocity and pressure)
Definition sddr-stokes.hpp:111
size_t sizeSystem() const
Returns the size of the statically condensed system (with Lagrange multiplier)
Definition sddr-stokes.hpp:117
StokesNorms()
Definition sddr-stokes.hpp:54
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> PressureGradientType
Definition sddr-stokes.hpp:74
Eigen::VectorXd & scVector()
Returns the static condensation rhs.
Definition sddr-stokes.hpp:166
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> VorticityType
Definition sddr-stokes.hpp:72
std::function< double(const Eigen::Vector3d &)> PressureType
Definition sddr-stokes.hpp:73
const SXDiv & sxDiv() const
Returns the space XDiv.
Definition sddr-stokes.hpp:135
Eigen::VectorXd & systemVector()
Returns the linear system right-hand side vector.
Definition sddr-stokes.hpp:156
void assembleLinearSystem(const ForcingTermType &f, const VelocityType &u, const VorticityType &omega, const ViscosityType &nu)
Assemble the global system
IntegralWeight ViscosityType
Definition sddr-stokes.hpp:75
const SXGrad & sxGrad() const
Returns the space SXGrad.
Definition sddr-stokes.hpp:123
StokesNorms(double norm_u, double norm_curl_u, double norm_p, double norm_grad_p)
Constructor.
Definition sddr-stokes.hpp:42
const SystemMatrixType & scMatrix() const
Returns the static condensation recovery operator.
Definition sddr-stokes.hpp:161
const SXCurl & sxCurl() const
Returns the space SXCurl.
Definition sddr-stokes.hpp:129
std::pair< StokesNorms, StokesNorms > computeContinuousErrorsNorms(const Eigen::VectorXd &v, const VelocityType &u, const VorticityType &curl_u, const PressureType &p, const PressureGradientType &grad_p) const
Compute the continuous Hcurl errors in u and Hgrad error in p (1st component), and same with continuo...
const Eigen::VectorXd & systemVector() const
Returns the linear system right-hand side vector.
Definition sddr-stokes.hpp:151
std::function< Eigen::Vector3d(const Eigen::Vector3d &)> ForcingTermType
Definition sddr-stokes.hpp:70
Stokes(const DDRCore &ddrcore, bool use_threads, std::ostream &output=std::cout)
Constructor.
SystemMatrixType & systemMatrix()
Returns the linear system matrix.
Definition sddr-stokes.hpp:146
Definition ddr-magnetostatics.hpp:41
Structure for weights (scalar, at the moment) in integral.
Definition integralweight.hpp:36
Structure to store information for, and perform, local static condensation.
Definition local_static_condensation.hpp:25
Structure to store norm components (for velocity, its curl, pressure, and its gradient),...
Definition sddr-navier-stokes.hpp:62