In this section, we review the basic equations describing the problem to be solved, and we present the necessary steps to derive the model equations.
Governing Equations
Our main goal is to describe subsonic air flow in the presence of porous media by means of coarse grid CFD. A typical example is the air flow through a vehicle’s underhood compartment, where the different heat exchangers are modeled as porous media. Such a flow is governed by the Navier–Stokes equations
$$\begin{aligned} \nabla \cdot \rho \mathbf {u}= & {} 0 \end{aligned}$$
(1)
$$\begin{aligned} \frac{\partial \rho \mathbf {u}}{\partial t} + (\mathbf {u} \cdot \nabla )\rho \mathbf {u}= & {} -\nabla p + \mu \nabla ^2 \mathbf {u} + {\varvec{{\mathcal {S}}}}, \end{aligned}$$
(2)
where \(\mathbf {u}\) and p, respectively, denote the independent flow-field variable velocity and pressure. The air density is given by \(\rho \) and the viscosity by \(\mu \). Additional body forces like the resistance of the porous media are given by the source term \({\varvec{{\mathcal {S}}}}\). It should be noted that this source terms account for geometric details which are not resolved by the numerical grid. In this approach, the flow within the porous medium is split into a free-stream part (with fully open geometry) and additional resistance forces (which account for flow area reduction and friction). Therefore, the source must be considered additionally to the convection and diffusion operators in this approach.
In vehicle aerodynamics, the heat exchanger resistance is commonly modeled by a suitable Darcy–Forchheimer law (Whitaker 1996; Rohsenow et al. 1998; Dukhan et al. 2014; Janssen et al. 2015). In our case, we follow the formulation as it is used, e.g., in OpenFOAM (Hafsteinsson 2009), which is given by
$$\begin{aligned} {\mathcal {S}}_i(u_i) = {-}\left( \mu D + {\displaystyle \frac{1}{2}}\rho |u_i| F \right) u_i. \end{aligned}$$
(3)
Here, the Darcy constant D accounts for viscous losses (and corresponds to the inverse permeability) and the Forchheimer constant F for losses due to turbulent effects in the porous medium.
Generally for porous media, the sign of the source term is always opposite to the sign of the local velocity, and the derivative w.r.t. velocity is always negative, which is a crucial condition for a robust solution (Patankar 1981). Thus, an implicit treatment of the porous medium is always preferable (Merci et al. 2000).
Discretized Equations
When developing our discretized model equations from the Navier–Stokes equations, our main goal is to obtain a steady-state solution for the momentum equation Eq. (2). In our approach, the system relaxes from some initial state toward equilibrium by applying simple forward Euler time stepping
$$\begin{aligned} \frac{{u_i}^{(n+1)} - {u_i}^{(n)}}{\varDelta t} = {\mathcal {C}}_i + {\mathcal {D}}_i + {\mathcal {P}}_i + {\mathcal {S}}_i, \end{aligned}$$
(4)
where n denotes the iteration step for a relaxation parameter \(\varDelta t\) (fictitious time step). Furthermore, \({\mathcal {C}}_i\), \({\mathcal {D}}_i\) and \({\mathcal {P}}_i\) denote the discretized forms of convection, diffusion, and the pressure gradient, respectively.
To account for mass conservation, Eq. (1), we apply the SIMPLE algorithm (Patankar 1980) to establish the velocity–pressure coupling. Basically, the update procedure for velocity is then given by
$$\begin{aligned} {u_i}^{(n+1)} = {u_i}^{(n)} + \varDelta t \left[ {{\mathcal {C}}_i}^{(n)} + {{\mathcal {D}}_i}^{(n)} + {{\mathcal {P}}_i}^{(n+1)} + (1-\varPsi ) {{\mathcal {S}}_i}^{(n)} + \varPsi {{\mathcal {S}}_i}^{(n+1)} \right] , \end{aligned}$$
(5)
where the superscripts (n) and \((n+1)\) denote, for which iteration step the discretization operators should be evaluated. Please note that the implicit treatment of the pressure via \({{\mathcal {P}}_i}^{(n+1)}\) is part of the SIMPLE strategy to ensure mass conservation, while the blending factor \(\varPsi \) makes the source term implicit.
For the further treatment of the model equations, we make the following assumptions, which are well fulfilled by the Darcy–Forchheimer law Eq. (3):
-
The source term depends explicitly on the velocity, i.e., an analytical dependence of the source term on velocity is provided: \({\mathcal {S}}_i = {\mathcal {S}}_i(u_i)\).
-
The source term is sufficiently smooth to be linearized.
By virtue of these assumptions, the implicit contribution of the source term can be written in linearized form as
$$\begin{aligned} {{\mathcal {S}}_i}^{(n+1)}\approx & {} {{\mathcal {S}}_i}^{(n)} + {\left( \frac{\text {d}{\mathcal {S}}_i}{\text {d}u_i}\right) }^{(n)} \left( {u_i}^{(n+1)} - {u_i}^{(n)} \right) \nonumber \\:= & {} {{\mathcal {S}}_i}^{(n)} + {{\mathcal {S}}_i^\prime }^{(n)} \left( {u_i}^{(n+1)} - {u_i}^{(n)} \right) . \end{aligned}$$
(6)
Furthermore, we consider only linear discretizations of the pressure gradient. This allows to split the implicit pressure contribution into a contribution from the previous iteration and a corrective contribution, such that
$$\begin{aligned} {p}^{(n+1)}:= & {} {p}^{(n)} + {\varDelta p}^{(n)} \Longrightarrow {\mathcal {P}}\left( {p}^{(n+1)}\right) = {\mathcal {P}}\left( {p}^{(n)}\right) + {\mathcal {P}}\left( {\varDelta p}^{(n)}\right) \nonumber \\:= & {} {{\mathcal {P}}}^{(n)} + {\varDelta {\mathcal {P}}}^{(n)}. \end{aligned}$$
(7)
By inserting the simplifications Eqs. (6) and (7) into the update rule Eq. (5) and introducing an intermediate velocity \(u_i^*\), we obtain
$$\begin{aligned} \nonumber {u_i}^{(n+1)}= & {} \left\{ {u_i}^{(n)} + \varDelta t \left[ {{\mathcal {C}}_i}^{(n)} + {{\mathcal {D}}_i}^{(n)} + {{\mathcal {P}}_i}^{(n)} + {{\mathcal {S}}_i}^{(n)} + \varPsi {{\mathcal {S}}_i^\prime }^{(n)} \left( u_i^* - {u_i}^{(n)}\right) \right] \right\} \\&+\,\varDelta t \left[ {\varDelta {\mathcal {P}}_i}^{(n)} + \varPsi {{\mathcal {S}}_i^\prime }^{(n)}\left( {u_i}^{(n+1)}-u_i^* \right) \right] . \end{aligned}$$
(8)
To fix the value of the yet unknown intermediate velocity, we demand that it is equal to the term within curly braces in the above equation, yielding the final update rule
$$\begin{aligned}&\displaystyle \varDelta t^* := \frac{\varDelta t}{1 - \varDelta t \varPsi {{\mathcal {S}}_i^\prime }^{(n)}} \end{aligned}$$
(9)
$$\begin{aligned}&\displaystyle u_i^* = {u_i}^{(n)} + \varDelta t^* \left[ {{\mathcal {C}}_i}^{(n)} + {{\mathcal {D}}_i}^{(n)} + {{\mathcal {P}}_i}^{(n)} + {{\mathcal {S}}_i}^{(n)} \right] \end{aligned}$$
(10)
$$\begin{aligned}&\displaystyle {u_i}^{(n+1)} = u_i^* + \varDelta t^* {\varDelta {\mathcal {P}}_i}^{(n)}. \end{aligned}$$
(11)
This update procedure corresponds to that of the SIMPLE algorithm with explicit source terms, except for the position-dependent time step \(\varDelta t^*\).
The obvious advantage of this approach is that the implicit treatment of the source terms neither increases the complexity nor decreases the speed of the SIMPLE algorithm, as no additional equation solving is required.
Pressure–Velocity Coupling
To complete the procedure presented in the previous section, a suitable pressure–velocity coupling must be implemented to ensure mass conservation according to the continuity equation Eq. (1). In the discretized form, continuity is given by
$$\begin{aligned} {\mathcal {L}}\left( {\mathbf {u}}^{(n+1)} \right) = {\mathcal {L}}\left( \mathbf {u}^* + \varDelta t^* {\varDelta {\mathcal {P}}}^{(n)} \right) = 0, \end{aligned}$$
(12)
where the operator \({\mathcal {L}}\) denotes the discretized divergence operator. By assuming that the divergence operator \({\mathcal {L}}\) is linear, mass conservation can be written as
$$\begin{aligned} {\mathcal {L}}\left( \varDelta t^* {\varDelta {\mathcal {P}}}^{(n)} \right) = - {\mathcal {L}}\left( \mathbf {u}^* \right) , \end{aligned}$$
(13)
where the r.h.s. can be calculated after the predictor step from the intermediate \(u^*\). By introduction of the influence function \({\mathcal {F}}\) with
$$\begin{aligned} {\mathcal {F}}\left( {\varDelta p}^{(n)} \right) := {\mathcal {L}}\left( \varDelta t^* {\varDelta {\mathcal {P}}}^{(n)} \right) = {\mathcal {L}}\left[ \varDelta t^* {\mathcal {P}}\left( {\varDelta p}^{(n)}\right) \right] \end{aligned}$$
(14)
and the fact that the combined application of divergence and gradient operator can also be written as a matrix operation, the mass conservation takes the final form
$$\begin{aligned} {\mathcal {F}}\left( {\varDelta p}^{(n)} \right) = A {\varDelta p}^{(n)} = - {\mathcal {L}}\left( \mathbf {u}^* \right) , \end{aligned}$$
(15)
where A is the pressure influence matrix. Contrary to the explicit case, this matrix is not constant for all iterations steps, but has to be updated in each step because of the derivative \({{\mathcal {S}}_i^\prime }^{(n)}\) which is part of the time step \(\varDelta t^*\) in Eq. (12).
For a Cartesian grid with a first-order pressure gradient, the pressure influence matrix has a predominantly diagonal structure with six (3D) and four (2D), respectively, occupied side diagonals (c.f. Fig. 1). Additional matrix elements occur locally next to these “geometry” elements due to the implicit treatment of the porous media. Our target is to place an arbitrary number of porous regions within the computational domain. Moreover, we want to keep the approach general, i.e., not only for Darcy–Forchheimer porosities Eq. (3), but for any law which describes the pressure drop in dependence of velocity sufficiently smooth and monotonic. To this end, we describe the system not directly by the influence matrix A, but we claim to know the different influence functions to describe geometry \(({\mathcal {F}}_G)\) and porous media \(({\mathcal {F}}_{P,i})\), where the latter can be derived from the pressure loss law. Due to this splitting, the total influence function reads
$$\begin{aligned} {\mathcal {F}}\left( {\varDelta p}^{(n)} \right) = {\mathcal {F}}_G\left( {\varDelta p}^{(n)} \right) + \sum _i {\mathcal {F}}_{P,i}\left( {\varDelta p}^{(n)} \right) . \end{aligned}$$
(16)
To determine the influence matrix automatically for an arbitrary number of influence functions, the following testing technique is applied: First, a series of pressure test vectors is defined by
$$\begin{aligned} \varDelta \hat{p}_\ell := \delta _{\ell m},\quad \ell ,m = 1,\dots ,M, \end{aligned}$$
(17)
where M is the number of unknown pressure values in general the number of cells in the numerical grid and the Kronecker delta \(\delta _{\ell m}\) is defined by
$$\begin{aligned} \delta _{\ell m} = \left\{ \begin{array}{ll} 1 &{}\quad \text {if}\; \ell = m \\ 0 &{}\quad \text {else}. \end{array} \right. \end{aligned}$$
(18)
Then, these test vectors are subsequently applied to the operator \({\mathcal {F}}\) to give the columns of the influence matrix by virtue of Eq. (13), c.f. Fig. 1, as
$$\begin{aligned} {\mathcal {F}}\left( \varDelta \hat{p}_\ell \right) = A_{im} \delta _{\ell m} = A_{i \ell }. \end{aligned}$$
(19)
This method does not represent a new way of how velocity and pressure are coupled (this is still according to the SIMPLE algorithm). Many methods for this purpose have been proposed and intensively studied in the literature (Patankar 1980; Ferziger and Perić 2002; Raithby and Schneider 1979; Doormaal and Raithby 1984). The approach considered here is a formal framework, which can be applied to velocity–pressure coupling algorithms which perform a predictor step for the velocity equation and a corrector step for pressure equation to fulfill mass conservation:
-
1.
Predictor step: \(u^{(n)} \rightarrow u^*\) with mass imbalance \(\varDelta m\).
-
2.
Corrector step: \(A \varDelta p = \varDelta m\).
The necessary influence matrix A is not assembled directly, but all the details about the used discretization scheme are contained in the influence operator \({\mathcal {F}}\).
In this way, an easy and straight forward determination of the influence matrix is possible for any combination of applied source terms. The price to pay is that the operator \({\mathcal {F}}\) has to be evaluated M times per iteration step.
Accelerated Pressure–Velocity Coupling
To overcome the drawback mentioned in the last section, the fact that usually finite stencils are applied for the discretized evaluation of divergence \({\mathcal {L}}\) and gradient \({\mathcal {P}}\) can be exploited to reduce the number of required test vectors.
To this end, the single columns of the pressure influence matrix will be denoted by \(\mathbf {a}_j\). The “structure” of the influence matrix can be described by the vectors \(\mathbf {a}_j^0\) with
$$\begin{aligned} A^0 = \left\{ \mathbf {a}_j^0\right\} _m = a_{j,m}^0 := 1-\left| \text {sgn}\left( a_{j,m}\right) \right| , \end{aligned}$$
(20)
where the sign function sgn is defined by
$$\begin{aligned} \text {sgn}\left( x\right) := \left\{ \begin{array}{lll} -1 &{}\quad \text {if} &{} x < 0 \\ 0 &{}\quad \text {if} &{} x = 0 \\ 1 &{}\quad \text {if} &{} x > 0, \end{array} \right. \end{aligned}$$
(21)
so that all non-empty matrix elements are marked by a 1, as shown in Fig. 2. As the structure of the matrix is constant during calculation, and only the values change, these vectors can be determined in a preliminary step. Then, it is possible to find sets of columns denoted by \({\mathcal {K}}_i = \kappa _{i,l}\), such that the corresponding stencils of each set are completely independent, which can be expressed by
$$\begin{aligned} \mathbf {a}_{l_1}^0 \cdot \mathbf {a}_{l_2}^0 = \delta _{l_1,l_2} \quad \forall (l_1, l_2) \, \in {\mathcal {K}}_i. \end{aligned}$$
(22)
These sets can be chosen such that
-
\(\bigcup _i ({\mathcal {K}}_i) = \{1,\dots ,M\}\),
-
\(\cap ({\mathcal {K}}_j, {\mathcal {K}}_k) = \emptyset \) for \(j \ne k\),
i.e., the sets span the entire range of admissible columns without selecting any column twice.
Once these sets have been defined, new pressure test vectors can be constructed by
$$\begin{aligned} \varDelta p_i^* := \sum _l \varDelta \hat{p}_{\kappa _{i,l}}. \end{aligned}$$
(23)
Since the stencils in the selected columns \(\kappa _{i,l}\) are completely independent, a unique mapping can be established to reconstruct the influence matrix columns \(\mathbf {a}_{\kappa _{i,l}}\) from the testing operation \({\mathcal {F}}( \varDelta \hat{p}_i^* )\). Namely, all rows, for which the matrix structure vector \(a_j^0, j \in {\mathcal {K}}_i\) are nonzero, belong to column j of the influence matrix.
The number of independent sets \({\mathcal {K}}\) depends on the used stencil for the discretization of the pressure gradient. Therefore, a constant number of test vectors \(\varDelta p_i^*\) are necessary to obtain the pressure influence matrix, regardless of the number of cells in the numerical grid. For our typical application example with coarse grids with \(10^3\) to \(10^4\) cells, the number of test vectors is reduced to less than 20. Due to this fact, a tremendous speed-up of the calculation is possible, keeping in mind that the influence matrix must be reconstructed in every iteration step.