Basilisk CFD
Adaptive Cartesian mesh PDE framework
Loading...
Searching...
No Matches
log-conform.h
Go to the documentation of this file.
1/** @file log-conform.h
2 */
3/**
4# The log-conformation method for some viscoelastic constitutive models
5
6## Introduction
7
8Viscoelastic fluids exhibit both viscous and elastic behaviour when
9subjected to deformation. Therefore these materials are governed by
10the Navier--Stokes equations enriched with an extra *elastic* stress
11\f$\mathbf{\tau}_p\f$
12\f[
13\rho\left[\partial_t\mathbf{u}+\nabla\cdot(\mathbf{u}\otimes\mathbf{u})\right] =
14- \nabla p + \nabla\cdot(2\mu_s\mathbf{D}) + \nabla\cdot\mathbf{\tau}_p
15+ \rho\mathbf{a}
16\f]
17where \f$\mathbf{D}=[\nabla\mathbf{u} + (\nabla\mathbf{u})^T]/2\f$ is the
18deformation tensor and \f$\mu_s\f$ is the solvent viscosity of the
19viscoelastic fluid.
20
21The *polymeric* stress \f$\mathbf{\tau}_p\f$ represents memory effects due to
22the polymers. Several constitutive rheological models are available in
23the literature where the polymeric stress \f$\mathbf{\tau}_p\f$ is typically a
24function \f$\mathbf{f_s}(\cdot)\f$ of the conformation tensor \f$\mathbf{A}\f$ such as
25\f[
26\mathbf{\tau}_p = \frac{\mu_p \mathbf{f_s}(\mathbf{A})}{\lambda}
27\f]
28where \f$\lambda\f$ is the relaxation parameter and \f$\mu_p\f$ is the
29polymeric viscosity.
30
31The conformation tensor \f$\mathbf{A}\f$ is related to the deformation of
32the polymer chains. \f$\mathbf{A}\f$ is governed by the equation
33\f[
34D_t \mathbf{A} - \mathbf{A} \cdot \nabla \mathbf{u} - \nabla
35\mathbf{u}^{T} \cdot \mathbf{A} =
36-\frac{\mathbf{f_r}(\mathbf{A})}{\lambda}
37\f]
38where \f$D_t\f$ denotes the material derivative and
39\f$\mathbf{f_r}(\cdot)\f$ is the relaxation function.
40
41In the case of an Oldroyd-B viscoelastic fluid, \f$\mathbf{f}_s
42(\mathbf{A}) = \mathbf{f}_r (\mathbf{A}) = \mathbf{A} -\mathbf{I}\f$,
43and the above equations can be combined to avoid the use of
44\f$\mathbf{A}\f$
45\f[
46\mathbf{\tau}_p + \lambda (D_t \mathbf{\tau}_p -
47\mathbf{\tau}_p \cdot \nabla \mathbf{u} -
48\nabla \mathbf{u}^{T} \cdot \mathbf{\tau}_p) = 2 \mu_p \mathbf{D}
49\f]
50
51[Comminal et al. (2015)](#comminal2015) gathered the functions
52\f$\mathbf{f}_s (\mathbf{A})\f$ and \f$\mathbf{f}_r (\mathbf{A})\f$ for
53different constitutive models. In the present library we have
54implemented the Oldroyd-B model and the related FENE-P model for which
55\f[
56\mathbf{f}_s (\mathbf{A}) = \mathbf{f}_r (\mathbf{A}) =
57\frac{\mathbf{A}}{1-Tr(\mathbf{A})/L^2} -\mathbf{I}
58\f]
59
60## Parameters
61
62The primary parameters are the retardation or relaxation time
63\f$\lambda\f$ and the polymeric viscosity \f$\mu_p\f$. The solvent viscosity
64\f$\mu_s\f$ is defined in the [Navier-Stokes
65solver](navier-stokes/centered.h). */
66
67const scalar lambda[] = 1.;
68const scalar mup[] = 1.;
69
70/**
71Constitutive models other than Oldroyd-B (the default) are defined
72through the two functions \f$\mathbf{f}_s (\mathbf{A})\f$ and
73\f$\mathbf{f}_r (\mathbf{A})\f$. */
74
75void (* f_s) (double, double *, double *) = NULL;
76void (* f_r) (double, double *, double *) = NULL;
77
78/**
79## The log conformation approach
80
81The numerical resolution of viscoelastic fluid problems often faces the
82[High-Weissenberg Number
83Problem](http://www.ma.huji.ac.il/~razk/iWeb/My_Site/Research_files/Visco1.pdf).
84This is a numerical instability appearing when strongly elastic flows
85create regions of high stress and fine features. This instability
86poses practical limits to the values of the relaxation time of the
87viscoelastic fluid, \f$\lambda\f$. [Fattal \& Kupferman (2004,
882005)](#fattal2004) identified the exponential nature of the solution
89as the origin of the instability. They proposed to use the logarithm
90of the conformation tensor \f$\Psi = \log \, \mathbf{A}\f$ rather than the
91viscoelastic stress tensor to circumvent the instability.
92
93The constitutive equation for the log of the conformation tensor is
94\f[
95D_t \Psi = (\Omega \cdot \Psi -\Psi \cdot \Omega) + 2 \mathbf{B} +
96\frac{e^{-\Psi} \mathbf{f}_r (e^{\Psi})}{\lambda}
97\f]
98where \f$\Omega\f$ and \f$\mathbf{B}\f$ are tensors that result from the
99decomposition of the transpose of the tensor gradient of the
100velocity
101\f[
102(\nabla \mathbf{u})^T = \Omega + \mathbf{B} + N
103\mathbf{A}^{-1}
104\f]
105
106The antisymmetric tensor \f$\Omega\f$ requires only the memory of a scalar
107in 2D since,
108\f[
109\Omega = \left(
110\begin{array}{cc}
1110 & \Omega_{12} \\
112-\Omega_{12} & 0
113\end{array}
114\right)
115\f]
116The log-conformation tensor, \f$\Psi\f$, is related to the
117polymeric stress tensor \f$\mathbf{\tau}_p\f$, by the strain function
118\f$\mathbf{f}_s (\mathbf{A})\f$
119\f[
120\Psi = \log \, \mathbf{A} \quad \mathrm{and} \quad \mathbf{\tau}_p =
121\frac{\mu_p}{\lambda} \mathbf{f}_s (\mathbf{A})
122\f]
123where \f$Tr\f$ denotes the trace of the tensor and \f$L\f$ is an additional
124property of the viscoelastic fluid.
125
126We will use the Bell--Collela--Glaz scheme to advect the log-conformation
127tensor \f$\Psi\f$. */
128
129#include "bcg.h"
130
131/**
132## Variables
133
134The main variable will be the stress tensor \f$\mathbf{\tau}_p\f$. The trace of
135the conformation tensor, \f$\mathbf{A}\f$, is often necessary for
136constitutive viscoelastic models other than Oldroyd-B. */
137
139#if AXI
140scalar tau_qq[];
141#endif
142const scalar trA[] = 0.;
143
144/** @brief Event: defaults (i = 0) */
145void event_defaults (void) {
146 if (is_constant (a.x))
147 a = {0} /* new vector */;
148 if (f_s || f_r)
149 trA = {0} /* new scalar */;
150
151 for (int _i = 0; _i < _N; _i++) /* foreach */ {
152 for (int _d = 0; _d < dimension; _d++)
153 tau_p.x.x[] = 0.;
154 tau_p.x.y[] = 0.;
155#if AXI
156 tau_qq[] = 0;
157#endif
158 }
159
160 /**
161 ## Boundary conditions
162
163 By default we set a zero Neumann boundary condition for all
164 the components except if the bottom is an axis of symmetry. */
165
166 for (int _s = 0; _s < 1; _s++) /* scalar in {tau_p} */ {
167 s.v.x.i = -1; // just a scalar, not the component of a vector
168 for (int _d = 0; _d < dimension; _d++)
169 if (s.boundary[left] != periodic_bc) {
170 /* BC: s[left] = neumann(0) */
171 /* BC: s[right] = neumann(0) */
172 }
173 }
174#if AXI
175 scalar s = tau_p.x.y;
176 /* BC: s[bottom] = dirichlet(0.) */
177#endif
178}
179
180/**
181## Numerical Scheme
182
183The first step is to implement a routine to calculate the eigenvalues
184and eigenvectors of the conformation tensor \f$\mathbf{A}\f$.
185
186These structs ressemble Basilisk vectors and tensors but are just
187arrays not related to the grid. */
188
189typedef struct { double x, y;} pseudo_v;
190typedef struct { pseudo_v x, y;} pseudo_t;
191
193{
194 /**
195 The eigenvalues are saved in vector \f$\Lambda\f$ computed from the
196 trace and the determinant of the symmetric conformation tensor
197 \f$\mathbf{A}\f$. */
198
199 if (sq(A->x.y) < 1e-15) {
200 R->x.x = R->y.y = 1.;
201 R->y.x = R->x.y = 0.;
202 Lambda->x = A->x.x; Lambda->y = A->y.y;
203 return;
204 }
205
206 double T = A->x.x + A->y.y; // Trace of the tensor
207 double D = A->x.x*A->y.y - sq(A->x.y); // Determinant
208
209 /**
210 The eigenvectors, \f$\mathbf{v}_i\f$ are saved by columns in tensor
211 \f$\mathbf{R} = (\mathbf{v}_1|\mathbf{v}_2)\f$. */
212
213 R->x.x = R->x.y = A->x.y;
214 R->y.x = R->y.y = -A->x.x;
215 double s = 1.;
216 for (int i = 0; i < dimension; i++) {
217 double * ev = (double *) Lambda;
218 ev[i] = T/2 + s*sqrt(sq(T)/4. - D);
219 s *= -1;
220 double * Rx = (double *) &R->x;
221 double * Ry = (double *) &R->y;
222 Ry[i] += ev[i];
223 double mod = sqrt(sq(Rx[i]) + sq(Ry[i]));
224 Rx[i] /= mod;
225 Ry[i] /= mod;
226 }
227}
228
229/**
230The stress tensor depends on previous instants and has to be
231integrated in time. In the log-conformation scheme the advection of
232the stress tensor is circumvented, instead the conformation tensor,
233\f$\mathbf{A}\f$ (or more precisely the related variable \f$\Psi\f$) is
234advanced in time.
235
236In what follows we will adopt a scheme similar to that of [Hao \& Pan
237(2007)](#hao2007). We use a split scheme, solving successively
238
239a) the upper convective term:
240\f[
241\partial_t \Psi = 2 \mathbf{B} + (\Omega \cdot \Psi -\Psi \cdot \Omega)
242\f]
243b) the advection term:
244\f[
245\partial_t \Psi + \nabla \cdot (\Psi \mathbf{u}) = 0
246\f]
247c) the model term (but set in terms of the conformation
248tensor \f$\mathbf{A}\f$). In an Oldroyd-B viscoelastic fluid, the model is
249\f[
250\partial_t \mathbf{A} = -\frac{\mathbf{f}_r (\mathbf{A})}{\lambda}
251\f]
252
253The implementation below assumes that the values of \f$\Psi\f$ and
254\f$\tau_p\f$ are never needed simultaneously. This means that \f$\tau_p\f$ can
255be used to store (temporarily) the values of \f$\Psi\f$ (i.e. \f$\Psi\f$ is
256just an alias for \f$\tau_p\f$). */
257
258/** @brief Event: tracer_advection (i++) */
260{
261 tensor Psi = tau_p;
262#if AXI
264#endif
265
266 /**
267 ### Computation of \f$\Psi = \log \mathbf{A}\f$ and upper convective term */
268
269 for (int _i = 0; _i < _N; _i++) /* foreach */ {
270 if (lambda[] == 0.) {
271 for (int _d = 0; _d < dimension; _d++)
272 Psi.x.x[] = 0.;
273 Psi.x.y[] = 0.;
274#if AXI
275 Psiqq[] = 0.;
276#endif
277 }
278 else { // lambda[] != 0.
279
280 /**
281 We assume that the stress tensor \f$\mathbf{\tau}_p\f$ depends on the
282 conformation tensor \f$\mathbf{A}\f$ as follows
283 \f[
284 \mathbf{\tau}_p = \frac{\mu_p}{\lambda} f_s (\mathbf{A}) =
285 \frac{\mu_p}{\lambda} \eta (\nu \mathbf{A} - I)
286 \f]
287 In most of the viscoelastic models, \f$\nu\f$ and \f$\eta\f$ are
288 nonlinear parameters that depend on the trace of the conformation tensor,
289 \f$\mathbf{A}\f$.*/
290
291 double eta = 1., nu = 1.;
292 if (f_s)
293 f_s (trA[], &nu, &eta);
294
295 double fa = (mup[] != 0 ? lambda[]/(mup[]*eta) : 0.);
296
297 pseudo_t A;
298 A.x.y = fa*tau_p.x.y[]/nu;
299 for (int _d = 0; _d < dimension; _d++)
300 A.x.x = (fa*tau_p.x.x[] + 1.)/nu;
301
302 /**
303 In the axisymmetric case, \f$\Psi_{\theta \theta} = \log A_{\theta
304 \theta}\f$. Therefore \f$\Psi_{\theta \theta} = \log [ ( 1 + fa
305 \tau_{p_{\theta \theta}})/\nu]\f$. */
306
307#if AXI
308 double Aqq = (1. + fa*tau_qq[])/nu;
309 Psiqq[] = log (Aqq);
310#endif
311
312 /**
313 The conformation tensor is diagonalized through the
314 eigenvector tensor \f$\mathbf{R}\f$ and the eigenvalues diagonal
315 tensor, \f$\Lambda\f$. */
316
318 pseudo_t R;
320
321 /**
322 \f$\Psi = \log \mathbf{A}\f$ is easily obtained after diagonalization,
323 \f$\Psi = R \cdot \log(\Lambda) \cdot R^T\f$. */
324
325 Psi.x.y[] = R.x.x*R.y.x*log(Lambda.x) + R.y.y*R.x.y*log(Lambda.y);
326 for (int _d = 0; _d < dimension; _d++)
327 Psi.x.x[] = sq(R.x.x)*log(Lambda.x) + sq(R.x.y)*log(Lambda.y);
328
329 /**
330 We now compute the upper convective term \f$2 \mathbf{B} +
331 (\Omega \cdot \Psi -\Psi \cdot \Omega)\f$.
332
333 The diagonalization will be applied to the velocity gradient
334 $(\nabla u)^T$ to obtain the antisymmetric tensor \f$\Omega\f$ and
335 the traceless, symmetric tensor, \f$\mathbf{B}\f$. If the conformation
336 tensor is \f$\mathbf{I}\f$, \f$\Omega = 0\f$ and \f$\mathbf{B}= \mathbf{D}\f$. */
337
338 pseudo_t B;
339 double OM = 0.;
340 if (fabs(Lambda.x - Lambda.y) <= 1e-20) {
341 B.x.y = (u.y[1,0] - u.y[-1,0] +
342 u.x[0,1] - u.x[0,-1])/(4.*Delta);
343 for (int _d = 0; _d < dimension; _d++)
344 B.x.x = (u.x[1,0] - u.x[-1,0])/(2.*Delta);
345 }
346 else {
347 pseudo_t M;
348 for (int _d = 0; _d < dimension; _d++) {
349 M.x.x = (sq(R.x.x)*(u.x[1] - u.x[-1]) +
350 sq(R.y.x)*(u.y[0,1] - u.y[0,-1]) +
351 R.x.x*R.y.x*(u.x[0,1] - u.x[0,-1] +
352 u.y[1] - u.y[-1]))/(2.*Delta);
353 M.x.y = (R.x.x*R.x.y*(u.x[1] - u.x[-1]) +
354 R.x.y*R.y.x*(u.y[1] - u.y[-1]) +
355 R.x.x*R.y.y*(u.x[0,1] - u.x[0,-1]) +
356 R.y.x*R.y.y*(u.y[0,1] - u.y[0,-1]))/(2.*Delta);
357 }
358 double omega = (Lambda.y*M.x.y + Lambda.x*M.y.x)/(Lambda.y - Lambda.x);
359 OM = (R.x.x*R.y.y - R.x.y*R.y.x)*omega;
360
361 B.x.y = M.x.x*R.x.x*R.y.x + M.y.y*R.y.y*R.x.y;
362 for (int _d = 0; _d < dimension; _d++)
363 B.x.x = M.x.x*sq(R.x.x)+M.y.y*sq(R.x.y);
364 }
365
366 /**
367 We now advance \f$\Psi\f$ in time, adding the upper convective
368 contribution. */
369
370 double s = - Psi.x.y[];
371 Psi.x.y[] += dt*(2.*B.x.y + OM*(Psi.y.y[] - Psi.x.x[]));
372 for (int _d = 0; _d < dimension; _d++) {
373 s *= -1;
374 Psi.x.x[] += dt*2.*(B.x.x + s*OM);
375 }
376
377 /**
378 In the axisymmetric case, the governing equation for \f$\Psi_{\theta
379 \theta}\f$ only involves that component,
380 \f[
381 \Psi_{\theta \theta}|_t - 2 L_{\theta \theta} =
382 \frac{\mathbf{f}_r(e^{-\Psi_{\theta \theta}})}{\lambda}
383 \f]
384 with \f$L_{\theta \theta} = u_y/y\f$. Therefore step (a) for
385 \f$\Psi_{\theta \theta}\f$ is */
386
387#if AXI
388 Psiqq[] += dt*2.*u.y[]/y;
389#endif
390 }
391 }
392
393 /**
394 ### Advection of \f$\Psi\f$
395
396 We proceed with step (b), the advection of the log of the
397 conformation tensor \f$\Psi\f$. */
398
399#if AXI
400 advection ({Psi.x.x, Psi.x.y, Psi.y.y, Psiqq}, uf, dt);
401#else
402 advection ({Psi.x.x, Psi.x.y, Psi.y.y}, uf, dt);
403#endif
404
405 /**
406 ### Model term */
407
408 for (int _i = 0; _i < _N; _i++) /* foreach */ {
409 if (lambda[] == 0.) {
410
411 /**
412 If \f$\lambda = 0\f$ the stress tensor for the polymeric part
413 reduces to that of a Newtonian fluid \f$\mathbf{\tau}_p = 2 \mu_p
414 \mathbf{D}\f$ with \f$\mathbf{D}\f$ the rate-of-strain
415 tensor. Note that \f$\mathbf{\tau}_p\f$ is in this case independent of
416 time. */
417
418 for (int _d = 0; _d < dimension; _d++)
419 tau_p.x.x[] = mup[]*(u.x[1,0] - u.x[-1,0])/Delta; // 2*mu*dxu;
420 tau_p.x.y[] = mup[]*(u.y[1,0] - u.y[-1,0] +
421 u.x[0,1] - u.x[0,-1])/(2.*Delta); // mu*(dxv+dyu)
422#if AXI
423 tau_qq[] = 2.*mup[]*u.y[]/y;
424#endif
425 }
426 else { // lambda != 0.
427
428 /**
429 It is time to undo the log-conformation, again by
430 diagonalization, to recover the conformation tensor \f$\mathbf{A}\f$
431 and to perform step (c).*/
432
433 pseudo_t A = {{Psi.x.x[], Psi.x.y[]}, {Psi.y.x[], Psi.y.y[]}}, R;
436 Lambda.x = exp(Lambda.x), Lambda.y = exp(Lambda.y);
437
438 A.x.y = R.x.x*R.y.x*Lambda.x + R.y.y*R.x.y*Lambda.y;
439 for (int _d = 0; _d < dimension; _d++)
440 A.x.x = sq(R.x.x)*Lambda.x + sq(R.x.y)*Lambda.y;
441#if AXI
442 double Aqq = exp(Psiqq[]);
443#endif
444
445 /**
446 We perform now step (c) by integrating
447 \f$\mathbf{A}_t = -\mathbf{f}_r (\mathbf{A})/\lambda\f$ to obtain
448 \f$\mathbf{A}^{n+1}\f$. This step is analytic,
449 \f[
450 \int_{t^n}^{t^{n+1}}\frac{d \mathbf{A}}{\mathbf{I}- \nu \mathbf{A}} =
451 \frac{\eta \, \Delta t}{\lambda}
452 \f]
453 */
454
455 double eta = 1., nu = 1.;
456 if (f_r) {
457#if 0 // Set to one if the midstep trace is to be used.
458 scalar t = trA;
459 t[] = A.x.x + A.y.y;
460#if AXI
461 t[] += Aqq;
462#endif
463#endif
464 f_r (trA[], &nu, &eta);
465 }
466
467 double fa = exp(-nu*eta*dt/lambda[]);
468
469#if AXI
470 Aqq = (1. - fa)/nu + fa*exp(Psiqq[]);
471 Psiqq[] = log (Aqq);
472#endif
473
474 A.x.y *= fa;
475 for (int _d = 0; _d < dimension; _d++)
476 A.x.x = (1. - fa)/nu + A.x.x*fa;
477
478 /**
479 The trace at time \f$n+1\f$ is also needed for some models. */
480
481 if (f_s || f_r) {
482 scalar t = trA;
483 t[] = A.x.x + A.y.y;
484#if AXI
485 t[] += Aqq;
486#endif
487 }
488
489 /**
490 Then the stress tensor \f$\mathbf{\tau}_p^{n+1}\f$ is computed from
491 \f$\mathbf{A}^{n+1}\f$ according to the constitutive model,
492 \f$\mathbf{f}_s(\mathbf{A})\f$. */
493
494 nu = 1; eta = 1.;
495 if (f_s)
496 f_s (trA[], &nu, &eta);
497
498 fa = mup[]/lambda[]*eta;
499
500 tau_p.x.y[] = fa*nu*A.x.y;
501#if AXI
502 tau_qq[] = fa*(nu*Aqq - 1.);
503#endif
504 for (int _d = 0; _d < dimension; _d++)
505 tau_p.x.x[] = fa*(nu*A.x.x - 1.);
506 }
507 }
508}
509
510/**
511### Divergence of the viscoelastic stress tensor
512
513The viscoelastic stress tensor \f$\mathbf{\tau}_p\f$ is defined at cell centers
514while the corresponding force (acceleration) will be defined at cell
515faces. Two terms contribute to each component of the momentum
516equation. For example the \f$x\f$-component in Cartesian coordinates has
517the following terms: \f$\partial_x \mathbf{\tau}_{p_{xx}} + \partial_y
518\mathbf{\tau}_{p_{xy}}\f$. The first term is easy to compute since it can be
519calculated directly from center values of cells sharing the face. The
520other one is harder. It will be computed from vertex values. The
521vertex values are obtained by averaging centered values. Note that as
522a result of the vertex averaging cells `[]` and `[-1,0]` are not
523involved in the computation of shear. */
524
525/** @brief Event: acceleration (i++) */
527{
528 vector av = a;
529 for (int _i = 0; _i < _N; _i++) /* foreach_face */
530 if (fm.x[] > 1e-20) {
531 double shear = (tau_p.x.y[0,1]*cm[0,1] + tau_p.x.y[-1,1]*cm[-1,1] -
532 tau_p.x.y[0,-1]*cm[0,-1] - tau_p.x.y[-1,-1]*cm[-1,-1])/4.;
533 av.x[] += (shear + cm[]*tau_p.x.x[] - cm[-1]*tau_p.x.x[-1])*
534 alpha.x[]/(sq(fm.x[])*Delta);
535 }
536#if AXI
537 for (int _i = 0; _i < _N; _i++) /* foreach_face */
538 if (y > 0.)
539 av.y[] -= (tau_qq[] + tau_qq[0,-1])*alpha.y[]/sq(y)/2.;
540#endif
541}
542
543/**
544## References
545
546~~~bib
547@article{fattal2004,
548 title={Constitutive laws for the matrix-logarithm of the conformation tensor},
549 author={Fattal, Raanan and Kupferman, Raz},
550 journal={Journal of Non-Newtonian Fluid Mechanics},
551 volume={123},
552 number={2-3},
553 pages={281--285},
554 year={2004},
555 publisher={Elsevier}
556}
557
558@article{fattal2005,
559 title={Time-dependent simulation of viscoelastic flows at
560 high {W}eissenberg number using the log-conformation representation},
561 author={Fattal, Raanan and Kupferman, Raz},
562 journal={Journal of Non-Newtonian Fluid Mechanics},
563 volume={126},
564 number={1},
565 pages={23--37},
566 year={2005},
567 publisher={Elsevier}
568}
569
570@article{hao2007,
571 title={Simulation for high {W}eissenberg number: viscoelastic
572 flow by a finite element method},
573 author={Hao, Jian and Pan, Tsorng-Whay},
574 journal={Applied mathematics letters},
575 volume={20},
576 number={9},
577 pages={988--993},
578 year={2007},
579 publisher={Elsevier}
580}
581
582@article{comminal2015,
583 title={Robust simulations of viscoelastic flows at high {W}eissenberg
584 numbers with the streamfunction/log-conformation formulation},
585 author={Comminal, Rapha{\"e}l and Spangenberg, Jon and Hattel, Jesper Henri},
586 journal={Journal of Non-Newtonian Fluid Mechanics},
587 volume={223},
588 pages={37--61},
589 year={2015},
590 publisher={Elsevier}
591}
592~~~
593
594## See also
595
596* [Functions \f$f_s\f$ and \f$f_r\f$ for the FENE-P model](fene-p.h)
597*/
#define u
Definition advection.h:30
vector uf[]
We allocate the (face) velocity field.
Definition advection.h:29
const vector alpha
Definition all-mach.h:47
const vector a
Definition all-mach.h:59
trace void advection(scalar *tracers, vector u, double dt, scalar *src=NULL)
The function below uses the tracer_fluxes function to integrate the advection equation,...
Definition bcg.h:71
#define dimension
Definition bitree.h:3
static double periodic_bc(Point point, Point neighbor, scalar s, bool *data)
int y
Definition common.h:76
int x
Definition common.h:76
const scalar cm[]
Definition common.h:397
static number sq(number x)
Definition common.h:11
@ left
Definition common.h:123
const vector fm[]
Definition common.h:396
double dt
scalar s
Definition embed-tree.h:56
scalar int i
Definition embed.h:74
double t
Definition events.h:24
vector D[]
The linear system can be inverted with the multigrid Poisson solver.
scalar eta
Definition hydro.h:50
double nu
Definition diffusion.h:135
void event_acceleration(void)
Event: acceleration (i++)
static void diagonalization_2D(pseudo_v *Lambda, pseudo_t *R, pseudo_t *A)
const scalar trA[]
void(* f_r)(double, double *, double *)
Definition log-conform.h:76
const scalar lambda[]
Definition log-conform.h:67
const scalar mup[]
Definition log-conform.h:68
symmetric tensor tau_p[]
void event_defaults(void)
Event: defaults (i = 0)
void event_tracer_advection(void)
The stress tensor depends on previous instants and has to be integrated in time.
void(* f_s)(double, double *, double *)
Constitutive models other than Oldroyd-B (the default) are defined through the two functions and .
Definition log-conform.h:75
#define A(i)
Definition rpe.h:57
vector av[]
def _i
Definition stencils.h:405
scalar omega[]
We allocate the vorticity field , the streamfunction field and a structure to store the statistics o...
Definition stream.h:39
pseudo_v x
pseudo_v y
double x
double y
int i
Definition common.h:44
vector x
Definition common.h:67
scalar x
Definition common.h:47
scalar y
Definition common.h:49
scalar T[]
Definition thermal.h:60