Gas-cooled Microreactor Air Jacket: Nek5000 CFD Simulation

Contact: Anshuman Chaube (achaube.at.anl.gov), April Novak (anovak.at.anl.gov), Dillon Shaver (dshaver.at.anl.gov)

Model link: Air Jacket CFD Model

High Level Summary of Model

We have created a CFD model of a a gas-cooled microreactor air jacket cooling system that passively removes decay heat. The complex geometry and natural circulation-driven flow may be challenging to capture with systems-level codes without calibration from experiments or higher-fidelity thermal-fluid modelling. However, CFD is particularly well-suited to the task of modelling microreactor air jackets due to its ability to capture the effect of the complicated geometry on the flow with resolved boundary layers. We use Nek5000 to simulate flow through an industry-inspired prototypical geometry and predict heat transfer and flow characteristics. The boundary conditions given to us are representative of a reactor design in early stages of development. From these CFD simulations, it is possible to evaluate available models for bulk heat and momentum transfer that can be used in systems-level codes, and to develop modifications to those models specific to the proposed design. Given limited initial data, we can use CFD to fill in the gaps pertaining to systems-level quantities such as the friction factor, Nusselt number, the average heat flux, bulk temperature, and mean outlet temperature. The key idea here is to illustrate the utility of CFD in characterizing a newly developed system with greater accuracy than that achieved through systems-level codes and/or correlations-based analysis. We also aim to highlight the iterative improvement of the mass flow rate (varied as the Reynolds number) based on pressure and energy balance equations, which is the primary source of improvement over the results obtained using generic correlations. These equations in the workflow described below can be replaced by systems-levels tools or other software that can be used in conjunction with CFD in designing a microreactor.

We describe the geometry, the model setup, the fundamental equations used, and the boundary conditions of the CFD simulation. The results include the CFD solution as well as quantities of interest pertaining to systems-level modeling.

For our CFD simulations, we have used Nek5000 (ANL, 2019), which has been extensively validated and verified and used for many nuclear engineering applications. Nek5000 uses spectral element-based high-order spatial discretization, with second- and third-order time-stepping schemes available. It is highly scalable, and has capabilities for Direct Numerical Simulations, Large-Eddy Simulations, and unsteady Reynolds-Averaged Navier-Stokes (RANS) simulations.

Prerequisites

commentnote

This tutorial assumes that you are familiar with the Nek5000 tutorial and have a general awareness of Nek5000's case structure, setup, and basic usage. You may ignore sections of the tutorial that focus on Nek5000's internal meshing utilities such as genbox, and instead use another meshing tool to generate a mesh in one of the two external formats supported by Nek5000 - an Exodus mesh (converted to Nek-supported .re2 using the exo2nek utility), or a Gmsh .msh mesh (converted to .re2 using gmsh2nek). Also consider skimming through the RANS Tutorial and the RANS example files to get better acquainted with the RANS models used in Nek5000.

Model Description, Theory, and Setup

Prior to explaining the workings of the CFD model, this section explains the theory underpinning our analysis. We discuss the advantages of using Nek5000 over conventional finite element CFD codes, followed by a look at the equations and the workflow we utilize in this analysis.

Nek5000 Theory

Nek5000 is a high-order CFD solver with its spatial discretization based on the Spectral Element Method(SEM) (Fischer and Tomboulides, 2023). The Nek5000 implementation of SEM uses high-order Legendre polynomials as basis functions and Gauss Lobatto Legendre points as SEM nodes. This allows for excellent convergence, stability, and low numerical dispersion. SEM offers key advantages over conventional finite-element solvers due to its ability to enable matrix-free forward operator evaluation using 1D stiffness matrices applied in succession, as opposed to forming full 2D or 3D stiffness matrices as in conventional finite-element solvers. This lowers floating-point operations and storage requirements for SEM significantly. For example, in 3D, the action of discrete operators can be evaluated with work and using memory, which is respectively 2 and 1 order-of-magnitude lower than conventional finite elements (where is the number of elements, and the number of unknowns in one dimension ).

This, however, limits the method to quadrilateral or hexahedral mesh elements, as 1D matrices need to be along clearly separable orthogonal axes for matrix-free forward operator evaluation. The trade off with using quad or hex elements is that care must be taken in meshing complex geometries to ensure elements conform well to non-linear features. Additionally, SEM's computational advantages come into play when one uses high-order elements. For that reason, Nek5000 runs best with elements of an order of at least 5, and ideally 7-11. Accordingly, if your prior experience is meshing for lower-order finite-elements, consider making a coarser mesh than usual and run the simulation at a high polynomial order, otherwise you are likely to end up with an over-resolved mesh, and any computational advantages of SEM will be nullified by the surplus degrees of freedom.

Nek5000 uses BDFk-EXTk solvers (Deville et al., 2002) that use extrapolation-based stabilization and implicit treatment of the advective term to provide second- to third-order time-stepping.

The main equations solved are

(1)

(2)

(3)

Nek5000 is able to adjust its solver tolerances automatically and solve the equations above directly, working in what we refer to as the dimensional formulation. However, we often set up Nek5000 cases in the non-dimensional form, as Nek5000 solver tolerances are optimized for such a formulation.

The non-dimensionalised form of the Navier-Stokes equations is (Deville et al., 2002):

(4)

where the non-dimensional temperature is based on a user-defined and : (5)

commentnote

When non-dimensionalizing, carefully consider the characteristic length-scale, characteristic velocity and reference temperatures based on estimated temperature and velocity values. Ideally, we want the maximum non-dimensional velocity and temperature to be as close to 1 as possible, and the respective minimum values to be 0.

To keep the computational costs for this tutorial accessible to as wide of a target audience as possible, we have used RANS to model turbulence. The RANS model used in our work is wall-resolved k- (Kok and Spekreijse, 2000). The advantages of over are similar to those of , in that it is superior to in resolving the effects of near-wall behavior and the effects of streamwise pressure gradient. Additionally, it is more numerically stable than k- as , which simplifies wall boundary conditions to homogeneous Dirichlet conditions and creates well-bounded source terms for the scalar transport equation near the wall.

Air Jacket Geometry

The air jacket is a natural circulation driven passive heat removal component of a generic high-temperature gas-cooled microreactor. This "jacket" is the air gap between the reactor vessel and the shielding, as shown in Figure 1 (right). A wedge-shaped section of the fluid domain is shown in Figure 1 (left). The inner surface of the air gap is heated by the reactor vessel, whereas the outer surface is insulated. The inlet at the bottom supplies air at 50C. The heated section, which is held at a constant temperature of 420C, drives the flow by natural circulation, causing the air to rise through the heated section before exiting at the exhaust at the top. The geometry that we have simulated is the 2D cross-section of a wedge-shaped slice of the air jacket.

Figure 1: The microreactor core (right) and the air jacket geometry, meshed in 3D (left).

Pressure balance in natural circulation

A typical natural convection problem involves a closed loop with a heat source (usually heat flux boundary condition) and a heat sink. The problem here has an open loop that is representative of a nascent reactor design when the exact geometry is in flux and the heat sink and source are not precisely defined. Instead of a heat flux boundary condition, we are given a temperature Dirichlet condition which has a value equivalent to the maximum safe temperature of the hot wall, and we are asked to investigate the flow characteristics, friction factor, and heat transfer coefficient at said limiting condition.

The exact inlet boundary condition or the mass flow rate, and the outlet temperature are not known. However, based on the pressure balance expected for a natural convection problem, we can iteratively derive the mass flow rate, which can then be used to evaluate other quantities of interest.

To create a relatively inexpensive CFD model that is accessible to a wide range of users, we have chosen wall-resolved RANS as our turbulence model. The problem is essentially 2D in character, due to a lack of variation in CFD statistics in the azimuthal direction of the cylindrical air jacket domain after Reynolds-averaging. Hence a 2D simulation is adequate for the purposes of calculating flow and heat transfer characteristics for this geometry when using RANS. The problem is simulated in the axisymmetric mode to capture the cylindrical nature of the 3D geometry in relation to the 2D. The details of the axisymmetric mode setup are in the next section of the tutorial.

The effect of buoyancy is modeled using the simpler of two options available in Nek5000: the Boussinesq approximation, with air represented as an ideal gas, instead of the alternative, which is a low-Mach treatment with either ideal or real gas behavior (ANL, 2019). We are utilizing the simple gradient diffusion hypothesis to model the turbulent heat flux (Hsieh and Lien, 2004) with a turbulent Prandtl number of 0.85.

The density reduction as the air heats up in the air jacket creates the main buoyant pressure difference driving the natural circulation. The average density of air in the air jacket can be calculated during the simulation using the ideal gas law as a function of the mean temperature. Given temperature boundary conditions and dimensions, our main objective was to determine the friction factor and the Nusselt number (). The pressure balance at the steady state is given by:

(6)

Assuming the inlet is at the ambient conditions, the external gravitational pressure drop is simply The total internal pressure drop includes the mean internal gravitational pressure drop and minor losses (with form and friction losses modeled with an effective friction factor) where the mean internal gravitational pressure drop (based on the mean weight of the air in the air jacket) and minor losses are modeled respectively as (7) Combining these with the total pressure balance given by Eq. (6) yields (8)

Since the gravitational pressure drop is a hydrostatic quantity, we adopt "mean density" to imply volumetric mean (simple volumetric average) rather than bulk mean (velocity-weighted volumetric average). The mean density is then evaluated using the Boussinesq model and the ideal gas approximation (. The general relationship for density is then given by Since this gives a linear relationship between density and temperature, we have The pressure balance then becomes (9)

The friction factor can be obtained using (10)

Initial guess for velocity and mean temperature

Given the geometry, the inlet temperature, and the hot wall temperature, there are two main unknowns that we need to estimate: : the mean inlet velocity, which shall help us determine the Reynolds number of the simulation, and : the bulk temperature, that will help us understand the energy balance and define the Boussinesq acceleration term.

These two unknowns are coupled through pressure and energy balance equations. These equations involve the following quantities: (11) (12) where is the atmospheric pressure, the molar mass of air (approx. 28 g mol (Jones, 1978)), the gas constant, the Darcy friction factor, the Reynolds number, and the Prandtl number.

Note that we are assuming ideal gas behaviour, and are also neglecting the pressure differences within the domain relative to atmospheric pressure. The mean temperature is approximated as the mean of the inlet and outlet temperatures as an initial guess, and the outlet temperature is the independent unknown variable. The correlations for the friction factor and heat transfer coefficient assume turbulent flow. You may find other correlations to be more appropriate for your case, however the idea is to verify that the results obtained from the pressure and energy balance obtained later in this section are consistent with your assumptions and correlations. In this case, we will find that assuming the flow is not laminar is appropriate. Also note that the main unknowns are still and or , with Eq. (11)-Eq. (12) being secondary equations that will feed into our main pressure and energy balance equations.

The pressure balance equation has already been discussed (Eq. (9)). The energy balance is given by the balance between the convective heat transfer between the hot wall and the fluid bulk, and the heat advected into and out of the air jacket: (13) where is the hot wall area, the hot wall temperature, the cross section area of the channel.

The main equations to be solved for and are Eq. (9) and Eq. (13). These are non-linear, and can be easily solved with symbolic mathematics software or iterative solver packages such as scipy.

def pqbalance(ubto):
    ub, to = ubto
    #turbulent:
    expr1 = (rho_amb*beta*(T_mean(to)-T_in)*g*H) - (fdturb(ub)*rho_amb*ub*ub*H/2.0/Dh)
    expr2 = (Ahot*htcoeff(ub)*(T_hot-T_mean(to))) - (rho_amb*ub*Aw*Cp*(to-T_in))

    return (expr1,expr2)

if (turbulent):
    #turbulent solve
    Ubar, Tout =  scp.optimize.fsolve(pqbalance, (1.0, 0.5*(T_hot+T_in)))
(microreactors/gcmr/airjacket/re_estimate.py)

Approximations for (which require an approximate heat transfer coefficient ) and using conventional correlations (such as Dittus-Boelter and Blasius correlations, respectively) can be used for an initial guess, but as the simulation is run, values are calculated directly from the results. With these results, the correct and can be determined for a given .

We have assumed uniform inlet () and hot-wall temperatures () based on simple data from limiting conditions, while all remaining walls have adiabatic boundary conditions applied to temperature due to insulating material.

The outlet was artificially extended by a few characteristic lengths and the Boussinesq acceleration term gradually ramped down to allow for the highly biased jet in the upper plenum to redistribute and flow outwards at the outlet uniformly in order to avoid any eddies that can cause numerical divergence-inducing backflow at the outlet. The gradual ramping down prevents any effect on the results upstream. Wall resolution was ensured by monitoring 1 values at the first Gauss Lobatto Legendre point off the wall.

To capture the buoyant momentum source, we have applied the Boussinesq approximation. The Boussinesq term is a forcing term applied to the momentum Navier-Stokes Equation (Eq. (4)), which in non-dimensional terms, is expressed as where is the Richardson number, the dimensional local temperature, and the non-dimensional local temperature.

The average Nusselt Number is calculated as where is the average non-dimensional temperature gradient at the hot wall, the non-dimensional hot-wall temperature, and the non-dimensional fluid bulk temperature.

Once the simulation has attained a fully developed state, it is possible to compare the pressure drop calculated from the CFD simulation, say , and compare it to the expected pressure drop based on Eq. (7), that is, zero (as the external pressure is balanced by the internal pressure at steady state). If the two pressure drops do not match, it is possible to iterate on the value of the mass flow rate by adjusting characteristic velocityu , or in other words, the Reynolds number (Eq. (4)) until we arrive at the expected pressure drop, using the procedure described in Figure 2.

Figure 2: The iterative algorithm that can be used to derive the correct pressure drop according to Eq. (7).

Computational Model Description

The following section describes the input file and the model setup. Please note that the setup of the RANS model is identical to the Nek5000 RANS Channel tutorial mentioned in the introduction, and is therefore not repeated here for the sake of brevity.

Axisymmetric Mode Setup

In Nek5000, the axisymmetric mode requires the axis of symmetry to be the x-axis, which becomes the r-axis, while the y-axis becomes the vertical axis. Furthermore, the entire mesh must lie above the x-axis/r-axis, as there can be no negative r values. Your mesh needs to be oriented accordingly in your mesh generator. Mesh modifications can also be performed in Nek5000, in the usr file's usrdat2 function. For the air jacket mesh (Figure 1), the mesh needs to be rotated clockwise by 90 degrees to be aligned with the axis of symmetry. This is accomplished by the following code:

C     rescale the domain BEFORE calling rans_init

      theta = pi/2.0
      do i=1,n
        xx = xm1(i,1,1,1)
        yy = ym1(i,1,1,1)
        xm1(i,1,1,1) =  xx*cos(theta) + yy*sin(theta)
        ym1(i,1,1,1) = -xx*sin(theta) + yy*cos(theta)
      enddo
(microreactors/gcmr/airjacket/airjacket.usr)

Once the mesh has the desired orientation, the axisymmetric mode can be turned on in the par file using the axiSymmetry = yes line in the [PROBLEMTYPE] block:

[PROBLEMTYPE]
equation = incompNS
axiSymmetry = yes
(microreactors/gcmr/airjacket/airjacket.par)

Boundary Conditions, Initial Conditions, Boussinesq approximation

Tying sidesets to a type of boundary condition can be accomplished through the par file. For each field, such as VELOCITY, sidesets starting from 1 can be assigned a boundary type using the boundaryTypeMap key:

[VELOCITY]
density = 1.0
viscosity = -3580.0
residualTol = 1e-6
boundaryTypeMap = v  ,O  ,W  ,W  
(microreactors/gcmr/airjacket/airjacket.par)

A similar action can be accomplished in the usr file, in the usrdat2 routine, by modifying the cbc array. This is recommended when your sideset IDs have arbitrary numbers that do not start with 1

c     assign BCs to sidesets using cbc array
c      do e=1,nelv
c      do f=1,2*ndim
c        id_face = boundaryID(f,e)
c        if (id_face.eq.1) then        ! dirichlet (inlet)  BCs
c           cbc(f,e,1) = 'v  '
c           cbc(f,e,2) = 't  '
c        elseif (id_face.eq.2) then    ! Outlet
c           cbc(f,e,1) = 'O  '
c           cbc(f,e,2) = 'O  '
c        elseif (id_face.eq.3) then    ! Hot wall
c           cbc(f,e,1) = 'W  '
c           cbc(f,e,2) = 't  '
c        elseif (id_face.eq.4) then    ! Insulated wall
c           cbc(f,e,1) = 'W  '
c           cbc(f,e,2) = 'I  '
c        endif
c      enddo
(microreactors/gcmr/airjacket/airjacket.usr)

The inlet boundary has a constant , , , and boundary condition, and temperature is set to 0 based on our nondimensionalization. The hot wall temperature is set to a constant value of 1 in nondimensional terms (420 C), that is implemented with a short, linear ramp near the base of the hot wall to avoid sharp gradients that create problems with resolution of scalars. The walls have zero Dirichlet conditions for and . The outlet boundary condition is do-nothing, specified in the par file. The boundary conditions are specified in the usr file in the userbc subroutine:

      subroutine userbc(ix,iy,iz,iside,eg) ! set up boundary conditions
      implicit none
      include 'SIZE'
      include 'TOTAL'
      include 'NEKUSE'
c
c     NOTE ::: This subroutine MAY NOT be called by every process
c
      integer ix,iy,iz,iside,e,eg
    
C     U, TKE, and Omg are all zero on the wall 

      real xbnd1,xbnd2,xx,xhat,mx,cx

      real Re,mu0,rho0,Uc,T0,cp0,k0,Lc,L0,Thw
      common /props/ Re,mu0,rho0,Uc,T0,cp0,k0,Lc,L0,Thw

      e = gllel(eg)

      ux = 0.0 
      uy = -3.5630245817969738E-002 
      temp = 0.0

      if(cbc(iside,e,1).eq.'W  ') then           ! walls
        if(ifield.eq.3) temp = 0.0
        if(ifield.eq.4) temp = 0.0
      endif

      if(boundaryID(iside,e).eq.1) then           ! inlet
        if(ifield.eq.3) temp = 0.01! kibc(ix,iy,iz,e)
        if(ifield.eq.4) temp = 0.2 ! tauibc(ix,iy,iz,e)
      endif

      xbnd1 = -675.0/Lc
      xbnd2 = 824.9764/Lc
      xbnd2 = 0.1*(xbnd2-xbnd1) + xbnd1
      mx = 1.0/(xbnd2-xbnd1)
      cx = 1.0 - mx*xbnd2

      if(boundaryID(iside,e).eq.3.and.ifield.eq.2) then           ! hot wall
       xx = xm1(ix,iy,iz,e)
       if(xx.le.xbnd2) then       
        temp = mx*xx + cx
       else
        temp = 1.0
       endif
      endif

      return
      end
(microreactors/gcmr/airjacket/airjacket.usr)

The initial conditions are specified in useric as follows

      subroutine useric(ix,iy,iz,eg) ! set up initial conditions
      implicit none
      include 'SIZE'
      include 'TOTAL'
      include 'NEKUSE'

      integer ix,iy,iz,e,eg
      real xx,xtop

      real Re,mu0,rho0,Uc,T0,cp0,k0,Lc,L0,Thw
      common /props/ Re,mu0,rho0,Uc,T0,cp0,k0,Lc,L0,Thw

      e = gllel(eg)
      xx = xm1(ix,iy,iz,e)
      xtop = 30.0

      ux   = 0.0001
      uy   = -0.0001
      if (xx.gt.xtop) uy = 0.0001
      uz   = 0.0
      temp = 0.0

      if(ifield.eq.3) temp = 0.01 !97662386491144943E-005
      if(ifield.eq.4) temp = 0.2  !6.8956997219801952

      return
      end
(microreactors/gcmr/airjacket/airjacket.usr)

Note that these initial conditions are overwritten if the simulation is restarted from another run's output, using the startFrom option in the par file. A good initial condition is vital for stability and good convergence. Some tips for generating the initial condition for this simulation include running with a coarse mesh, turning off the axisymmetric mode, and using the obtained data to restart the simulation using the output obtained.

The Boussinesq approximation is applied as a forcing term in the userf routine. Note that the Richardson number is calculated in the userchk subroutine, and transferred to userf using a common block, as shown below. Complicated calculations that require global operations across all MPI ranks are best performed in userchk, as subroutines like userbc, useric, and userf are not called by every MPI process by design, as mentioned in the Nek5000 documentation and template .usr file (Nek5000/core/zero.usr). The Boussinesq term is gradually ramped down in the upper plenum, as we want the highly biased flow to redistribute and exit the domain cleanly, without causing backflow at the outlet, which can cause the simulation to diverge.

      subroutine userf(ix,iy,iz,eg) ! set acceleration term
      implicit none
      include 'SIZE'
      include 'TOTAL'
      include 'NEKUSE'
c
c     Note: this is an acceleration term, NOT a force!
c     Thus, ffx will subsequently be multiplied by rho(x,t).
c     userf is only called for velocity
c     temp is preloaded with t(ix,iy,iz,ie,1): see bdry.f:1181

      real Ri
      common /boussinesq/ Ri

      integer ix,iy,iz,eg,e
      real ybnd1,ybnd2, xx, yy, mb, cb,temp_mosdef

      real xmin,xmax,ymin,ymax,zmin,zmax
      common /dmn_size/ xmin,xmax,ymin,ymax,zmin,zmax

      ybnd1 = 0.6*ymax
      ybnd2 = 0.8*ymax
      mb = -1.0/(ybnd2-ybnd1)
      cb = -ybnd2*mb

      e = gllel(eg)
      xx = xm1(ix,iy,iz,e)
      yy = ym1(ix,iy,iz,e)

      ffz = 0.0
      ffy = 0.0
      ffx = Ri*temp
      if(yy.gt.ybnd1.and.yy.le.ybnd2.and.xx.gt.0.0) then ! ramping down gradually
        ffx = (mb*yy+cb)*Ri*temp
      endif
      if(yy.gt.ybnd2.and.xx.gt.0.0) then
        ffx = 0.0
      endif

      return
      end
(microreactors/gcmr/airjacket/airjacket.usr)

Meshing

When meshing, we performed h-refinement in our meshing software (Cubit) by adding elements to areas of transition between the channel and the plena, and other regions where under-resolution was observed. Then the final mesh refinement was performed using p-refinement in Nek (using the lx1 parameter in the SIZE file), as is typical in spectral elements. Also of note are the boundary layers, which can have a relatively aggressive growth rate in spectral elements(Figure 3).

Figure 3: The boundary layers in the channel.

The mesh was created using Cubit and a stp file provided by the reactor designer. The file was exported to the Exodus format and converted to the Nek-supported .re2 using the utility exo2nek. If Nek5000/bin is added to the $PATH, exo2nek can be executed directly from the command line. The tool guides the user through the mesh conversion process. In this case, we recommend skipping the element right-handedness check for the mesh and proceeding with the mesh conversion process as suggested by the command line prompts.

Wall resolution can be verified by checking values call the print_yplimits subroutine (provided in the extract_yp.f file) in userchk at whatever frequency is desired. The subroutine calculates values and outputs a variety of relevant metrics, the most important being the ratio of wall points with to the total number of wall points, outputted as ratio less than 1.0 is : in the logfile. Ideally, this ratio should be nearly 1.0. The values can also be visualized using the output array from print_yplimits dumped into a Nek5000 output file using the outpost function.

Statistics at runtime and postprocessing

To iterate on the Reynolds number until the correct pressure drop of zero is obtained we need to calculate the pressure drop across the channel. We also need to calculate the Nusselt number, mean and outlet temperatures, and monitor a variety of other quantities for convergence. Our averaging code can monitor simulations as they run, using lines printed in the logfile. The basic idea behind our code is to construct masks or maps that identify the correct points or element faces based on coordinate ranges. We want to do this once, at the beginning of the simulation in usrdat2, to not have to waste computational time looking for the same elements at every time step (which is what would occur if the following code were placed in userchk instead of usrdat2). We create element maps/masks, that store local element and face IDs based on the element's centroid being between a certain coordinate range, and the face lying along a normal

c    element map of lower plane, close to inlet
      norm1  = (/0.0,1.0,0.0/)
      ptmin1 = (/-764.0,-1163.0,0.0/)
      ptmax1 = (/-723.0,-1157.0,0.0/)

      call emap_nsurf(emap_lo,exyzlo,norm1,ptmin1,ptmax1)
      call test_emap(emap_lo,'elo')
(microreactors/gcmr/airjacket/airjacket.usr)

The above code will store zeros in the emap_lo array, indicating the local element ID corresponding to that index of emap_lo belongs to an element whose centroid does not lie in the specified range of x and y values. For elements that do lie within the specified coordinate range, the corresponding value of emap_lo at the index corresponding to the local element ID stores the face that has a normal closest to the normal specified. To verify the correct elements and faces have been selected, the test_emap function can be used. It will create a Nek output file with the name elo<casename>.nek5000, which can be opened in Paraview. Look at the x-velocity field - the element map emap_lo will be highlighted with values equal to 1.0 at each node on the face. The rest of the points will be zero.

Now that we have stored the element and face IDs that we need, we can average over faces using functions in the aravg.f file, that rely on Nek5000's internal functions facint_v and facint_a, which require element and face IDs as arguments. This will allow us to calculate area averages across the selected faces. Volumetric averages can be computed by constructing masks of nodes between a range of x and y values, using the following code

c     create masks for volumetric averages
      ptmin1 = (/-788.0,-1153.7,0.0/)
      ptmax1 = (/-720.0,1210.79,0.0/)
      call create_mask(msk_inout,ptmin1,ptmax1)
(microreactors/gcmr/airjacket/airjacket.usr)

These element maps can be stored in a common block, so that they are accessible in userchk despite being created in usrdat2. To average any of the Nek5000 solution arrays over these element maps, simply call the following functions from aravg.f in userchk, such as

c     calculating averages of vx,vy,temp,k,tau

      uinav = emap_avg(vx,emap_in)
      vinav = emap_avg(vy,emap_in)
      tinav   = emap_avg(t(1,1,1,1,1),emap_in)
      kinav   = emap_avg(t(1,1,1,1,2),emap_in)
      tauinav = emap_avg(t(1,1,1,1,3),emap_in)
(microreactors/gcmr/airjacket/airjacket.usr)

Bulk averages can be calculated similarly using the point masks and the bulkavg function. Weighted scalar averages or area integrals can be calculated using the emap_scalar_avg function. The variables can be saved, for example, using a common block, and the difference between their values at successive time-steps printed to monitor convergence. Gradients for calculating the Nusselt number are obtained using Nek5000's gradm1 subroutine, and the gradients are averaged over the hot-wall to obtain a heat flux using Nek5000's facint function.

Using these postprocessing functions, we can monitor the pressure drop across the channel at runtime by calculating the average pressure at the top and bottom of the channel, and iterating on the Reynolds number until the difference between the calculated pressure drop and the target pressure drop is below the solver tolerance.

c     pressure drop calculation
      pin = emap_avg(pr,emap_lo)
      pout = emap_avg(pr,emap_hi)
      dp = pin - pout
(microreactors/gcmr/airjacket/airjacket.usr)

Input parameters

A list of miscellaneous input parameters is included in Table 1 for reproducibility.

Table 1: Simulation input parameters.

ParameterValueUnit
Inlet temperature323.15K
Hot wall temperature693.15K
Density1.10342 (Lemmon et al., 2000)kg m
Viscosity1.951 10 (Kestin and Whitelaw, 1964)Pa s
Thermal conductivity0.02766 (Stephan and Laesecke, 1985)W m K
Specific Heat Capacity 1007.4333 (Lemmon et al., 2000)J kg K
Prandtl Number0.710594-
Characteristic length40mm
(Eq. (5))323.15K
(Eq. (5))370.0K
Pressure solver tolerance10-
Velocity solver tolerance10-
solver tolerance10-
solver tolerance10-

Results

The velocity and temperature results obtained are shown in Figure 4 and Figure 5. The flow enters the domain from the bottom left in the lower plenum, and accelerates in the hot channel due to a narrowing of the cross-section and due to the Boussinesq acceleration term. The air leaves the heated channel and enters the upper plenum in a state biased entirely towards the top of the plenum. The gradual ramping down of the Boussinesq term in the upper plenum gradually redistributes this jet and allows it to exit the domain without any backflow at the outlet, while causing no impact on the results upstream. The relatively low Reynolds number in the hot channel (obtained both through correlations and our iterative analysis) does not promote significant mixing in the channel itself. For the purposes of visualization, the excess upper plenum outlet region has been clipped by about 50% to remove the region that exists only for allowing the flow to redistribute and exit the domain cleanly.

Figure 4: The velocity solution.

Figure 5: The temperature solution.

The quantities of interest calculated from steady state results are summarized in Table 2. Note that CFD also allows the estimation of certain data that cannot be reliably estimated from correlations alone without significant approximations and simplifications.

Table 2: Summary of results.

ParameterCorrelation-based estimateCFD-based resultUnits
Reynolds Number3152.993580-
Friction Factor0.04090.028403-
Nusselt Number13.9813.53-
Bulk temperature-352.458K
Outlet temperature-383.394K
Heat flux-3.01 10W m
Heat removed per second-2.072 10W

Run Command

To generate an .ma2 file for your mesh (.re2), use genmap, as described in the Nek5000 tutorial. Adjust the mesh resolution and other parameters in the SIZE file, and compile using makenek <casename>. To run the case, execute


nekbmpi airjacket 144

which uses the script nekbmpi to internally call mpiexec. On some HPC systems, srun may be required instead.

References

  1. ANL. Nek5000 Version 19.0. Argonne National Laboratory, Illinois, 2019. URL: https://nek5000.mcs.anl.gov.[BibTeX]
  2. M. O. Deville, P. F. Fischer, and E. H. Mund. High-Order Methods for Incompressible Fluid Flow. Cambridge Monographs on Applied and Computational Mathematics, August 2002. URL: /core/books/highorder-methods-for-incompressible-fluid-flow/D59381B3A2968E7ADED018C47201964C (visited on 2019-10-29), doi:10.1017/CBO9780511546792.[BibTeX]
  3. Paul F. Fischer and Ananias G. Tomboulides. Chapter 3 - Spectral element methods for turbulence. In Robert D. Moser, editor, Numerical Methods in Turbulence Simulation, Numerical Methods in Turbulence, pages 95–137. Academic Press, January 2023. URL: https://www.sciencedirect.com/science/article/pii/B9780323911443000097 (visited on 2023-08-09), doi:10.1016/B978-0-32-391144-3.00009-7.[BibTeX]
  4. K. J. Hsieh and F. S. Lien. Numerical modeling of buoyancy-driven turbulent flows in enclosures. International Journal of Heat and Fluid Flow, 25(4):659–670, August 2004. URL: https://www.sciencedirect.com/science/article/pii/S0142727X03001565 (visited on 2023-05-01), doi:10.1016/j.ijheatfluidflow.2003.11.023.[BibTeX]
  5. Frank E. Jones. The Air Density Equation and the Transfer of the Mass Unit. Journal of Research of the National Bureau of Standards, 83(5):419–428, 1978. URL: https://www.ncbi.nlm.nih.gov/pmc/articles/PMC6764509/ (visited on 2023-08-10), doi:10.6028/jres.083.028.[BibTeX]
  6. J. Kestin and J. H. Whitelaw. The viscosity of dry and humid air. International Journal of Heat and Mass Transfer, 7(11):1245–1255, November 1964. URL: https://www.sciencedirect.com/science/article/pii/0017931064900663 (visited on 2023-08-10), doi:10.1016/0017-9310(64)90066-3.[BibTeX]
  7. J. C. Kok and S. P. Spekreijse. Efficient and accurate implementation of the k-omega turbulence model in the NLR multi-block Navier-Stokes system. Technical Report, Nationaal Lucht- en Ruimtevaartlaboratorium, 2000. URL: https://reports.nlr.nl/handle/10921/822 (visited on 2021-04-21).[BibTeX]
  8. Eric W. Lemmon, Richard T Jacobsen, Steven G. Penoncello, and Daniel G. Friend. Thermodynamic Properties of Air and Mixtures of Nitrogen, Argon, and Oxygen From 60 to 2000 K at Pressures to 2000 MPa. Journal of Physical and Chemical Reference Data, 29(3):331–385, May 2000. URL: https://doi.org/10.1063/1.1285884 (visited on 2023-08-09), doi:10.1063/1.1285884.[BibTeX]
  9. K. Stephan and A. Laesecke. The Thermal Conductivity of Fluid Air. Journal of Physical and Chemical Reference Data, 14(1):227–234, January 1985. URL: https://doi.org/10.1063/1.555749 (visited on 2023-08-09), doi:10.1063/1.555749.[BibTeX]