<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//NLM//DTD Journal Publishing with OASIS Tables v3.0 20080202//EN" "journalpub-oasis3.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:oasis="http://docs.oasis-open.org/ns/oasis-exchange/table" dtd-version="3.0"><?xmltex \makeatother\@nolinetrue\makeatletter?>
  <front>
    <journal-meta>
<journal-id journal-id-type="publisher">GMD</journal-id>
<journal-title-group>
<journal-title>Geoscientific Model Development</journal-title>
<abbrev-journal-title abbrev-type="publisher">GMD</abbrev-journal-title>
<abbrev-journal-title abbrev-type="nlm-ta">Geosci. Model Dev.</abbrev-journal-title>
</journal-title-group>
<issn pub-type="epub">1991-9603</issn>
<publisher><publisher-name>Copernicus Publications</publisher-name>
<publisher-loc>Göttingen, Germany</publisher-loc>
</publisher>
</journal-meta>

    <article-meta>
      <article-id pub-id-type="doi">10.5194/gmd-9-3803-2016</article-id><title-group><article-title>A structure-exploiting numbering algorithm for finite elements on
extruded meshes, and its performance evaluation in Firedrake</article-title>
      </title-group><?xmltex \runningtitle{A numbering algorithm for finite elements on extruded meshes}?><?xmltex \runningauthor{G.-T. Bercea et al.}?>
      <contrib-group>
        <contrib contrib-type="author" corresp="yes" rid="aff1">
          <name><surname>Bercea</surname><given-names>Gheorghe-Teodor</given-names></name>
          <email>gb308@doc.ic.ac.uk</email>
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff2 aff3 aff4">
          <name><surname>McRae</surname><given-names>Andrew T. T.</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff3">
          <name><surname>Ham</surname><given-names>David A.</given-names></name>
          
        <ext-link>https://orcid.org/0000-0001-9545-9110</ext-link></contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1 aff3">
          <name><surname>Mitchell</surname><given-names>Lawrence</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1 aff5">
          <name><surname>Rathgeber</surname><given-names>Florian</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Nardi</surname><given-names>Luigi</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Luporini</surname><given-names>Fabio</given-names></name>
          
        </contrib>
        <contrib contrib-type="author" corresp="no" rid="aff1">
          <name><surname>Kelly</surname><given-names>Paul H. J.</given-names></name>
          
        </contrib>
        <aff id="aff1"><label>1</label><institution>Department of Computing, Imperial College London, London, SW7 2AZ, UK</institution>
        </aff>
        <aff id="aff2"><label>2</label><institution>The Grantham Institute, Imperial College London, London, SW7 2AZ, UK</institution>
        </aff>
        <aff id="aff3"><label>3</label><institution>Department of Mathematics, Imperial College London, London, SW7 2AZ, UK</institution>
        </aff>
        <aff id="aff4"><label>4</label><institution>Department of Mathematical Sciences, University of Bath, Bath, BA2 7AY, UK</institution>
        </aff>
        <aff id="aff5"><label>5</label><institution>European Centre for Medium-Range Weather Forecasts (ECMWF), Reading, RG2 9AX, UK</institution>
        </aff>
      </contrib-group>
      <author-notes><corresp id="corr1">Gheorghe-Teodor Bercea (gb308@doc.ic.ac.uk)</corresp></author-notes><pub-date><day>27</day><month>October</month><year>2016</year></pub-date>
      
      <volume>9</volume>
      <issue>10</issue>
      <fpage>3803</fpage><lpage>3815</lpage>
      <history>
        <date date-type="received"><day>27</day><month>May</month><year>2016</year></date>
           <date date-type="rev-request"><day>9</day><month>June</month><year>2016</year></date>
           <date date-type="rev-recd"><day>16</day><month>September</month><year>2016</year></date>
           <date date-type="accepted"><day>26</day><month>September</month><year>2016</year></date>
      </history>
      <permissions>
<license license-type="open-access">
<license-p>This work is licensed under a Creative Commons Attribution 3.0 Unported License. To view a copy of this license, visit <ext-link ext-link-type="uri" xlink:href="http://creativecommons.org/licenses/by/3.0/">http://creativecommons.org/licenses/by/3.0/</ext-link></license-p>
</license>
</permissions><self-uri xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016.html">This article is available from https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016.html</self-uri>
<self-uri xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016.pdf">The full text article is available as a PDF file from https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016.pdf</self-uri>


      <abstract>
    <p>We present a generic algorithm for numbering and then efficiently iterating
over the data values attached to an extruded mesh. An extruded mesh is formed
by replicating an existing mesh, assumed to be unstructured, to form layers
of prismatic cells. Applications of extruded meshes include, but are not
limited to, the representation of three-dimensional high aspect ratio domains
employed by geophysical finite element simulations. These meshes are
structured in the extruded direction. The algorithm presented here exploits
this structure to avoid the performance penalty traditionally associated with
unstructured meshes. We evaluate the implementation of this algorithm in the
Firedrake finite element system on a range of low compute intensity
operations which constitute worst cases for data layout performance
exploration. The experiments show that having structure along the extruded
direction enables the cost of the indirect data accesses to be amortized
after 10–20 layers as long as the underlying mesh is well ordered. We
characterize the resulting spatial and temporal reuse in a representative set
of both continuous-Galerkin and discontinuous-Galerkin discretizations. On
meshes with realistic numbers of layers the performance achieved is between
70 and 90 % of a theoretical hardware-specific limit.</p>
  </abstract>
    </article-meta>
  </front>
<body>
      

      <?xmltex \hack{\newpage}?>
<sec id="Ch1.S1" sec-type="intro">
  <title>Introduction</title>
      <p>In the field of numerical simulation of fluids and structures, there is
traditionally considered to be a tension between the computational efficiency
and ease of implementation of structured grid models, and the flexible
geometry and resolution offered by unstructured meshes.</p>
      <p>In particular, one of the grand challenges in simulation science is modelling
the ocean and atmosphere for the purposes of predicting the weather or
understanding the Earth's climate system. The current generation of
large-scale operational atmosphere and ocean models almost all employ
structured meshes <xref ref-type="bibr" rid="bib1.bibx31" id="paren.1"/>. However, requirements for geometric
flexibility as well as the need to overcome scalability issues created by the
poles of structured meshes have led in recent years to a number of national
projects to create unstructured mesh models
<xref ref-type="bibr" rid="bib1.bibx8 bib1.bibx34 bib1.bibx30" id="paren.2"/>.</p>
      <p>The ocean and atmosphere are thin shells on the Earth's surface, with typical
domain aspect ratios in the thousands (oceans are a few kilometres deep but
thousands of kilometres across). Additionally the direction of gravity and
the stratification of the ocean and atmosphere create important scale
separations between the vertical and horizontal directions. The consequence
of this is that even unstructured mesh models of the ocean and atmosphere are
in fact only unstructured in the horizontal direction, while the mesh is
composed of aligned layers in the vertical direction. In other words, the
meshes employed in the new generation of models are the result of extruding
an unstructured two-dimensional mesh to form a layered mesh of prismatic
elements.</p>
      <p>This layered structure was exploited in <xref ref-type="bibr" rid="bib1.bibx19" id="text.3"/> to create a numbering
for a finite volume atmospheric model such that iteration from one cell to
the next within a vertical column required only direct addressing. They show
that when only paying the price of indirect addressing on the base mesh there
is less than 5 % performance difference between two implementations of an
atmospheric model which treat the same icosahedral mesh first as fully
structured and then as partially structured (extruded). One of the caveats of
that comparison is that the underlying mesh is fully structured in both
cases, which presents an advantage to the indirect addressing scheme which is
not present for more general unstructured meshes.</p>
      <p>Exploiting the anisotropic nature of domains has seen various software
developments in various fields. For example, <monospace>p6est</monospace>
(<xref ref-type="bibr" rid="bib1.bibx14" id="altparen.4"/> and <xref ref-type="bibr" rid="bib1.bibx13" id="altparen.5"><named-content content-type="post">Sect. 2.3</named-content></xref>), a package for
2 <inline-formula><mml:math display="inline"><mml:mo>+</mml:mo></mml:math></inline-formula> 1 dimensional adaptive mesh refinement, was developed to maintain
columnwise numbering for numerical reasons in ice sheet modelling, but does
not support general unstructured base meshes. The DUNE-PrismGrid
module <xref ref-type="bibr" rid="bib1.bibx9" id="paren.6"/> provides extruded meshes for any base DUNE
grid, but does not describe a degree of freedom numbering or provide detailed
performance characteristics of the iteration on extruded meshes. The Model
for Prediction Across Scales (MPAS) uses a column innermost numbering for
their C-grid atmospheric and ocean model <xref ref-type="bibr" rid="bib1.bibx29" id="paren.7"/>. Their
implementation is limited to the single discretization employed by that
model.</p>
      <p>A key motivation for this work was to provide an efficient mechanism for the
implementation of the layered finite element numerics which have been adopted
by the UK Met Office's Gung Ho programme to develop a new atmospheric
dynamical core. The algorithms here have been adopted by the Met Office for
this purpose <xref ref-type="bibr" rid="bib1.bibx8" id="paren.8"/>. While geophysical applications motivate this
work, the algorithms and their implementation in Firedrake
<xref ref-type="bibr" rid="bib1.bibx28" id="paren.9"/> are more general and could be applied to any high
aspect ratio domain.</p>
<sec id="Ch1.S1.SSx1" specific-use="unnumbered">
  <title>Contributions</title>
      <p><list list-type="bullet">
            <list-item>

      <p>We generalize the numbering algorithm in <xref ref-type="bibr" rid="bib1.bibx19" id="text.10"/> to the full range of finite element discretizations.</p>
            </list-item>
            <list-item>

      <p>We demonstrate the effectiveness of the algorithm with respect to absolute hardware performance limits.</p>
            </list-item>
          </list></p>
</sec>
</sec>
<sec id="Ch1.S2">
  <title>Unstructured meshes</title>
      <p>In this section we briefly restate the data model for unstructured meshes
introduced in <xref ref-type="bibr" rid="bib1.bibx17" id="text.11"/> and <xref ref-type="bibr" rid="bib1.bibx15" id="text.12"/>. In
Sect. <xref ref-type="sec" rid="Ch1.S2.SS2"/> we rigorously define a <italic>mesh</italic>, and explain
mesh topology, geometry, and numbering. In Sect. <xref ref-type="sec" rid="Ch1.S2.SS3"/> we
explain how data may be associated with meshes.</p>
<sec id="Ch1.S2.SS1">
  <title>Terminology</title>
      <p>When describing a mesh, we need some way of specifying the neighbours of a
given entity. This is always possible using <italic>indirect addressing</italic> in
which the neighbours are explicitly enumerated, and sometimes possible with
<italic>direct addressing</italic> where a closed-form mathematical expression
suffices.</p>
      <p>In what follows we start with a <italic>base mesh</italic> which we will
<italic>extrude</italic> to form a mesh of higher topological dimension. Due to
geophysical considerations, we refer to the plane of the base mesh as the
<italic>horizontal</italic> and to the layers as the <italic>vertical</italic>.</p>
      <p>We will also employ the definition of a <italic>graph</italic> as a set <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula> and a set
<inline-formula><mml:math display="inline"><mml:mi>E</mml:mi></mml:math></inline-formula> of edges where each edge represents the relationships between the
elements of the set <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula>.</p>
</sec>
<sec id="Ch1.S2.SS2">
  <title>Meshes</title>
      <p>A mesh is a decomposition of a simulation domain into non-overlapping
polygonal or polyhedral cells. We consider meshes used in algorithms for the
automatic numerical solution of partial differential equations. These meshes
combine topology and geometry. The topology of a mesh is composed of mesh
entities (such as vertices, edges, and cells) and the adjacency relationships
between them (cells to vertices or edges to cells). The geometry of the mesh
is represented by coordinates which define the position of the mesh entities
in space.</p>
      <p>Every mesh entity has a topological dimension given by the minimum number of
spatial dimensions required to represent that entity. We define <inline-formula><mml:math display="inline"><mml:mi>D</mml:mi></mml:math></inline-formula> to be the
minimum number of spatial dimensions needed to represent a mesh and all its
entities. A vertex is representable in zero-dimensional space; similarly, an
edge is a one-dimensional entity and a cell a <inline-formula><mml:math display="inline"><mml:mi>D</mml:mi></mml:math></inline-formula>-dimensional entity. In a
two-dimensional mesh of triangles, for example, the entities are the
vertices, edges, and triangle cells with topological dimensions <inline-formula><mml:math display="inline"><mml:mn mathvariant="normal">0</mml:mn></mml:math></inline-formula>, <inline-formula><mml:math display="inline"><mml:mn mathvariant="normal">1</mml:mn></mml:math></inline-formula>, and
<inline-formula><mml:math display="inline"><mml:mn mathvariant="normal">2</mml:mn></mml:math></inline-formula> respectively. The minimum number of geometric dimensions needed to
represent the mesh and all its entities is <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>D</mml:mi><mml:mo>=</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:mrow></mml:math></inline-formula>.</p>
      <p>A mesh can be represented by several graphs. Each graph consists of a
multi-type set <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula> and a typed adjacency relationship <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mtext>Adj</mml:mtext><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> between <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> typed elements in <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula>. The type of an
entity in <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula> is simply its dimension. The adjacency graphs will always map
from a set of uniform dimension to a set of uniform dimension. Attaching
types to elements of <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula> enables graphs to capture the relationships between
different mesh entities, for example cells and vertices, and edges and
vertices.</p>
      <p>We write <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>V</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> to mean the set of mesh entities of topological dimension <inline-formula><mml:math display="inline"><mml:mi>d</mml:mi></mml:math></inline-formula> where <inline-formula><mml:math display="inline"><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:mi>d</mml:mi><mml:mo>≤</mml:mo><mml:mi>D</mml:mi></mml:mrow></mml:math></inline-formula>:
            <disp-formula id="Ch1.E1" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msub><mml:mi>V</mml:mi><mml:mi>d</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:mo mathvariant="italic">{</mml:mo><mml:mo>(</mml:mo><mml:mi>d</mml:mi><mml:mo>,</mml:mo><mml:mi>i</mml:mi><mml:mo>)</mml:mo><mml:mspace width="0.33em" linebreak="nobreak"/><mml:mo>|</mml:mo><mml:mn> 0</mml:mn><mml:mo>≤</mml:mo><mml:mi>i</mml:mi><mml:mo>≤</mml:mo><mml:msub><mml:mi>N</mml:mi><mml:mi>d</mml:mi></mml:msub><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo mathvariant="italic">}</mml:mo><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
          where <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>N</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> is the number of entities of dimension <inline-formula><mml:math display="inline"><mml:mi>d</mml:mi></mml:math></inline-formula>. The set <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula>
is then simply the union of the <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>V</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula>s:
            <disp-formula id="Ch1.E2" content-type="numbered"><mml:math display="block"><mml:mrow><mml:mi>V</mml:mi><mml:mo>=</mml:mo><mml:munder><mml:mo movablelimits="false">⋃</mml:mo><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:mi>d</mml:mi><mml:mo>≤</mml:mo><mml:mi>D</mml:mi></mml:mrow></mml:munder><mml:msub><mml:mi>V</mml:mi><mml:mi>d</mml:mi></mml:msub><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>
      <p>Every mesh entity has a number of adjacent entities. The mesh–element
connectivity relationships are used to specify the way mesh entities are
connected. For a given mesh of topological dimension <inline-formula><mml:math display="inline"><mml:mi>D</mml:mi></mml:math></inline-formula> there are <inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:mi>D</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:msup><mml:mo>)</mml:mo><mml:mn mathvariant="normal">2</mml:mn></mml:msup></mml:mrow></mml:math></inline-formula>
different types of adjacency relationships. To define the mesh, only a
minimal subset of relationships from which all the others can be derived is
required. For example, as shown in <xref ref-type="bibr" rid="bib1.bibx17" id="text.13"/>, the complete set of
adjacency relationships may be derived from the cell–vertex adjacency.</p>
      <p>We write
            <disp-formula id="Ch1.E3" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msub><mml:mtext>Adj</mml:mtext><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:math></disp-formula>
          to specify the entities <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo>∈</mml:mo><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> adjacent to <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>v</mml:mi><mml:mo>∈</mml:mo><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>.</p>
      <p>In a mesh with a very regular topology, there may be a closed-form
mathematical expression for the adjacency relationship <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mtext>Adj</mml:mtext><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula>. Such meshes are termed <italic>structured</italic>. However, since we are
also interested in supporting more general <italic>unstructured meshes</italic>, we
must store the lists of adjacent entities explicitly.</p>
</sec>
<sec id="Ch1.S2.SS3">
  <title>Attaching data to meshes</title>
      <p>Every mesh entity has a number of values associated with it. These values are
also known as <italic>degrees of freedom</italic> and they are the discrete
representation of the continuous data fields of the domain. As the degrees of
freedom are uniquely associated with mesh entities, the mesh topology can be
used to access the degrees of freedom local to any entity using the
connectivity relationships.</p>
      <p>A <italic>finite element discretization</italic> associates a number of degrees of
freedom with each entity of the mesh. A <italic>function space</italic> uses the
discretization to define a numbering for all the degrees of freedom. Multiple
different function spaces may be defined on a mesh and each function space
may have several data fields associated with it. In the case of a triangular
mesh for example, a piecewise linear function space will associate a degree
of freedom with every vertex of the mesh, while a cubic function space will
associate one degree of freedom with every vertex, two degrees of freedom
with every edge, and one degree of freedom with every cell. In the former
case there will be 3 degrees of freedom adjacent to a cell, and a total of 10
in the latter case.</p>
      <p>The data associated with the mesh also need to be numbered. The choice of
numbering can have a significant effect on the computational efficiency of
calculations over the mesh <xref ref-type="bibr" rid="bib1.bibx11 bib1.bibx16 bib1.bibx33" id="paren.14"/>.</p>
</sec>
<sec id="Ch1.S2.SS4">
  <title>Kernels and stencils</title>
      <p>The most common operation performed on meshes is the local application of a
function or <italic>kernel</italic> while traversing or <italic>iterating</italic> over a
homogeneous subset of mesh entities. The kernel is executed once for each
such mesh entity and acts on the degrees of freedom in a <italic>stencil</italic>
composed of the mesh entities adjacent to the the iterated entity. For
example, a finite element operator evaluating an integral over the domain
would iterate over the mesh cells and access data through a stencil
comprising the degrees of freedom on that cell and its adjacent facets,
edges, and vertices. For a more in-depth discussion on the construction of
stencils on unstructured meshes, the reader is referred to <xref ref-type="bibr" rid="bib1.bibx17" id="text.15"/>
and <xref ref-type="bibr" rid="bib1.bibx15" id="text.16"/>. In theory, this requires cell-to-facets,
cell-to-edges, and cell-to-vertices adjacency relationships (cell-to-cell is
implicit). In practice the three different relationships may be composed into
a single adjacency relationship which references the data associated with all
the different adjacent entity types.</p>
      <p>In the unstructured case, we store an explicit list (also known as a
<italic>map</italic>) <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>L</mml:mi><mml:mo>(</mml:mo><mml:mi>e</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> for each type of stencil operation which given a
topological entity <inline-formula><mml:math display="inline"><mml:mi>e</mml:mi></mml:math></inline-formula> returns the set of degrees of freedom in the stencil at
that entity.</p>
</sec>
</sec>
<sec id="Ch1.S3">
  <title>Extruded meshes</title>
      <p>In Sect. <xref ref-type="sec" rid="Ch1.S3.SS1"/> we introduce extruded meshes and in
Sect. <xref ref-type="sec" rid="Ch1.S3.SS2"/> we show how the entities and the data are to be
numbered. In Sect. <xref ref-type="sec" rid="Ch1.S3.SS3"/> we present the extruded mesh
iteration algorithm and the offset computation for the direct addressing
scheme along the vertical direction.</p>
<sec id="Ch1.S3.SS1">
  <title>Definition of an extruded mesh</title>
      <p>An extruded mesh consists of a base mesh which is replicated a fixed number
of times in a layered structure<fn id="Ch1.Footn1"><p>For ease of
exposition, we discuss the case where each mesh column contains the
same number of layers; however, this is not a limitation of the
method and algorithms presented here</p></fn>. A mesh of topological
dimension <inline-formula><mml:math display="inline"><mml:mi>D</mml:mi></mml:math></inline-formula> becomes an extruded mesh of topological dimension
<inline-formula><mml:math display="inline"><mml:mrow><mml:mi>D</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula>.</p>
      <p>The mesh definition can be extended to include extruded meshes. Let mesh <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>M</mml:mi><mml:mo>=</mml:mo><mml:mo>(</mml:mo><mml:mi>V</mml:mi><mml:mo>,</mml:mo><mml:mtext>Adj</mml:mtext><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> be a non-extruded mesh where Adj stands for all the
valid adjacency relationships of <inline-formula><mml:math display="inline"><mml:mi>M</mml:mi></mml:math></inline-formula>. An extruded mesh which has <inline-formula><mml:math display="inline"><mml:mi>M</mml:mi></mml:math></inline-formula> as the
base mesh can be defined as a triple <inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:msup><mml:mi>V</mml:mi><mml:mtext>extr</mml:mtext></mml:msup><mml:mo>,</mml:mo><mml:msup><mml:mtext>Adj</mml:mtext><mml:mtext>extr</mml:mtext></mml:msup><mml:mo>,</mml:mo><mml:mi mathvariant="italic">λ</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> where <inline-formula><mml:math display="inline"><mml:mrow><mml:msup><mml:mtext>Adj</mml:mtext><mml:mtext>extr</mml:mtext></mml:msup></mml:mrow></mml:math></inline-formula> is the
set of valid adjacency relationships and <inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="italic">λ</mml:mi><mml:mo>∈</mml:mo><mml:msup><mml:mi mathvariant="double-struck">N</mml:mi><mml:mo>+</mml:mo></mml:msup></mml:mrow></mml:math></inline-formula> is the
number of intervals over which the mesh is extruded. This implies that there
are <inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="italic">λ</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> vertices in the extruded direction. Before we can define
<inline-formula><mml:math display="inline"><mml:mrow><mml:msup><mml:mi>V</mml:mi><mml:mtext>extr</mml:mtext></mml:msup></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math display="inline"><mml:mrow><mml:msup><mml:mtext>Adj</mml:mtext><mml:mtext>extr</mml:mtext></mml:msup></mml:mrow></mml:math></inline-formula> several concepts have to be
introduced.</p>
<sec id="Ch1.S3.SS1.SSS1">
  <title>Tensor product cells</title>
      <p>The effect of the extrusion process on the base mesh can always be captured
by associating a line segment with the vertical direction. We write
<inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>D</mml:mi><mml:mtext>b</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula> for the topological dimension of the base mesh, while the
topological dimension of the vertical mesh is always equal to <inline-formula><mml:math display="inline"><mml:mn mathvariant="normal">1</mml:mn></mml:math></inline-formula>.</p>
      <p>As a consequence, the cells of the extruded mesh are prisms formed by taking
the tensor product of the base mesh cell with the vertical line segment. For
example, each triangle becomes a triangular prism. The construction of tensor
product cells and finite element spaces on them is considered in more detail
in <xref ref-type="bibr" rid="bib1.bibx21" id="text.17"/>.</p>
</sec>
<sec id="Ch1.S3.SS1.SSS2">
  <title>Extruded mesh entities</title>
      <p>The extrusion process introduces new types of mesh entities reflecting the
connectivity between layers. The pairs of corresponding entities of dimension
<inline-formula><mml:math display="inline"><mml:mi>d</mml:mi></mml:math></inline-formula> in adjacent layers are connected using entities of dimension <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>d</mml:mi><mml:mo>+</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula>. In a
triangular mesh for example (Fig. <xref ref-type="fig" rid="Ch1.F1"/>), the corresponding
vertices are connected using vertical edges, edges contained in each layer
are connected by quadrilateral facets, and the two-dimensional triangle faces
are connected by a three-dimensional triangular prism
(Fig. <xref ref-type="fig" rid="Ch1.F2"/>).</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F1"><caption><p>Extruded mesh entities belonging to the base mesh to be extruded
(left to right): vertices, horizontal edges, horizontal facets.</p></caption>
            <?xmltex \igopts{width=156.490157pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f01.pdf"/>

          </fig>

      <?xmltex \floatpos{t}?><fig id="Ch1.F2"><caption><p>Mesh entities used in the extrusion process to connect entities in
Fig. <xref ref-type="fig" rid="Ch1.F1"/> (left to right): vertical edges, vertical facets,
three-dimensional cells.</p></caption>
            <?xmltex \igopts{width=156.490157pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f02.pdf"/>

          </fig>

      <p>The topological dimension on its own is no longer enough to distinguish
between the different types of entities and their orientation. Instead
entities are characterized by a pair composed of the horizontal and vertical
dimensions. In the case of a two-dimensional triangular base mesh, the set of
dimensions is <inline-formula><mml:math display="inline"><mml:mrow><mml:mo mathvariant="italic">{</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">2</mml:mn><mml:mo mathvariant="italic">}</mml:mo></mml:mrow></mml:math></inline-formula>. The line segment of the vertical can be
described by the set of dimensions <inline-formula><mml:math display="inline"><mml:mrow><mml:mo mathvariant="italic">{</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo mathvariant="italic">}</mml:mo></mml:mrow></mml:math></inline-formula>. The Cartesian product of the
two sets yields a set of pairs (Eq. <xref ref-type="disp-formula" rid="Ch1.E4"/>) which can be used to
uniquely identify mesh entities.
              <disp-formula id="Ch1.E4" content-type="numbered"><mml:math display="block"><mml:mrow><mml:mo mathvariant="italic">{</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">2</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">2</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo><mml:mo mathvariant="italic">}</mml:mo></mml:mrow></mml:math></disp-formula>
            We refer to the components of each pair as the <italic>horizontal</italic> and
<italic>vertical</italic> dimensions of the entity respectively. Table <xref ref-type="table" rid="Ch1.T1"/>
shows the mapping between the mesh entity types and their descriptor.</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T1"><caption><p>Topological dimensions of extruded mesh entities. <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>D</mml:mi><mml:mtext>b</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula>
denotes the topological dimension of the base mesh.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="2">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left"/>
     <oasis:thead>
       <oasis:row rowsep="1">  
         <oasis:entry colname="col1">Mesh entity</oasis:entry>  
         <oasis:entry colname="col2">Dimensions</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>  
         <oasis:entry colname="col1">Vertex</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Vertical edge</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Horizontal edge</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Vertical facet</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>D</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Horizontal facet</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>D</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Cell</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>D</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

</sec>
<sec id="Ch1.S3.SS1.SSS3">
  <title>Extruded mesh entity numbering</title>
      <p>We write <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> to denote the set of topological entities which
are the tensor product of entities of dimensions <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> in the horizontal
and <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> in the vertical (<inline-formula><mml:math display="inline"><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>≤</mml:mo><mml:msub><mml:mi>D</mml:mi><mml:mtext>b</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math display="inline"><mml:mrow><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>≤</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula>):

                  <disp-formula specific-use="align" content-type="numbered"><mml:math display="block"><mml:mtable displaystyle="true"><mml:mtr><mml:mtd><mml:mrow><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:mtd><mml:mtd><mml:mrow><mml:mo>=</mml:mo><mml:mfenced open="{" close=""><mml:mo>(</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:mi>i</mml:mi><mml:mo>,</mml:mo><mml:mi>l</mml:mi><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mspace width="0.33em" linebreak="nobreak"/><mml:mo>|</mml:mo><mml:mn> 0</mml:mn><mml:mo>≤</mml:mo><mml:mi>i</mml:mi><mml:mo>≤</mml:mo><mml:msub><mml:mi>N</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mfenced></mml:mrow></mml:mtd></mml:mtr><mml:mlabeledtr id="Ch1.E5"><mml:mtd/><mml:mtd/><mml:mtd><mml:mrow><mml:mfenced open="." close="}"><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mn> 0</mml:mn><mml:mo>≤</mml:mo><mml:mi>l</mml:mi><mml:mo>≤</mml:mo><mml:mi mathvariant="italic">λ</mml:mi><mml:mo>-</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mfenced><mml:mo>,</mml:mo></mml:mrow></mml:mtd></mml:mlabeledtr></mml:mtable></mml:math></disp-formula>

              where <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>N</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> is the number of entities of dimension <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> in the base
mesh and <inline-formula><mml:math display="inline"><mml:mi mathvariant="italic">λ</mml:mi></mml:math></inline-formula> is the number of edges in the extruded direction. The
subtraction of <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> from <inline-formula><mml:math display="inline"><mml:mi mathvariant="italic">λ</mml:mi></mml:math></inline-formula> accounts for the fencepost error caused
by the fact that there is always one fewer edge than vertex in the vertical
direction.</p>
      <p>The complete set of extruded mesh entities is then
              <disp-formula id="Ch1.E6" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msup><mml:mi>V</mml:mi><mml:mtext>extr</mml:mtext></mml:msup><mml:mo>=</mml:mo><mml:munder><mml:mo movablelimits="false">⋃</mml:mo><mml:mstyle scriptlevel="+1"><mml:mtable class="substack"><mml:mtr><mml:mtd><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>≤</mml:mo><mml:msub><mml:mi>D</mml:mi><mml:mtext>b</mml:mtext></mml:msub></mml:mtd></mml:mtr><mml:mtr><mml:mtd><mml:mn mathvariant="normal">0</mml:mn><mml:mo>≤</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>≤</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mtd></mml:mtr></mml:mtable></mml:mstyle></mml:munder><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula>
            These entities are those drawn for the case of an extruded triangle in
Fig. <xref ref-type="fig" rid="Ch1.F4"/>.</p>
      <p>Similarly we must extend the indexing of the adjacency relationships, writing
              <disp-formula id="Ch1.E7" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msubsup><mml:mtext>Adj</mml:mtext><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">3</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">4</mml:mn></mml:msub><mml:mo>)</mml:mo></mml:mrow><mml:mi mathvariant="normal">extr</mml:mi></mml:msubsup><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo>)</mml:mo><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
            where <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>v</mml:mi><mml:mo>∈</mml:mo><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula> and <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi>v</mml:mi><mml:mi>k</mml:mi></mml:msub><mml:mo>∈</mml:mo><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">3</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">4</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>.</p>
</sec>
</sec>
<sec id="Ch1.S3.SS2">
  <title>Attaching data to extruded meshes</title>
      <p>Identically to the case of non-extruded meshes, function spaces over an
extruded mesh associate degrees of freedom with the (extended) set of mesh
entities. A constant number of degrees of freedom is associated with each
entity of a given type.</p>
      <p>If we can arrange that the degrees of freedom are numbered such that the
vertical entities are “innermost”, it is possible to use direct addressing
for the vertical part of any mesh iteration, significantly reducing the
computational penalty introduced by using an indirectly addressed,
unstructured base mesh. Algorithm 1 implements this “vertical innermost”
numbering algorithm. The critical feature of this algorithm is that degrees
of freedom associated with vertically adjacent entities have adjacent global
numbers. The outcome of this vertical numbering is shown in
Fig. <xref ref-type="fig" rid="Ch1.F5"/>. The global numbering algorithm is orthogonal to
any base mesh decomposition strategy used to support execution on distributed
memory parallel systems. The numbering order within each entity column is not
unique; for example, one could interchange the <inline-formula><mml:math display="inline"><mml:mi>l</mml:mi></mml:math></inline-formula> and <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> loops in
Algorithm 1. However, our choice maximizes cache-line usage on a per-element
basis.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F3">
          <?xmltex \igopts{width=236.157874pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-g01.pdf"/>
        </fig>

      <?xmltex \floatpos{t}?><fig id="Ch1.F4"><caption><p>Numbering of the topological entities of an extruded cell
for the case of an extruded triangle.  The cell itself has
numbering <inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">2</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> (not shown); the other entities are
numbered as shown with vertices in black, edges in green, and faces
in blue.</p></caption>
          <?xmltex \igopts{width=241.848425pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f03.pdf"/>

        </fig>

      <?xmltex \floatpos{t}?><fig id="Ch1.F5"><caption><p>Vertical numbering of degrees of freedom (shown in filled circles)
associated with vertices and horizontal edges. Only one set of vertically
aligned degrees of freedom of each type is shown. The arrows outline the
order in which the degrees of freedom are numbered.</p></caption>
          <?xmltex \igopts{width=85.358268pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f04.pdf"/>

        </fig>

</sec>
<sec id="Ch1.S3.SS3">
  <title>Iterating over extruded meshes</title>
      <p>Iterating over the mesh and applying a kernel to a set of connected entities
(stencil) is the key operation used in mesh-based computations.</p>
      <p>The global numbering of the degrees of freedom allows stencils to be
calculated using a direct addressing scheme when accessing the degrees of
freedom of vertically adjacent entities. We assume that the traversal of the
mesh occurs over a set of mesh entities which is homogeneous (a set
containing only cells for example). Degrees of freedom belonging to
vertically adjacent entities, accessed by two consecutive kernel applications
on the same column, have a constant offset between them. The offset is given
by the sum of degrees of freedom attached to the two vertically adjacent
entities contained in the stencil:
            <disp-formula id="Ch1.E8" content-type="numbered"><mml:math display="block"><mml:mrow><mml:mi mathvariant="italic">δ</mml:mi><mml:mo>(</mml:mo><mml:mo>(</mml:mo><mml:mi>d</mml:mi><mml:mo>,</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mo>+</mml:mo><mml:mi mathvariant="italic">δ</mml:mi><mml:mo>(</mml:mo><mml:mo>(</mml:mo><mml:mi>d</mml:mi><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>
      <p>Let <inline-formula><mml:math display="inline"><mml:mi>S</mml:mi></mml:math></inline-formula> be the stencil of a kernel which needs to access the values of the
degrees of freedom of a field <inline-formula><mml:math display="inline"><mml:mi>f</mml:mi></mml:math></inline-formula> defined on a function space <inline-formula><mml:math display="inline"><mml:mi mathvariant="sans-serif">fs</mml:mi></mml:math></inline-formula>.
Let <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>L</mml:mi><mml:mi mathvariant="sans-serif">fs</mml:mi></mml:msub><mml:mo>(</mml:mo><mml:mi>v</mml:mi><mml:mo>)</mml:mo><mml:mo>=</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mrow><mml:mi>k</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> be the list of degrees of freedom of the stencil for an
input entity <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>v</mml:mi><mml:mo>∈</mml:mo><mml:msub><mml:mi>V</mml:mi><mml:mrow><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi>d</mml:mi><mml:mn mathvariant="normal">2</mml:mn></mml:msub></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>.</p>
      <p>The lists of degrees of freedom accessed by <inline-formula><mml:math display="inline"><mml:mi>S</mml:mi></mml:math></inline-formula> could be provided explicitly
for all the input entities <inline-formula><mml:math display="inline"><mml:mi>v</mml:mi></mml:math></inline-formula>. Using the previous result we can instead
reduce the number of explicitly provided lists by a factor of <inline-formula><mml:math display="inline"><mml:mi mathvariant="italic">λ</mml:mi></mml:math></inline-formula>. For
each column we visit, the only explicit accesses required are the ones to the
degrees of freedom at the bottom of the column. The degrees of freedom
identifiers for the rest of the stencil applications in the same column can
be obtained by adding a multiple of the constant vertical offset to each
degree of freedom in the bottom explicit list.</p>
      <p>For a given stencil function <inline-formula><mml:math display="inline"><mml:mi>S</mml:mi></mml:math></inline-formula> an offset can be computed for each degree of
freedom in the corresponding explicit list <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>L</mml:mi><mml:mi mathvariant="sans-serif">fs</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula>. As the ordering
of the degrees of freedom in the stencil is fixed (by consistent ordering of
mesh entities) the vertical offset only needs to be computed once for a
particular function space <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>f</mml:mi><mml:mi>s</mml:mi></mml:mrow></mml:math></inline-formula>.</p>
      <p>The algorithm for computing the vertical offset is presented in Algorithm 2.
Note that since the offset for two vertically aligned entity types is the
same, only the base mesh entity type is considered.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F6">
          <?xmltex \igopts{width=236.157874pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-g02.pdf"/>
        </fig>

      <p>If <inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mrow><mml:mi>k</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub><mml:mo>)</mml:mo></mml:mrow></mml:math></inline-formula> is
the explicit list of degrees of freedom for the initial layer to which the
stencil can be applied, then the list of degrees of freedom for the <inline-formula><mml:math display="inline"><mml:mi>n</mml:mi></mml:math></inline-formula>th
application of the stencil along the vertical is given by

                <disp-formula specific-use="align" content-type="numbered"><mml:math display="block"><mml:mtable displaystyle="true"><mml:mtr><mml:mtd><mml:mrow><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:msub></mml:mrow></mml:mtd><mml:mtd><mml:mrow><mml:mo>+</mml:mo><mml:mi>n</mml:mi><mml:mo>×</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">offset</mml:mi><mml:mrow><mml:mi>S</mml:mi><mml:mo>,</mml:mo><mml:mi>f</mml:mi></mml:mrow></mml:msub><mml:mo>(</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mo>,</mml:mo><mml:mi mathvariant="normal">…</mml:mi><mml:mo>,</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">dof</mml:mi><mml:mrow><mml:mi>k</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msub></mml:mrow></mml:mtd></mml:mtr><mml:mlabeledtr id="Ch1.E9"><mml:mtd/><mml:mtd/><mml:mtd><mml:mrow><mml:mo>+</mml:mo><mml:mi>n</mml:mi><mml:mo>×</mml:mo><mml:mo>(</mml:mo><mml:msub><mml:mi mathvariant="sans-serif">offset</mml:mi><mml:mrow><mml:mi>S</mml:mi><mml:mo>,</mml:mo><mml:mi>f</mml:mi></mml:mrow></mml:msub><mml:mo>(</mml:mo><mml:mi>k</mml:mi><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mo>)</mml:mo><mml:mo>.</mml:mo></mml:mrow></mml:mtd></mml:mlabeledtr></mml:mtable></mml:math></disp-formula></p>
      <p>Algorithm 3 shows the iteration algorithm working for a single field <inline-formula><mml:math display="inline"><mml:mi>f</mml:mi></mml:math></inline-formula> on a
function space <inline-formula><mml:math display="inline"><mml:mi mathvariant="sans-serif">fs</mml:mi></mml:math></inline-formula>. The stencil function <inline-formula><mml:math display="inline"><mml:mi>S</mml:mi></mml:math></inline-formula> is applied to the
entities of each column in turn. Each time the algorithm moves on to the next
vertically adjacent entity, the indices of the degrees of freedom accessed
are incremented by the vertical offset <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi mathvariant="sans-serif">offset</mml:mi><mml:mrow><mml:mi>S</mml:mi><mml:mo>,</mml:mo><mml:mi mathvariant="sans-serif">fs</mml:mi></mml:mrow></mml:msub></mml:mrow></mml:math></inline-formula>.
The algorithm is also applicable to stencil functions of multiple fields
defined on the same function space since the data associated with each field
are accessible using the same set of degree of freedom numbers. The extension
to fields from different function spaces just requires explicit lists
<inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>L</mml:mi><mml:mi mathvariant="sans-serif">fs</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> for each space.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F7">
          <?xmltex \igopts{width=236.157874pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-g03.pdf"/>
        </fig>

</sec>
</sec>
<sec id="Ch1.S4">
  <title>Performance evaluation</title>
      <p>In this section, we test the hypothesis that iteration exploiting the
extruded structure of the mesh amortizes the unstructured base mesh overhead
of accessing memory through explicit neighbour lists. We also show that the
more layers the mesh contains, the closer its performance is to the hardware
limits of the machine.</p>
      <p>We validate our hypotheses in the Firedrake finite element framework
<xref ref-type="bibr" rid="bib1.bibx28" id="paren.18"/>. Although we restrict our performance evaluation to
examples drawn from finite element discretizations, the algorithms we have
presented can be applied to any mesh-based discretization.</p>
      <p>In Sect. <xref ref-type="sec" rid="Ch1.S4.SS1"/> we describe the design of the experiments undertaken.
The hardware platforms and the methodology used are described in
Sect. <xref ref-type="sec" rid="Ch1.S4.SS2"/> followed by results and discussion in
Sects. <xref ref-type="sec" rid="Ch1.S4.SS3"/> and <xref ref-type="sec" rid="Ch1.S4.SS4"/> respectively.</p><?xmltex \hack{\newpage}?>
<sec id="Ch1.S4.SS1">
  <title>Experimental design</title>
      <p>The design space to be explored is parameterized by number of layers and the
manner in which the data are associated with the mesh and therefore accessed.
In establishing the relationship between the performance and the hardware we
examine performance on two generations of processors and varying process
counts.</p>
<sec id="Ch1.S4.SS1.SSS1">
  <title>Choosing the computation</title>
      <p>Numerical computations of integrals are the core mesh iteration operation in
the finite element method. We focus on residual (vector) assembly for two
reasons. First, in contrast to Jacobian assembly, there are no overheads due
to sparse matrix insertion; the experiment is purely a test of data access
via the mesh indirections. Second, residual evaluation is the assembly
operation with the lowest computational intensity and therefore constitutes a
worst-case scenario for data layout performance exploration.</p>
      <p>Since we are interested in data accesses, we choose the simplest non-trivial
residual assembly operation:
              <disp-formula id="Ch1.E10" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msub><mml:mi>I</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub><mml:mo>=</mml:mo><mml:munder><mml:mo movablelimits="false">∫</mml:mo><mml:mi mathvariant="normal">Ω</mml:mi></mml:munder><mml:mspace linebreak="nobreak" width="-0.125em"/><mml:mi>f</mml:mi><mml:mi>v</mml:mi><mml:mspace width="0.125em" linebreak="nobreak"/><mml:mi mathvariant="normal">d</mml:mi><mml:mi>x</mml:mi><mml:mo>,</mml:mo><mml:mspace linebreak="nobreak" width="1em"/><mml:mo>∀</mml:mo><mml:mi>v</mml:mi><mml:mo>∈</mml:mo><mml:mi>V</mml:mi></mml:mrow></mml:math></disp-formula>
            for <inline-formula><mml:math display="inline"><mml:mi>f</mml:mi></mml:math></inline-formula> in the finite element space <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula>. For this study we choose <inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">Ω</mml:mi><mml:mo>=</mml:mo><mml:mo>[</mml:mo><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:msup><mml:mo>]</mml:mo><mml:mn mathvariant="normal">3</mml:mn></mml:msup></mml:mrow></mml:math></inline-formula> to be the unit cube. The base mesh is generated in an unstructured
manner using Gmsh <xref ref-type="bibr" rid="bib1.bibx10" id="paren.19"/>, and then extruded to form a
three-dimensional domain.</p>
      <p>In addition to the output field <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>I</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:msub></mml:mrow></mml:math></inline-formula> and the input field <inline-formula><mml:math display="inline"><mml:mi>f</mml:mi></mml:math></inline-formula> this
computation accesses the coordinate field, <inline-formula><mml:math display="inline"><mml:mi mathvariant="bold-italic">x</mml:mi></mml:math></inline-formula>. Regardless of the
choice of <inline-formula><mml:math display="inline"><mml:mi>V</mml:mi></mml:math></inline-formula>, we always represent <inline-formula><mml:math display="inline"><mml:mi mathvariant="bold-italic">x</mml:mi></mml:math></inline-formula> by a <inline-formula><mml:math display="inline"><mml:mi>d</mml:mi></mml:math></inline-formula>-vector at each vertex
of the <inline-formula><mml:math display="inline"><mml:mi>d</mml:mi></mml:math></inline-formula>-dimensional mesh.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F8"><caption><p>Tensor product finite elements with different data layout and
cell-to-cell data re-use.</p></caption>
            <?xmltex \igopts{width=241.848425pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f05.pdf"/>

          </fig>

</sec>
<sec id="Ch1.S4.SS1.SSS2">
  <title>Choosing the discretizations</title>
      <p>The construction of a wide variety of finite element spaces on extruded
meshes was introduced in <xref ref-type="bibr" rid="bib1.bibx21" id="text.20"/>. This enables us to select the
horizontal and vertical data discretizations independently.</p>
      <p>For the purposes of data access, the distinguishing feature of different
finite element spaces is the extent to which degrees of freedom are shared
between adjacent cells.</p>
      <p>We choose a set of finite element spaces spanning the combinations of
horizontal and vertical reuse patterns found on extruded meshes: horizontal
and vertical reuse, only horizontal, only vertical, or no reuse at all.</p>
      <p>We employ low-order continuous and discontinuous discretizations (abbreviated
as <italic>CG</italic> and <italic>DG</italic> respectively) in both the horizontal and
vertical directions.</p>
      <p>The set of discretizations is <inline-formula><mml:math display="inline"><mml:mrow><mml:mi>A</mml:mi><mml:mo>=</mml:mo><mml:mo mathvariant="italic">{</mml:mo><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>,</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn><mml:mo>,</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo mathvariant="italic">}</mml:mo></mml:mrow></mml:math></inline-formula> where the number indicates the degree of polynomials in the
space. We examine all pairs of discretizations <inline-formula><mml:math display="inline"><mml:mrow><mml:mo>(</mml:mo><mml:mi>h</mml:mi><mml:mo>,</mml:mo><mml:mi>v</mml:mi><mml:mo>)</mml:mo><mml:mo>∈</mml:mo><mml:mi>A</mml:mi><mml:mo>×</mml:mo><mml:mi>A</mml:mi></mml:mrow></mml:math></inline-formula>.
Since the cells of the base mesh are triangles, the extruded mesh consists of
triangular prisms. Figure <xref ref-type="fig" rid="Ch1.F8"/> shows the data layout of each of
these finite elements.</p>
      <p>Both Firedrake and our numbering algorithm support a much larger range of
finite element spaces than this. However, the more complex and higher degree
spaces will result in more computationally intensive kernels but not
materially different data reuse. The lowest-order spaces are the most severe
test of our approach since they are more likely to be memory bound.</p><?xmltex \hack{\newpage}?>
</sec>
<sec id="Ch1.S4.SS1.SSS3">
  <title>Layer count and problem size</title>
      <p>We vary the number of layers between 1 and 100. This is a realistic range for
current ocean and atmosphere simulations. The number of cells in the extruded
mesh is kept approximately constant by shrinking the base mesh as the number
of layers increases. The mesh size is chosen such that the data volume far
exceeds the total last level cache capacity of each chosen architecture (L3
cache in all cases). This minimizes caching benefits and is therefore the
strongest test of our algorithms. The overall mesh size is fixed at
approximately 15 million cells, which yields a data volume of between 300 and
840 MB, depending on discretization.</p>
</sec>
<sec id="Ch1.S4.SS1.SSS4">
  <title>Base mesh numbering</title>
      <p>The order in which the entities of the unstructured mesh are numbered is
known to be critical for data access performance. To characterize this effect
and distinguish it from the impact of the number of layers, we employ two
variants of each base mesh. The first is a mesh for which the traversal is
optimized using a reverse Cuthill–McKee ordering <xref ref-type="bibr" rid="bib1.bibx16" id="paren.21"/>. The second
is a <italic>badly</italic> ordered mesh with a random numbering. This represents a
pathological case for temporal locality.</p>
</sec>
</sec>
<sec id="Ch1.S4.SS2">
  <title>Experimental setup</title>
      <p>The specification of the hardware used to conduct the experiments is shown in
Table <xref ref-type="table" rid="Ch1.T2"/>. Following <xref ref-type="bibr" rid="bib1.bibx24" id="text.22"/> we disable the
Intel turbo boost and frequency scaling. This is intended to prevent our
performance results from being subject to fluctuations due to processor
temperature.</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T2"><caption><p>Hardware used.</p></caption><oasis:table frame="topbot"><?xmltex \begin{scaleboxenv}{.95}[.95]?><oasis:tgroup cols="3">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left"/>
     <oasis:colspec colnum="3" colname="col3" align="left"/>
     <oasis:thead>
       <oasis:row rowsep="1">  
         <oasis:entry colname="col1">Name</oasis:entry>  
         <oasis:entry colname="col2">Intel Sandy Bridge</oasis:entry>  
         <oasis:entry colname="col3">Intel Haswell</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>  
         <oasis:entry colname="col1">Model</oasis:entry>  
         <oasis:entry colname="col2">Xeon E5-2620</oasis:entry>  
         <oasis:entry colname="col3">Xeon E5-2640 v3</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Frequency</oasis:entry>  
         <oasis:entry colname="col2">2.0 GHz</oasis:entry>  
         <oasis:entry colname="col3">2.6 GHz</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Sockets</oasis:entry>  
         <oasis:entry colname="col2">2</oasis:entry>  
         <oasis:entry colname="col3">2</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Cores per socket</oasis:entry>  
         <oasis:entry colname="col2">6</oasis:entry>  
         <oasis:entry colname="col3">8</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Bandwidth per socket</oasis:entry>  
         <oasis:entry colname="col2">42.6 GB s<inline-formula><mml:math display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col3">56.0 GB s<inline-formula><mml:math display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup><?xmltex \end{scaleboxenv}?></oasis:table></table-wrap>

      <p>The experiments we are considering are run on a single two-socket machine and
use MPI (Message Passing Interface) parallelism. The number of MPI processes
varies from one up to two processes per physical core (exploiting
hyperthreading). We pin the processes evenly across physical cores to ensure
load balance and prevent process migration between cores.</p>
      <p>The Firedrake platform performs integral computations by automatically
generating <italic>C</italic> code. The compiler used is GCC version 4.9.1
(<monospace>-O3 -march=native -ffast-math -fassociative-math</monospace>). We also assessed
the performance of the Intel C Compiler version 15.0.2 (<monospace>-O3 -xAVX -ip -xHost</monospace>); however, we only report results from GCC in this paper since the
performance of the Intel compiler was inferior.</p>
<sec id="Ch1.S4.SS2.SSS1">
  <title>Runtime, data volume, bandwidth, and FLOPs</title>
      <p>Runtime is measured using a nanosecond precision timer. Each experiment is
performed 10 times and we report the minimum runtime. Exclusive access to the
hardware has been ensured for all experiments.</p>
      <p>We model the data transfer from main memory to CPU assuming a perfect cache:
each piece of data is only loaded from main memory once. We define the
<italic>valuable data volume</italic> as the total size of the input, output, and
coordinate fields. This gives a lower bound on the memory traffic to and from
main memory. The valuable data volume divided by the runtime yields the
<italic>valuable bandwidth</italic>.</p>
      <p>Different discretizations lead to different data volumes due to the way data
are shared between cells. <inline-formula><mml:math display="inline"><mml:mi mathvariant="normal">DG</mml:mi></mml:math></inline-formula>-based discretizations require the
movement of larger data volumes, while <inline-formula><mml:math display="inline"><mml:mi mathvariant="normal">CG</mml:mi></mml:math></inline-formula> discretizations lead to
smaller volumes due to data reuse.</p>
      <p>To evaluate the impact of different data volumes we compare the valuable
bandwidth with the maximum bandwidth achieved for the STREAM triad
benchmark <xref ref-type="bibr" rid="bib1.bibx20" id="paren.23"/>, shown in Table <xref ref-type="table" rid="Ch1.T3"/>. The valuable
bandwidth achieved as a percentage of STREAM bandwidth shows how prone the
code is to becoming bandwidth bound as its floating point performance is
improved.</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T3"><caption><p>Maximum STREAM triad (<inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>a</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>b</mml:mi><mml:mi>i</mml:mi></mml:msub><mml:mo>+</mml:mo><mml:mi mathvariant="italic">α</mml:mi><mml:msub><mml:mi>c</mml:mi><mml:mi>i</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula>) performance achieved
by varying the number of MPI processes from one to twice the number of
physical cores.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="2">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="left"/>
     <oasis:thead>
       <oasis:row rowsep="1">  
         <oasis:entry colname="col1">Platform</oasis:entry>  
         <oasis:entry colname="col2">STREAM bandwidth</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>  
         <oasis:entry colname="col1">Intel Sandy Bridge</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mn>55.3</mml:mn></mml:math></inline-formula> GB s<inline-formula><mml:math display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1">Intel Haswell</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mn>80.2</mml:mn></mml:math></inline-formula> GB s<inline-formula><mml:math display="inline"><mml:msup><mml:mi/><mml:mrow><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:msup></mml:math></inline-formula></oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <p>The floating point operations – adds, multiplies, and, on Haswell, fused
multiply–add (FMA) operations – are counted automatically using the Intel
Architecture Code Analyzer <xref ref-type="bibr" rid="bib1.bibx12" id="paren.24"/> whose results are verified with
PAPI <xref ref-type="bibr" rid="bib1.bibx23" id="paren.25"/> which accesses the hardware counters.</p>
</sec>
<sec id="Ch1.S4.SS2.SSS2">
  <title>Theoretical performance bounds</title>
      <p>The performance of the extruded iteration depends on the efficiency of the
generated finite element kernel (payload) code which for some cases may not
be vectorized (as outlined in <xref ref-type="bibr" rid="bib1.bibx18" id="altparen.26"/>) or may not have a
perfectly balanced number of floating point additions and multiplications. A
discussion of kernel code optimality is outside the scope of this paper.</p>
      <p>To a first approximation the performance of a numerical algorithm will be
limited by either the memory bandwidth or the floating point throughput. The
STREAM benchmark provides an effective upper bound on the achievable memory
bandwidth. The floating point bounds employed are based on the theoretical
maximum given the clock frequency of the processor.</p>
      <p>The Intel architectures considered are capable of executing both a floating
point addition and a floating point multiplication on each clock cycle. The
Haswell processor can execute a fused multiply–add instruction (FMA) instead
of either an addition or multiplication operation.</p>
      <p>The achievable FLOP rate may therefore be as much as twice the clock rate
depending on the mix of instructions executed. The achievable speed-up over
the clock rate, <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula>, for the Sandy Bridge platform is therefore
bounded by the balance factor
              <disp-formula id="Ch1.E11" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>+</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>min⁡</mml:mo><mml:mo>(</mml:mo><mml:mi mathvariant="normal">add</mml:mi><mml:mspace width="0.25em" linebreak="nobreak"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>,</mml:mo><mml:mi mathvariant="normal">multiplication</mml:mi><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>)</mml:mo></mml:mrow><mml:mrow><mml:mo>max⁡</mml:mo><mml:mo>(</mml:mo><mml:mi mathvariant="normal">add</mml:mi><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>,</mml:mo><mml:mi mathvariant="normal">multiplication</mml:mi><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>)</mml:mo></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
            while for Haswell it is bounded by
              <disp-formula id="Ch1.E12" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>+</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mo>min⁡</mml:mo><mml:mo>(</mml:mo><mml:mi mathvariant="normal">add</mml:mi><mml:mspace width="0.25em" linebreak="nobreak"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>,</mml:mo><mml:mi mathvariant="normal">multiplication</mml:mi><mml:mspace width="0.25em" linebreak="nobreak"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>)</mml:mo><mml:mo>+</mml:mo><mml:mi>k</mml:mi></mml:mrow><mml:mrow><mml:mo>max⁡</mml:mo><mml:mo>(</mml:mo><mml:mi mathvariant="normal">add</mml:mi><mml:mspace width="0.25em" linebreak="nobreak"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>,</mml:mo><mml:mi mathvariant="normal">multiplication</mml:mi><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mi mathvariant="normal">FLOPs</mml:mi><mml:mo>)</mml:mo><mml:mo>+</mml:mo><mml:mi>k</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>,</mml:mo></mml:mrow></mml:math></disp-formula>
            where <inline-formula><mml:math display="inline"><mml:mi>k</mml:mi></mml:math></inline-formula> is half the number of FMAs.</p>
</sec>
<sec id="Ch1.S4.SS2.SSS3">
  <title>Vectorization</title>
      <p>The processors employed support 256 bit wide vector floating point
instructions. The double precision FLOP rate of a fully vectorized code can
be as much as 4 times that of an unvectorized code. GCC automatically
vectorized only a part of the total number of floating point instructions.
The ratio between the number of vector (packed) floating point instructions
and the total number of floating point instructions (scalar and packed)
characterizes the impact of partial vectorization on the floating point bound
through the vectorization factor
              <disp-formula id="Ch1.E13" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>v</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>+</mml:mo><mml:mo>(</mml:mo><mml:mn mathvariant="normal">4</mml:mn><mml:mo>-</mml:mo><mml:mn mathvariant="normal">1</mml:mn><mml:mo>)</mml:mo><mml:mo>×</mml:mo><mml:mstyle displaystyle="true"><mml:mfrac style="display"><mml:mrow><mml:mi mathvariant="normal">vector</mml:mi><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mi mathvariant="normal">FLOPs</mml:mi></mml:mrow><mml:mrow><mml:mi mathvariant="normal">total</mml:mi><mml:mspace linebreak="nobreak" width="0.25em"/><mml:mi mathvariant="normal">FLOPs</mml:mi></mml:mrow></mml:mfrac></mml:mstyle><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F9" specific-use="star"><caption><p>Performance of the <inline-formula><mml:math display="inline"><mml:mi>I</mml:mi></mml:math></inline-formula> integral computation with a varying number of
layers and number of processes on a badly ordered base mesh. The horizontal
line is the base FLOP throughput for <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>f</mml:mi><mml:mtext>v</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> and the
number of physical cores used.</p></caption>
            <?xmltex \igopts{width=312.980315pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f06.pdf"/>

          </fig>

      <p>To control the impact of the kernel computation (payload) on the evaluation,
we compare the measured floating point throughput with a theoretical peak
which incorporates the payload instruction balance and the degree of
vectorization. Let <inline-formula><mml:math display="inline"><mml:mi>c</mml:mi></mml:math></inline-formula> be the number of active physical CPU cores during the
computation of interest. The theoretical base floating point performance
<inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>B</mml:mi><mml:mi>c</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> is the same for all discretizations and assumes one floating point
instruction per cycle for each active physical CPU core. The peak theoretical
floating point throughput <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>P</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> is different for each discretization <inline-formula><mml:math display="inline"><mml:mi>d</mml:mi></mml:math></inline-formula> as
it depends on the properties of the payload and is given by
              <disp-formula id="Ch1.E14" content-type="numbered"><mml:math display="block"><mml:mrow><mml:msub><mml:mi>P</mml:mi><mml:mi>d</mml:mi></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>B</mml:mi><mml:mi>c</mml:mi></mml:msub><mml:mo>×</mml:mo><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>×</mml:mo><mml:msub><mml:mi>f</mml:mi><mml:mtext>v</mml:mtext></mml:msub><mml:mo>.</mml:mo></mml:mrow></mml:math></disp-formula></p><?xmltex \hack{\newpage}?>
</sec>
</sec>
<sec id="Ch1.S4.SS3">
  <title>Experimental results</title>
<sec id="Ch1.S4.SS3.SSS1">
  <title>Percentage of theoretical performance</title>
      <p>For the Sandy Bridge and Haswell architectures, the best performance is
achieved in the 100-layer case run with 24 and 32 processes respectively
(hyperthreading enabled). The results in Tables <xref ref-type="table" rid="Ch1.T4"/> and
<xref ref-type="table" rid="Ch1.T5"/> show percentages of the STREAM bandwidth and the theoretical
floating point throughput which incorporates the instruction balance and
vectorization factors.</p>

      <?xmltex \floatpos{t}?><fig id="Ch1.F10" specific-use="star"><caption><p>Performance of the <inline-formula><mml:math display="inline"><mml:mi>I</mml:mi></mml:math></inline-formula> integral computation with a varying number of
layers and number of processes on a well-ordered base mesh. The star-shaped
markers show the performance of the one-layer badly ordered mesh for
comparison. The horizontal line is the base FLOP throughput for <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>f</mml:mi><mml:mtext>v</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> and the number of physical cores used.</p></caption>
            <?xmltex \igopts{width=312.980315pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f07.pdf"/>

          </fig>

      <p>On Sandy Bridge, the proportion of peak theoretical floating point throughput
is between 71 and 85 %, while on Haswell it is between 71 and 92 %.
In contrast, the proportion of peak bandwidth achieved varies between 7 and
51 % on Sandy Bridge and 9 and 75 % on Haswell. The higher and much
more consistent peak FLOP results lead us to the conclusion that we are in an
operation- rather than bandwidth-limited regime. The performance figures are
therefore presented with respect to this metric.</p>
</sec>
<sec id="Ch1.S4.SS3.SSS2">
  <title>Amortizing the cost of indirect accesses</title>
      <p>When the base mesh is well ordered (Fig. <xref ref-type="fig" rid="Ch1.F10"/>), the number
of layers required to reach a performance plateau is between 10 and 20 for
all discretizations. When the base mesh is badly ordered
(Fig. <xref ref-type="fig" rid="Ch1.F9"/>) the plateau is frequently not reached even
with 100 layers. A striking feature of Figs. <xref ref-type="fig" rid="Ch1.F9"/> and
<xref ref-type="fig" rid="Ch1.F10"/> is that cases in which the local kernel calculations
are identical produce very similar achieved FLOP rates, despite having
different data sharing patterns. This supports the hypothesis that the
results are operation bound.</p>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T4"><caption><p>Percentage of STREAM bandwidth and theoretical throughput achieved
by the computation of integral <inline-formula><mml:math display="inline"><mml:mi>I</mml:mi></mml:math></inline-formula> over 100 layers on Sandy Bridge with 24
MPI processes.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="5">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="right"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">  
         <oasis:entry colname="col1">Discretization</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col3"><inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>v</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col4"><inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>P</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (%)</oasis:entry>  
         <oasis:entry colname="col5">Bandwidth (%)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.7</oasis:entry>  
         <oasis:entry colname="col3">1.58</oasis:entry>  
         <oasis:entry colname="col4">73.45</oasis:entry>  
         <oasis:entry colname="col5">7.092</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.81</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">78.96</oasis:entry>  
         <oasis:entry colname="col5">14.70</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.7</oasis:entry>  
         <oasis:entry colname="col3">1.58</oasis:entry>  
         <oasis:entry colname="col4">73.03</oasis:entry>  
         <oasis:entry colname="col5">10.50</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.65</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">76.01</oasis:entry>  
         <oasis:entry colname="col5">27.86</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.5</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">85.14</oasis:entry>  
         <oasis:entry colname="col5">34.86</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.65</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">75.45</oasis:entry>  
         <oasis:entry colname="col5">45.68</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.7</oasis:entry>  
         <oasis:entry colname="col3">1.58</oasis:entry>  
         <oasis:entry colname="col4">73.20</oasis:entry>  
         <oasis:entry colname="col5">24.60</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.81</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">78.93</oasis:entry>  
         <oasis:entry colname="col5">50.98</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.7</oasis:entry>  
         <oasis:entry colname="col3">1.58</oasis:entry>  
         <oasis:entry colname="col4">71.78</oasis:entry>  
         <oasis:entry colname="col5">44.37</oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

<?xmltex \floatpos{t}?><table-wrap id="Ch1.T5"><caption><p>Percentage of STREAM bandwidth and theoretical throughput achieved
by the computation of integral <inline-formula><mml:math display="inline"><mml:mi>I</mml:mi></mml:math></inline-formula> over 100 layers on Haswell with 32 MPI
processes.</p></caption><oasis:table frame="topbot"><oasis:tgroup cols="5">
     <oasis:colspec colnum="1" colname="col1" align="left"/>
     <oasis:colspec colnum="2" colname="col2" align="right"/>
     <oasis:colspec colnum="3" colname="col3" align="right"/>
     <oasis:colspec colnum="4" colname="col4" align="right"/>
     <oasis:colspec colnum="5" colname="col5" align="right"/>
     <oasis:thead>
       <oasis:row rowsep="1">  
         <oasis:entry colname="col1">Discretization</oasis:entry>  
         <oasis:entry colname="col2"><inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col3"><inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>v</mml:mtext></mml:msub></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col4"><inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>P</mml:mi><mml:mi>d</mml:mi></mml:msub></mml:mrow></mml:math></inline-formula> (%)</oasis:entry>  
         <oasis:entry colname="col5">Bandwidth (%)</oasis:entry>
       </oasis:row>
     </oasis:thead>
     <oasis:tbody>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.76</oasis:entry>  
         <oasis:entry colname="col3">1.61</oasis:entry>  
         <oasis:entry colname="col4">72.43</oasis:entry>  
         <oasis:entry colname="col5">9.015</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.97</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">88.57</oasis:entry>  
         <oasis:entry colname="col5">21.92</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.76</oasis:entry>  
         <oasis:entry colname="col3">1.61</oasis:entry>  
         <oasis:entry colname="col4">72.20</oasis:entry>  
         <oasis:entry colname="col5">13.39</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.87</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">73.94</oasis:entry>  
         <oasis:entry colname="col5">38.74</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.66</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">91.93</oasis:entry>  
         <oasis:entry colname="col5">53.10</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.87</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">72.89</oasis:entry>  
         <oasis:entry colname="col5">63.11</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">CG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.76</oasis:entry>  
         <oasis:entry colname="col3">1.61</oasis:entry>  
         <oasis:entry colname="col4">71.99</oasis:entry>  
         <oasis:entry colname="col5">31.19</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">0</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.97</oasis:entry>  
         <oasis:entry colname="col3">1.0</oasis:entry>  
         <oasis:entry colname="col4">87.55</oasis:entry>  
         <oasis:entry colname="col5">75.17</oasis:entry>
       </oasis:row>
       <oasis:row>  
         <oasis:entry colname="col1"><inline-formula><mml:math display="inline"><mml:mrow><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn><mml:mo>×</mml:mo><mml:mi mathvariant="normal">DG</mml:mi><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula></oasis:entry>  
         <oasis:entry colname="col2">1.76</oasis:entry>  
         <oasis:entry colname="col3">1.61</oasis:entry>  
         <oasis:entry colname="col4">71.50</oasis:entry>  
         <oasis:entry colname="col5">56.98</oasis:entry>
       </oasis:row>
     </oasis:tbody>
   </oasis:tgroup></oasis:table></table-wrap>

      <?xmltex \floatpos{t}?><fig id="Ch1.F11"><caption><p>Performance of the <inline-formula><mml:math display="inline"><mml:mi>I</mml:mi></mml:math></inline-formula> integral computations on different data
discretizations with a varying number of layers on the Haswell architecture
for a well-ordered base mesh. The star-shaped markers show the performance of
the one-layer badly ordered mesh for comparison. The horizontal line is the
base FLOP throughput for <inline-formula><mml:math display="inline"><mml:mrow><mml:msub><mml:mi>f</mml:mi><mml:mtext>b</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:msub><mml:mi>f</mml:mi><mml:mtext>v</mml:mtext></mml:msub><mml:mo>=</mml:mo><mml:mn mathvariant="normal">1</mml:mn></mml:mrow></mml:math></inline-formula> and the number of
physical cores used.</p></caption>
            <?xmltex \igopts{width=199.169291pt}?><graphic xlink:href="https://gmd.copernicus.org/articles/9/3803/2016/gmd-9-3803-2016-f08.pdf"/>

          </fig>

</sec>
</sec>
<sec id="Ch1.S4.SS4">
  <title>Discussion</title>
      <p>The performance of the extruded mesh iteration is constrained by the
properties of the mesh and the kernel computation. The total number of
computations is based on the number of degrees of freedom per cell. The range
of discretizations used in this paper (Fig. <xref ref-type="fig" rid="Ch1.F8"/>) leads to four
cases: one, two, three, or six degrees of freedom per cell. In compute bound
situations, discretizations with the same number of computations have the
same performance (Fig. <xref ref-type="fig" rid="Ch1.F11"/>).</p>
<sec id="Ch1.S4.SS4.SSSx1" specific-use="unnumbered">
  <title>Temporal locality</title>
      <p>The numbering algorithm ensures good temporal locality between vertically
aligned cells. Any degrees of freedom which are shared vertically are reused
when the iteration algorithm visits the next element. The reuse distance
along the vertical is therefore minimal.</p>
      <p>For <inline-formula><mml:math display="inline"><mml:mi mathvariant="normal">CG</mml:mi></mml:math></inline-formula> discretizations, where degrees of freedom are shared
horizontally with other vertical columns, the overall performance depends on
the ordering of cells in the base mesh. Assuming a perfect ordering of the
base mesh, the numbering algorithm ensures a minimal reuse distance while
guaranteeing a minimum number of indirect accesses and satisfying all the
previously introduced spatial and temporal locality requirements.</p>
      <p>Figures <xref ref-type="fig" rid="Ch1.F10"/> and <xref ref-type="fig" rid="Ch1.F9"/> demonstrate the
combined impact of horizontal mesh ordering and extrusion. In the extreme
case the flop rate increases up to 14 times between the badly ordered
single-layer case and the 100-layer well-ordered case. This is consistent
with the widely held belief that unstructured mesh models are an order of
magnitude slower than structured mesh models.</p>
      <p>The difference between well-ordered and badly ordered mesh performance
outlines the benefits responsible for the boost in performance. Horizontal
data reuse dominates performance for a low number of layers, while spatial
locality and vertical temporal locality (ensured by the numbering and
iteration algorithms) are responsible for most of the performance gains as
the number of layers increases.</p>
      <p>We note, once again, that these results are for the lowest-order spaces which
represent a worst case. Higher-order methods both access more contiguous data
in each column and require many more FLOPs. As a result, we would expect to
reach performance plateaus at lower numbers of layers.</p>
</sec>
</sec>
</sec>
<sec id="Ch1.S5" sec-type="conclusions">
  <title>Conclusions</title>
      <p>In this paper we have presented efficient, locality-aware algorithms for
numbering and iterating over extruded meshes. For a sufficient number of
layers, the cost of using an unstructured base mesh is amortized. Achieved
performance ranges from 70 to 90 % of our best estimate for the
hardware's performance capabilities and current level of kernel optimization.
Benefits of spatial and temporal locality vary with the number of layers: as
the number of layers is increased, the benefits of spatial locality increase,
while those of temporal locality decrease.</p>
      <p>This paper employed two simplifying constraints: that there are a constant
number of layers in each column, and that the number of degrees of freedom
associated with each entity type is a constant. These assumptions are not
fundamental to the numbering algorithm presented here, or to its performance.
We intend to relax those constraints as they become important for the use
cases for which Firedrake is employed.</p>
      <p>The current code generation scheme can be extended to include inter-kernel
vectorization (an optimization mentioned in <xref ref-type="bibr" rid="bib1.bibx22" id="altparen.27"/>) for the
operations which cannot be vectorized at intra-kernel level. The efficiency
of such a generic scheme applicable to different data discretizations is
currently being explored.</p>
      <p>In future work we intend to generalize some of the optimizations which
extrusion enables for both residual and Jacobian assembly: inter-kernel
optimizations, grouping of addition of contributions to the global system,
and exploiting the vertical alignment at the level of the sparse
representation of the global system matrix. In addition to the CPU results
presented in this paper, we also plan to explore the performance portability
issues of extruded meshes on graphical processing units and Intel Xeon Phi
accelerators.</p>
</sec>
<sec id="Ch1.S6">
  <title>Code availability</title>
      <p>The packages used to perform the experiments have been archived using Zenodo:
Firedrake <xref ref-type="bibr" rid="bib1.bibx7" id="paren.28"/>, PETSc
<xref ref-type="bibr" rid="bib1.bibx25" id="paren.29"/>, petsc4py <xref ref-type="bibr" rid="bib1.bibx26" id="paren.30"/>,
FIAT <xref ref-type="bibr" rid="bib1.bibx6" id="paren.31"/>, UFL
<xref ref-type="bibr" rid="bib1.bibx32" id="paren.32"/>, FFC <xref ref-type="bibr" rid="bib1.bibx5" id="paren.33"/>,
PyOP2 <xref ref-type="bibr" rid="bib1.bibx27" id="paren.34"/>, and COFFEE
<xref ref-type="bibr" rid="bib1.bibx4" id="paren.35"/>. The source code repositories as well as
the archived versions are publicly available.</p>
</sec>
<sec id="Ch1.S7">
  <title>Data availability</title>
      <p>The scripts used to perform the experiments as well as the results are
archived using Zenodo: Sandy Bridge <xref ref-type="bibr" rid="bib1.bibx3" id="paren.36"/> and
Haswell <xref ref-type="bibr" rid="bib1.bibx2" id="paren.37"/>. The meshes used in the experiments are
available also <xref ref-type="bibr" rid="bib1.bibx1" id="paren.38"/>. The archives are publicly
available.</p>
</sec>

      
      </body>
    <back><notes notes-type="authorcontribution">

      <p>Gheorghe-Teodor Bercea designed the generalized extrusion
algorithm, and performed the extension of the Firedrake and PyOP2 packages to
support extruded meshes, the performance evaluation, and the preparation of
the graphs and tables. Andrew T. T. McRae extended components of the
Firedrake toolchain to support the finite element types used in the
experiments, and made minor contributions to the extruded mesh iteration
functionality. David A. Ham was the proponent of a generalized extrusion
algorithm. Lawrence Mitchell, Florian Rathgeber, and Fabio Luporini developed
related features and framework improvements in Firedrake, PyOP2, and COFFEE.
Luigi Nardi is responsible for the use of the floating point balance metric.
David A. Ham and Paul H. J. Kelly are the principal investigators for this
paper. Gheorghe-Teodor Bercea prepared the manuscript with contributions from
all the authors. All authors contributed with feedback during the paper's
write-up process.</p>
  </notes><ack><title>Acknowledgements</title><p>This work was supported by an Engineering and Physical Sciences Research
Council prize studentship (ref. 1252364), the Grantham Institute and
Climate-KIC, the Natural Environment Research Council (grant numbers
NE/K006789/1, NE/K008951/1, and NE/M013480/1) and the Department of
Computing, Imperial College London. The authors would like to thank
J. (Ram) Ramanujam at Louisiana State University for the insightful
discussions and feedback during the writing of this paper. We are thankful to
Francis Russell at Imperial College London for the feedback on this
paper.<?xmltex \hack{\newline}?><?xmltex \hack{\newline}?> Edited by: S.
Unterstrasser<?xmltex \hack{\newline}?> Reviewed by: two anonymous referees</p></ack><ref-list>
    <title>References</title>

      <ref id="bib1.bibx1"><label>Bercea(2016a)</label><mixed-citation>Bercea, G.-T.: Unstructured meshes for extrusion article,
<ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.61819" ext-link-type="DOI">10.5281/zenodo.61819</ext-link>, 2016a.</mixed-citation></ref>
      <ref id="bib1.bibx2"><label>Bercea(2016b)</label><mixed-citation>Bercea, G.-T.: Data and plot scripts for Haswell experiments,
<ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.61919" ext-link-type="DOI">10.5281/zenodo.61919</ext-link>, 2016b.</mixed-citation></ref>
      <ref id="bib1.bibx3"><label>Bercea(2016c)</label><mixed-citation>Bercea, G.-T.: Data and plot scripts for Sandy Bridge experiments,
<ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.61920" ext-link-type="DOI">10.5281/zenodo.61920</ext-link>, 2016c.</mixed-citation></ref>
      <ref id="bib1.bibx4"><label>COFFEE(2016)</label><mixed-citation>COFFEE: A Compiler for Fast Expression
Evaluation, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47715" ext-link-type="DOI">10.5281/zenodo.47715</ext-link>, 2016.</mixed-citation></ref>
      <ref id="bib1.bibx5"><label>FFC(2016)</label><mixed-citation>FFC: FEniCS Form
Compiler, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47761" ext-link-type="DOI">10.5281/zenodo.47761</ext-link>, 2016.</mixed-citation></ref>
      <ref id="bib1.bibx6"><label>FIAT(2016)</label><mixed-citation>FIAT:
The Finite Element Automated Tabulator, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47716" ext-link-type="DOI">10.5281/zenodo.47716</ext-link>, 2016.</mixed-citation></ref>
      <ref id="bib1.bibx7"><label>Firedrake(2016)</label><mixed-citation>Firedrake: An automated finite element
system, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47717" ext-link-type="DOI">10.5281/zenodo.47717</ext-link>, 2016.</mixed-citation></ref>
      <ref id="bib1.bibx8"><label>Ford et al.(2013)Ford, Glover, Ham, Maynard, Pickles, and
Riley</label><mixed-citation>
Ford, R., Glover, M., Ham, D., Maynard, C., Pickles, S., and Riley, G.:
GungHo Phase 1: Computational Science Recommendations, Tech. rep., Met
Office, Exeter, 2013.</mixed-citation></ref>
      <ref id="bib1.bibx9"><label>Gersbacher(2012)</label><mixed-citation>Gersbacher, C.: The Dune-PrismGrid Module, in: Advances in DUNE: Proceedings
of
the DUNE User Meeting, edited by: Dedner, A., Flemisch, B., and Klöfkorn, R., 6–8 October 2010, Stuttgart, Germany,
33–44,
Springer Berlin Heidelberg, Berlin, Heidelberg,
<ext-link xlink:href="http://dx.doi.org/10.1007/978-3-642-28589-9_3" ext-link-type="DOI">10.1007/978-3-642-28589-9_3</ext-link>, 2012.</mixed-citation></ref>
      <ref id="bib1.bibx10"><label>Geuzaine and Remacle(2009)</label><mixed-citation>
Geuzaine, C. and Remacle, J.-F.: Gmsh: A 3-D finite element mesh generator
with built-in pre- and post-processing facilities, International
Journal for Numerical Methods in Engineering, 79, 1309–1331, 2009.</mixed-citation></ref>
      <ref id="bib1.bibx11"><label>Günther et al.(2006)Günther, Mehl, Pögl, and
Zenger</label><mixed-citation>Günther, F., Mehl, M., Pögl, M., and Zenger, C.: A Cache-Aware
Algorithm for PDEs on Hierarchical Data Structures Based on Space-Filling
Curves, SIAM J. Sci. Comput., 28, 1634–1650, <ext-link xlink:href="http://dx.doi.org/10.1137/040604078" ext-link-type="DOI">10.1137/040604078</ext-link>, 2006.</mixed-citation></ref>
      <ref id="bib1.bibx12"><label>Intel(2012)</label><mixed-citation>Intel: Intel Architecture Code Analyzer, available at:
<uri>https://software.intel.com/en-us/articles/intel-architecture-code-analyzer</uri>
(last access: October 2016), 2012.</mixed-citation></ref>
      <ref id="bib1.bibx13"><label>Isaac(2015)</label><mixed-citation>
Isaac, T.: Scalable, adaptive methods for forward and inverse problems in
continental-scale ice sheet modeling, PhD thesis, University of Texas,
Austin, 2015.</mixed-citation></ref>
      <ref id="bib1.bibx14"><label>Isaac et al.(2015)Isaac, Stadler, and Ghattas</label><mixed-citation>Isaac, T., Stadler, G., and Ghattas, O.: Solution of Nonlinear Stokes
Equations
Discretized By High-Order Finite Elements on Nonconforming and Anisotropic
Meshes, with Application to Ice Sheet Dynamics, SIAM J. Sci.
Comput., 37, B804–B833, <ext-link xlink:href="http://dx.doi.org/10.1137/140974407" ext-link-type="DOI">10.1137/140974407</ext-link>, 2015.</mixed-citation></ref>
      <ref id="bib1.bibx15"><label>Knepley and Karpeev(2009)</label><mixed-citation>Knepley, M. G. and Karpeev, D. A.: Mesh Algorithms for PDE with Sieve I:
Mesh
Distribution, Sci. Program., 17, 215–230,
<ext-link xlink:href="http://dx.doi.org/10.3233/SPR-2009-0249" ext-link-type="DOI">10.3233/SPR-2009-0249</ext-link>, 2009.</mixed-citation></ref>
      <ref id="bib1.bibx16"><label>Lange et al.(2016)Lange, Mitchell, Knepley, and Gorman</label><mixed-citation>Lange, M., Mitchell, L., Knepley, M., and Gorman, G.: Efficient mesh
management
in Firedrake using PETSc-DMPlex,  SIAM J. Sci.
Comput., available at: <uri>http://arxiv.org/abs/1506.07749</uri>, in press, 2016.</mixed-citation></ref>
      <ref id="bib1.bibx17"><label>Logg(2009)</label><mixed-citation>Logg, A.: Efficient Representation of Computational Meshes, Int.
J. Comput. Sci. Eng., 4, 283–295,
<ext-link xlink:href="http://dx.doi.org/10.1504/IJCSE.2009.029164" ext-link-type="DOI">10.1504/IJCSE.2009.029164</ext-link>, 2009.</mixed-citation></ref>
      <ref id="bib1.bibx18"><label>Luporini et al.(2015)</label><mixed-citation>Luporini, F., Varbanescu, A. L., Rathgeber, F., Bercea, G.-T., Ramanujam, J.,
Ham, D. A., and Kelly, P. H. J.: Cross-Loop Optimization of Arithmetic
Intensity for Finite Element Local Assembly, ACM Trans. Archit. Code Optim.,
11, 1–25, <ext-link xlink:href="http://dx.doi.org/10.1145/2687415" ext-link-type="DOI">10.1145/2687415</ext-link>, 2015.</mixed-citation></ref>
      <ref id="bib1.bibx19"><label>Macdonald et al.(2011)Macdonald, Middlecoff, Henderson, and
Lee</label><mixed-citation>Macdonald, A. E., Middlecoff, J., Henderson, T., and Lee, J.-L.: A General
Method for Modeling on Irregular Grids, Int. J. High Perform. C.,
25, 392–403, <ext-link xlink:href="http://dx.doi.org/10.1177/1094342010385019" ext-link-type="DOI">10.1177/1094342010385019</ext-link>, 2011.</mixed-citation></ref>
      <ref id="bib1.bibx20"><label>McCalpin(1995)</label><mixed-citation>
McCalpin, J. D.: Memory Bandwidth and Machine Balance in Current High
Performance Computers, IEEE Computer Society Technical Committee on Computer
Architecture (TCCA) Newsletter,  19–25, 1995.</mixed-citation></ref>
      <ref id="bib1.bibx21"><label>McRae et al.(2016)McRae, Bercea, Mitchell, Ham, and
Cotter</label><mixed-citation>McRae, A. T. T., Bercea, G.-T., Mitchell, L., Ham, D. A., and Cotter, C. J.:
Automated generation and symbolic manipulation of tensor product finite
elements,  SIAM J. Sci. Comput., available at: <uri>http://arxiv.org/abs/1411.2940</uri>, in press, 2016.</mixed-citation></ref>
      <ref id="bib1.bibx22"><label>Meister and Bader(2015)</label><mixed-citation>Meister, O. and Bader, M.: 2D adaptivity for 3D problems: Parallel SPE10
reservoir simulation on dynamically adaptive prism grids, J. Comput. Sci., 9,
101–106,
<ext-link xlink:href="http://dx.doi.org/10.1016/j.jocs.2015.04.016" ext-link-type="DOI">10.1016/j.jocs.2015.04.016</ext-link>, 2015.</mixed-citation></ref>
      <ref id="bib1.bibx23"><label>Mucci et al.(1999)Mucci, Browne, Deane, and Ho</label><mixed-citation>
Mucci, P. J., Browne, S., Deane, C., and Ho, G.: PAPI: A Portable Interface
to Hardware Performance Counters, Proceedings of the Department of
Defense HPCMP Users Group Conference, 7–10, 1999.</mixed-citation></ref>
      <ref id="bib1.bibx24"><label>Ofenbeck et al.(2014)</label><mixed-citation>Ofenbeck, G., Steinmann, R., Caparros, V., Spampinato, D. G., and Puschel,
M.:
Applying the roofline model, in: 2014 IEEE International Symposium on
Performance Analysis of Systems and Software (ISPASS),  76–85,
<ext-link xlink:href="http://dx.doi.org/10.1109/ISPASS.2014.6844463" ext-link-type="DOI">10.1109/ISPASS.2014.6844463</ext-link>, 2014.</mixed-citation></ref>
      <ref id="bib1.bibx25"><label>PETSc(2016)</label><mixed-citation>PETSc: Portable, Extensible
Toolkit for Scientific Computation, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47718" ext-link-type="DOI">10.5281/zenodo.47718</ext-link>, 2016.
</mixed-citation></ref><?xmltex \hack{\newpage}?>
      <ref id="bib1.bibx26"><label>petsc4py(2016)</label><mixed-citation>petsc4py: The Python interface to PETSc, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47714" ext-link-type="DOI">10.5281/zenodo.47714</ext-link>,
2016.</mixed-citation></ref>
      <ref id="bib1.bibx27"><label>PyOP2(2016)</label><mixed-citation>PyOP2: Framework for performance-portable
parallel computations on unstructured meshes, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47712" ext-link-type="DOI">10.5281/zenodo.47712</ext-link>,
2016.</mixed-citation></ref>
      <ref id="bib1.bibx28"><label>Rathgeber et al.(2016)Rathgeber, Ham, Mitchell, Lange, Luporini,
McRae, Bercea, Markall, and Kelly</label><mixed-citation>Rathgeber, F., Ham, D. A., Mitchell, L., Lange, M., Luporini, F., McRae, A.
T. T., Bercea, G.-T., Markall, G. R., and Kelly, P. H. J.: Firedrake:
automating the finite element method by composing abstractions,  ACM Trans. Math. Software, available at: <uri>http://arxiv.org/abs/1501.01809</uri>, in press,
2016.</mixed-citation></ref>
      <ref id="bib1.bibx29"><label>Sarje et al.(2015)Koziel, Leifsson, Lees, V.Krzhizhanovskaya,
Dongarra, Sloot, Sarje, Song, Jacobsen, Huck, Hollingsworth, Malony,
Williams, and Oliker</label><mixed-citation>Sarje, A., Song, S., Jacobsen, D., Huck, K., Hollingsworth, J., Malony, A.,
Williams, S., and Oliker, L.: Parallel Performance Optimizations on
Unstructured Mesh-based Simulations, Procedia Computer Science, 51,
2016–2025, <ext-link xlink:href="http://dx.doi.org/10.1016/j.procs.2015.05.466" ext-link-type="DOI">10.1016/j.procs.2015.05.466</ext-link>, 2015.</mixed-citation></ref>
      <ref id="bib1.bibx30"><label>Skamarock et al.(2012)Skamarock, Klemp, Duda, Fowler, Park, and
Ringler</label><mixed-citation>Skamarock, W. C., Klemp, J. B., Duda, M. G., Fowler, L. D., Park, S.-H., and
Ringler, T. D.: A multiscale nonhydrostatic atmospheric model using
centroidal Voronoi tesselations and C-grid staggering, Mon. Weather
Rev., 140, 3090–3105, <ext-link xlink:href="http://dx.doi.org/10.1175/MWR-D-11-00215.1" ext-link-type="DOI">10.1175/MWR-D-11-00215.1</ext-link>, 2012.</mixed-citation></ref>
      <ref id="bib1.bibx31"><label>Slingo et al.(2009)Slingo, Bates, Nikiforakis, Piggott, Roberts,
Shaffrey, Stevens, Vidale, and Weller</label><mixed-citation>Slingo, J., Bates, K., Nikiforakis, N., Piggott, M., Roberts, M., Shaffrey,
L.,
Stevens, I., Vidale, P. L., and Weller, H.: Developing the next-generation
climate system models: challenges and achievements, Philos.
T. R. Soc. Lond. A, 367, 815–831, <ext-link xlink:href="http://dx.doi.org/10.1098/rsta.2008.0207" ext-link-type="DOI">10.1098/rsta.2008.0207</ext-link>, 2009.</mixed-citation></ref>
      <ref id="bib1.bibx32"><label>UFL(2016)</label><mixed-citation>UFL: The Unified Form
Language, <ext-link xlink:href="http://dx.doi.org/10.5281/zenodo.47713" ext-link-type="DOI">10.5281/zenodo.47713</ext-link>, 2016.</mixed-citation></ref>
      <ref id="bib1.bibx33"><label>Yoon et al.(2005)Yoon, Lindstrom, Pascucci, and Manocha</label><mixed-citation>Yoon, S.-E., Lindstrom, P., Pascucci, V., and Manocha, D.: Cache-oblivious
Mesh
Layouts, ACM Trans. Graph., 24, 886–893, <ext-link xlink:href="http://dx.doi.org/10.1145/1073204.1073278" ext-link-type="DOI">10.1145/1073204.1073278</ext-link>,  2005.</mixed-citation></ref>
      <ref id="bib1.bibx34"><label>Zängl et al.(2015)Zängl, Reinert, Rípodas, and
Baldauf</label><mixed-citation>Zängl, G., Reinert, D., Rípodas, P., and Baldauf, M.: The ICON
(ICOsahedral Non-hydrostatic) modelling framework of DWD and MPI-M:
Description of the non-hydrostatic dynamical core, Q. J.
Roy. Meteor. Soc., 141, 563–579, <ext-link xlink:href="http://dx.doi.org/10.1002/qj.2378" ext-link-type="DOI">10.1002/qj.2378</ext-link>, 2015.</mixed-citation></ref>

  </ref-list><app-group content-type="float"><app><title/>

    </app></app-group></back>
    <!--<article-title-html>A structure-exploiting numbering algorithm for finite elements on
extruded meshes, and its performance evaluation in Firedrake</article-title-html>
<abstract-html><p class="p">We present a generic algorithm for numbering and then efficiently iterating
over the data values attached to an extruded mesh. An extruded mesh is formed
by replicating an existing mesh, assumed to be unstructured, to form layers
of prismatic cells. Applications of extruded meshes include, but are not
limited to, the representation of three-dimensional high aspect ratio domains
employed by geophysical finite element simulations. These meshes are
structured in the extruded direction. The algorithm presented here exploits
this structure to avoid the performance penalty traditionally associated with
unstructured meshes. We evaluate the implementation of this algorithm in the
Firedrake finite element system on a range of low compute intensity
operations which constitute worst cases for data layout performance
exploration. The experiments show that having structure along the extruded
direction enables the cost of the indirect data accesses to be amortized
after 10–20 layers as long as the underlying mesh is well ordered. We
characterize the resulting spatial and temporal reuse in a representative set
of both continuous-Galerkin and discontinuous-Galerkin discretizations. On
meshes with realistic numbers of layers the performance achieved is between
70 and 90 % of a theoretical hardware-specific limit.</p></abstract-html>
<ref-html id="bib1.bib1"><label>Bercea(2016a)</label><mixed-citation>
Bercea, G.-T.: Unstructured meshes for extrusion article,
<a href="http://dx.doi.org/10.5281/zenodo.61819" target="_blank">doi:10.5281/zenodo.61819</a>, 2016a.
</mixed-citation></ref-html>
<ref-html id="bib1.bib2"><label>Bercea(2016b)</label><mixed-citation>
Bercea, G.-T.: Data and plot scripts for Haswell experiments,
<a href="http://dx.doi.org/10.5281/zenodo.61919" target="_blank">doi:10.5281/zenodo.61919</a>, 2016b.
</mixed-citation></ref-html>
<ref-html id="bib1.bib3"><label>Bercea(2016c)</label><mixed-citation>
Bercea, G.-T.: Data and plot scripts for Sandy Bridge experiments,
<a href="http://dx.doi.org/10.5281/zenodo.61920" target="_blank">doi:10.5281/zenodo.61920</a>, 2016c.
</mixed-citation></ref-html>
<ref-html id="bib1.bib4"><label>COFFEE(2016)</label><mixed-citation>
COFFEE: A Compiler for Fast Expression
Evaluation, <a href="http://dx.doi.org/10.5281/zenodo.47715" target="_blank">doi:10.5281/zenodo.47715</a>, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib5"><label>FFC(2016)</label><mixed-citation>
FFC: FEniCS Form
Compiler, <a href="http://dx.doi.org/10.5281/zenodo.47761" target="_blank">doi:10.5281/zenodo.47761</a>, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib6"><label>FIAT(2016)</label><mixed-citation>
FIAT:
The Finite Element Automated Tabulator, <a href="http://dx.doi.org/10.5281/zenodo.47716" target="_blank">doi:10.5281/zenodo.47716</a>, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib7"><label>Firedrake(2016)</label><mixed-citation>
Firedrake: An automated finite element
system, <a href="http://dx.doi.org/10.5281/zenodo.47717" target="_blank">doi:10.5281/zenodo.47717</a>, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib8"><label>Ford et al.(2013)Ford, Glover, Ham, Maynard, Pickles, and
Riley</label><mixed-citation>
Ford, R., Glover, M., Ham, D., Maynard, C., Pickles, S., and Riley, G.:
GungHo Phase 1: Computational Science Recommendations, Tech. rep., Met
Office, Exeter, 2013.
</mixed-citation></ref-html>
<ref-html id="bib1.bib9"><label>Gersbacher(2012)</label><mixed-citation>
Gersbacher, C.: The Dune-PrismGrid Module, in: Advances in DUNE: Proceedings
of
the DUNE User Meeting, edited by: Dedner, A., Flemisch, B., and Klöfkorn, R., 6–8 October 2010, Stuttgart, Germany,
33–44,
Springer Berlin Heidelberg, Berlin, Heidelberg,
<a href="http://dx.doi.org/10.1007/978-3-642-28589-9_3" target="_blank">doi:10.1007/978-3-642-28589-9_3</a>, 2012.
</mixed-citation></ref-html>
<ref-html id="bib1.bib10"><label>Geuzaine and Remacle(2009)</label><mixed-citation>
Geuzaine, C. and Remacle, J.-F.: Gmsh: A 3-D finite element mesh generator
with built-in pre- and post-processing facilities, International
Journal for Numerical Methods in Engineering, 79, 1309–1331, 2009.
</mixed-citation></ref-html>
<ref-html id="bib1.bib11"><label>Günther et al.(2006)Günther, Mehl, Pögl, and
Zenger</label><mixed-citation>
Günther, F., Mehl, M., Pögl, M., and Zenger, C.: A Cache-Aware
Algorithm for PDEs on Hierarchical Data Structures Based on Space-Filling
Curves, SIAM J. Sci. Comput., 28, 1634–1650, <a href="http://dx.doi.org/10.1137/040604078" target="_blank">doi:10.1137/040604078</a>, 2006.
</mixed-citation></ref-html>
<ref-html id="bib1.bib12"><label>Intel(2012)</label><mixed-citation>
Intel: Intel Architecture Code Analyzer, available at:
<a href="https://software.intel.com/en-us/articles/intel-architecture-code-analyzer" target="_blank">https://software.intel.com/en-us/articles/intel-architecture-code-analyzer</a>
(last access: October 2016), 2012.
</mixed-citation></ref-html>
<ref-html id="bib1.bib13"><label>Isaac(2015)</label><mixed-citation>
Isaac, T.: Scalable, adaptive methods for forward and inverse problems in
continental-scale ice sheet modeling, PhD thesis, University of Texas,
Austin, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib14"><label>Isaac et al.(2015)Isaac, Stadler, and Ghattas</label><mixed-citation>
Isaac, T., Stadler, G., and Ghattas, O.: Solution of Nonlinear Stokes
Equations
Discretized By High-Order Finite Elements on Nonconforming and Anisotropic
Meshes, with Application to Ice Sheet Dynamics, SIAM J. Sci.
Comput., 37, B804–B833, <a href="http://dx.doi.org/10.1137/140974407" target="_blank">doi:10.1137/140974407</a>, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib15"><label>Knepley and Karpeev(2009)</label><mixed-citation>
Knepley, M. G. and Karpeev, D. A.: Mesh Algorithms for PDE with Sieve I:
Mesh
Distribution, Sci. Program., 17, 215–230,
<a href="http://dx.doi.org/10.3233/SPR-2009-0249" target="_blank">doi:10.3233/SPR-2009-0249</a>, 2009.
</mixed-citation></ref-html>
<ref-html id="bib1.bib16"><label>Lange et al.(2016)Lange, Mitchell, Knepley, and Gorman</label><mixed-citation>
Lange, M., Mitchell, L., Knepley, M., and Gorman, G.: Efficient mesh
management
in Firedrake using PETSc-DMPlex,  SIAM J. Sci.
Comput., available at: <a href="http://arxiv.org/abs/1506.07749" target="_blank">http://arxiv.org/abs/1506.07749</a>, in press, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib17"><label>Logg(2009)</label><mixed-citation>
Logg, A.: Efficient Representation of Computational Meshes, Int.
J. Comput. Sci. Eng., 4, 283–295,
<a href="http://dx.doi.org/10.1504/IJCSE.2009.029164" target="_blank">doi:10.1504/IJCSE.2009.029164</a>, 2009.
</mixed-citation></ref-html>
<ref-html id="bib1.bib18"><label>Luporini et al.(2015)</label><mixed-citation>
Luporini, F., Varbanescu, A. L., Rathgeber, F., Bercea, G.-T., Ramanujam, J.,
Ham, D. A., and Kelly, P. H. J.: Cross-Loop Optimization of Arithmetic
Intensity for Finite Element Local Assembly, ACM Trans. Archit. Code Optim.,
11, 1–25, <a href="http://dx.doi.org/10.1145/2687415" target="_blank">doi:10.1145/2687415</a>, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib19"><label>Macdonald et al.(2011)Macdonald, Middlecoff, Henderson, and
Lee</label><mixed-citation>
Macdonald, A. E., Middlecoff, J., Henderson, T., and Lee, J.-L.: A General
Method for Modeling on Irregular Grids, Int. J. High Perform. C.,
25, 392–403, <a href="http://dx.doi.org/10.1177/1094342010385019" target="_blank">doi:10.1177/1094342010385019</a>, 2011.
</mixed-citation></ref-html>
<ref-html id="bib1.bib20"><label>McCalpin(1995)</label><mixed-citation>
McCalpin, J. D.: Memory Bandwidth and Machine Balance in Current High
Performance Computers, IEEE Computer Society Technical Committee on Computer
Architecture (TCCA) Newsletter,  19–25, 1995.
</mixed-citation></ref-html>
<ref-html id="bib1.bib21"><label>McRae et al.(2016)McRae, Bercea, Mitchell, Ham, and
Cotter</label><mixed-citation>
McRae, A. T. T., Bercea, G.-T., Mitchell, L., Ham, D. A., and Cotter, C. J.:
Automated generation and symbolic manipulation of tensor product finite
elements,  SIAM J. Sci. Comput., available at: <a href="http://arxiv.org/abs/1411.2940" target="_blank">http://arxiv.org/abs/1411.2940</a>, in press, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib22"><label>Meister and Bader(2015)</label><mixed-citation>
Meister, O. and Bader, M.: 2D adaptivity for 3D problems: Parallel SPE10
reservoir simulation on dynamically adaptive prism grids, J. Comput. Sci., 9,
101–106,
<a href="http://dx.doi.org/10.1016/j.jocs.2015.04.016" target="_blank">doi:10.1016/j.jocs.2015.04.016</a>, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib23"><label>Mucci et al.(1999)Mucci, Browne, Deane, and Ho</label><mixed-citation>
Mucci, P. J., Browne, S., Deane, C., and Ho, G.: PAPI: A Portable Interface
to Hardware Performance Counters, Proceedings of the Department of
Defense HPCMP Users Group Conference, 7–10, 1999.
</mixed-citation></ref-html>
<ref-html id="bib1.bib24"><label>Ofenbeck et al.(2014)</label><mixed-citation>
Ofenbeck, G., Steinmann, R., Caparros, V., Spampinato, D. G., and Puschel,
M.:
Applying the roofline model, in: 2014 IEEE International Symposium on
Performance Analysis of Systems and Software (ISPASS),  76–85,
<a href="http://dx.doi.org/10.1109/ISPASS.2014.6844463" target="_blank">doi:10.1109/ISPASS.2014.6844463</a>, 2014.
</mixed-citation></ref-html>
<ref-html id="bib1.bib25"><label>PETSc(2016)</label><mixed-citation>
PETSc: Portable, Extensible
Toolkit for Scientific Computation, <a href="http://dx.doi.org/10.5281/zenodo.47718" target="_blank">doi:10.5281/zenodo.47718</a>, 2016.

</mixed-citation></ref-html>
<ref-html id="bib1.bib26"><label>petsc4py(2016)</label><mixed-citation>
petsc4py: The Python interface to PETSc, <a href="http://dx.doi.org/10.5281/zenodo.47714" target="_blank">doi:10.5281/zenodo.47714</a>,
2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib27"><label>PyOP2(2016)</label><mixed-citation>
PyOP2: Framework for performance-portable
parallel computations on unstructured meshes, <a href="http://dx.doi.org/10.5281/zenodo.47712" target="_blank">doi:10.5281/zenodo.47712</a>,
2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib28"><label>Rathgeber et al.(2016)Rathgeber, Ham, Mitchell, Lange, Luporini,
McRae, Bercea, Markall, and Kelly</label><mixed-citation>
Rathgeber, F., Ham, D. A., Mitchell, L., Lange, M., Luporini, F., McRae, A.
T. T., Bercea, G.-T., Markall, G. R., and Kelly, P. H. J.: Firedrake:
automating the finite element method by composing abstractions,  ACM Trans. Math. Software, available at: <a href="http://arxiv.org/abs/1501.01809" target="_blank">http://arxiv.org/abs/1501.01809</a>, in press,
2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib29"><label>Sarje et al.(2015)Koziel, Leifsson, Lees, V.Krzhizhanovskaya,
Dongarra, Sloot, Sarje, Song, Jacobsen, Huck, Hollingsworth, Malony,
Williams, and Oliker</label><mixed-citation>
Sarje, A., Song, S., Jacobsen, D., Huck, K., Hollingsworth, J., Malony, A.,
Williams, S., and Oliker, L.: Parallel Performance Optimizations on
Unstructured Mesh-based Simulations, Procedia Computer Science, 51,
2016–2025, <a href="http://dx.doi.org/10.1016/j.procs.2015.05.466" target="_blank">doi:10.1016/j.procs.2015.05.466</a>, 2015.
</mixed-citation></ref-html>
<ref-html id="bib1.bib30"><label>Skamarock et al.(2012)Skamarock, Klemp, Duda, Fowler, Park, and
Ringler</label><mixed-citation>
Skamarock, W. C., Klemp, J. B., Duda, M. G., Fowler, L. D., Park, S.-H., and
Ringler, T. D.: A multiscale nonhydrostatic atmospheric model using
centroidal Voronoi tesselations and C-grid staggering, Mon. Weather
Rev., 140, 3090–3105, <a href="http://dx.doi.org/10.1175/MWR-D-11-00215.1" target="_blank">doi:10.1175/MWR-D-11-00215.1</a>, 2012.
</mixed-citation></ref-html>
<ref-html id="bib1.bib31"><label>Slingo et al.(2009)Slingo, Bates, Nikiforakis, Piggott, Roberts,
Shaffrey, Stevens, Vidale, and Weller</label><mixed-citation>
Slingo, J., Bates, K., Nikiforakis, N., Piggott, M., Roberts, M., Shaffrey,
L.,
Stevens, I., Vidale, P. L., and Weller, H.: Developing the next-generation
climate system models: challenges and achievements, Philos.
T. R. Soc. Lond. A, 367, 815–831, <a href="http://dx.doi.org/10.1098/rsta.2008.0207" target="_blank">doi:10.1098/rsta.2008.0207</a>, 2009.
</mixed-citation></ref-html>
<ref-html id="bib1.bib32"><label>UFL(2016)</label><mixed-citation>
UFL: The Unified Form
Language, <a href="http://dx.doi.org/10.5281/zenodo.47713" target="_blank">doi:10.5281/zenodo.47713</a>, 2016.
</mixed-citation></ref-html>
<ref-html id="bib1.bib33"><label>Yoon et al.(2005)Yoon, Lindstrom, Pascucci, and Manocha</label><mixed-citation>
Yoon, S.-E., Lindstrom, P., Pascucci, V., and Manocha, D.: Cache-oblivious
Mesh
Layouts, ACM Trans. Graph., 24, 886–893, <a href="http://dx.doi.org/10.1145/1073204.1073278" target="_blank">doi:10.1145/1073204.1073278</a>,  2005.
</mixed-citation></ref-html>
<ref-html id="bib1.bib34"><label>Zängl et al.(2015)Zängl, Reinert, Rípodas, and
Baldauf</label><mixed-citation>
Zängl, G., Reinert, D., Rípodas, P., and Baldauf, M.: The ICON
(ICOsahedral Non-hydrostatic) modelling framework of DWD and MPI-M:
Description of the non-hydrostatic dynamical core, Q. J.
Roy. Meteor. Soc., 141, 563–579, <a href="http://dx.doi.org/10.1002/qj.2378" target="_blank">doi:10.1002/qj.2378</a>, 2015.
</mixed-citation></ref-html>--></article>
