1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388
|
\chapter{Create Fields and Field Sets}
In this chapter, we show how to create fields and field sets
using \Atlas. Specifically, we outline how to create two simple
fields and how to include them into a field set. These two fields
are standalone, thus not related to any grid - i.e. they are just
defined as generic multidimensional arrays containing some values
and a short description of what is stored inside them.
Successively, we introduce how to create two fields on a given
grid and again how to add them to a field set.
As done for the other examples, we show both the C++ and Fortran
versions.
\section{Standalone Fields and Field Sets}
\label{sect:standalone-fields}
\subsection{C++ version}
The \lista{code-fields-C} shows how to construct two standalone
fields and encapsulate them into a field set.
%
\lstinputlisting[caption=Generating two fields and encapsulating
them into a FieldSet using C++, style=CStyle, label=code-fields-C]{fields.cc}
%
On the first few lines of the code, we include the necessary
\Atlas header files needed for this example. Note in particular
the inclusion of \inltc{Field.h}, \inltc{FieldSet.h} and
\inltc{Metadata.h}. The first is necessary to define fields,
the second to define field set and the third to add a description
to the fields.
We then define two fields, one called \inltc{field\_pressure} that,
for instance, will contain the pressure, and the other one called
\inltc{field\_wind} that will for example contain the velocity of
the wind in two orthogonal directions.
How does the creation of a field work?\\
On lines 18 and 20, we can see the construction of the two fields.
We first need to declare a pointer of type \inltc{Field} and we
successively call the constructor for this field. This is composed
by three elements: the type of data contained within the field
(in our case double), the name of the field as a string (in our
case 'pressure') and its dimensions.
Note that we allow multidimensional fields up to 6 dimensions
(this number can be extended if required)!
%
\begin{tipbox}
In a field we can only store numbers - no strings or characters!
In particular, we support 32 and 64 bit integer and real types.
\end{tipbox}
%
Once the fields are defined we need to initialize them
and give them some values. This task can be achieved
by using the code on lines 24 and 25, where we acquire access to
the two fields using \inltc{ArrayView} objects, \inltc{pressure}
and \inltc{wind}.
We successively prescribe some values to these two objects
(see lines 28 to 33). This step automatically updates what
is stored in the two field objects, \inltc{field\_pressure}
and \inltc{field\_wind}.
The work for defining the two fields is almost completed.
We can add just one more little feature - one or more
descriptors. This task is performed on lines 37 to 40,
where we use the \inltc{metadata} object to set the
units of our fields and retrieve them through the
functions, \inltc{set} and \inltc{get}, respectively.
These two fields are fully functional and can be used
for our specific application. However, we may want to
encapsulate several fields into one object. This task
can be achieved by using the object \inltc{FieldSet},
as show on lines 43 to 45, where we define the field
set and we add the two fields into it.
Any field can also be retrieved from a \emph{FieldSet} by
using the code on lines 48 and 49, where we ask for
the field 'pressure' and the field 'wind' to be retrieved
by two new empty fields.
%
\begin{notebox}
It is possible to retrieve a field from a \emph{FieldSet}
either by using the name of the field or by using
the number identifying it. In our example, \inltc{field\_pressure}
assumes id=0 (since stored first), while \inltc{field\_wind}
assumes id=1 (since stored second).
\end{notebox}
%
After having defined the field set, we print some
useful information regarding the fields (for the
sake of brevity we print just some information
regarding the \inltc{field\_wind} - the information
regarding the \inltc{field\_pressure} can be obtained
in an identical way).
In particular, we print the name, the size and the \inltc{metadata}
associated to the \inltc{field\_wind} (see lines 52 to 54).
We then extract its rank, shape and dimensions in bytes
(see lines 55 to 58). We finally print type of the data
stored in the field (see lines 60 and 61).
On lines 64 to 66 we also print the values of one element
per each field. Note that the memory of the objects defined
in this example is automatically released when the execution
ends. So, there is no need to manually destroy the objects.
This aspect is different in the Fortran example below, where
we will need to explicitly finalise all the objects created!
It is now possible to run this simple program typing
the following text on the terminal
%
\begin{lstlisting}[style=BashStyle]
./atlas_c-fields
\end{lstlisting}
%
This will produce the two fields described and a field
set and will destroy them at the end of the routine,
thus automatically releasing the memory.
It will also print to the screen some useful information
regarding the fields - specifically you should obtain
a screen output similar to the one below:
%
\begin{lstlisting}[style=BashStyle]
[0] (2016-03-15 T 15:57:33) (I) -- name = wind
[0] (2016-03-15 T 15:57:33) (I) -- size = 200
[0] (2016-03-15 T 15:57:33) (I) -- units = [m/s]
[0] (2016-03-15 T 15:57:33) (I) -- rank = 2
[0] (2016-03-15 T 15:57:33) (I) -- shape = 100 2
[0] (2016-03-15 T 15:57:33) (I) -- memory = 1600 bytes
[0] (2016-03-15 T 15:57:33) (I) -- type = real64
[0] (2016-03-15 T 15:57:33) (I) -- kind = 8
[0] (2016-03-15 T 15:57:33) (I) -- pressure(9) = 101325
[0] (2016-03-15 T 15:57:33) (I) -- wind(9, 0) = 9.01
[0] (2016-03-15 T 15:57:33) (I) -- wind(9, 1) = 9.02
\end{lstlisting}
%
You can now play with the code in \lista{code-fields-C}
to generate as many fields/field sets as you want!
\section{Fortran version}
The \lista{code-fields-F} shows how to construct two standalone
fields and encapsulate them into a field set.
%
\lstinputlisting[caption=Generating two fields and encapsulating
them into a FieldSet using Fortran, style=FStyle, label=code-fields-F]{fields.F90}
%
On the first few lines of the code, we define the variables
needed for this program. In particular, the \Atlas specific
variables needed for this example are the \inltf{atlas\_Field},
\inltf{atlas\_FieldSet} and \inltf{atlas\_Metadata} objects.
After having defined all the data needed for this example,
we initialize the \Atlas library as usual and we define
two fields, one called \inltf{field\_pressure} that, for
instance, will contain the pressure and the other one
called \inltf{field\_wind} that will for example contain
the velocity of the wind in two orthogonal directions.
How does the creation of a field work?\\
On lines 17 and 18 we can see the construction of the two fields.
We first need to specify the name of the field (in our case 'pressure'
and 'wind'), then we need to specify the type of the data stored
into the fields (in our case double precision numbers) and finally
we need to provide the dimension of the field.
Note that we allow multidimensional fields up to 6 dimensions
(this number can be extended if required)!
%
\begin{tipbox}
In a field we can only store numbers - no strings or characters!
In particular, we support integers, float types and double types.
\end{tipbox}
%
Once the fields are defined we need to access the data
and give them some values. This task can be achieved
by using the code on lines 23 and 24, where we access
the data of the two fields by two pointers \inltf{pressure} and
\inltf{wind}, respectively.
We successively prescribe some values to these two pointers
(see lines 27 to 31). This step automatically updates what
is stored in the two field objects, \inltf{field\_pressure}
and \inltf{field\_wind}.
The work for defining the two fields is almost completed.
We can add just one more little feature - one or more
descriptors. This task is performed on lines 34 to 39,
where we use the \inltf{metadata} object to set the units
of our fields and retrieve them through the functions,
\inltf{set} and \inltf{get}, respectively.
These two fields are fully functional and can be used
for our specific application. However, we may want to
encapsulate several fields into one object. This task
can be achieved by using the object \inltf{atlas\_FieldSet},
as show on lines 40 to 42, where we define the field
set and we add the two fields into it.
Any field can also be retrieved from a field set by
using the code on lines 45 and 46, where we ask for
the field 'pressure' and the field 'wind' to be retrieved
by two new \inltf{atlas\_Field} objects.
%
\begin{notebox}
It is possible to retrieve a \emph{Field} from a \emph{FieldSet}
either by using the name of the field or by using
the number identifying it. In our example, \inltf{field\_pressure}
assumes id=1 (since stored first), while \inltf{field\_wind}
assumes id=2 (since stored second).
\end{notebox}
%
After having defined the field set, we print some
useful information regarding the fields (for the sake of
brevity we print just some information regarding the \inltf{field\_wind}
- the information regarding the \inltf{field\_pressure} can
be obtained in an identical way).
In particular, we print the name, the size and the \inltf{metadata}
associated to the \inltf{field\_wind} (see lines 51 to 55).
We then extract its rank, shape and dimensions in bytes
(see lines 57 to 66). We finally print type of the data
stored in the field (see lines 67 and 70).
On lines 73 to 78 we also print the values of one element
per each field and we finalise the field objects on lines
81 and 82 (thus releasing the memory).
Note that finalising the \inltf{atlas\_Field} objects
is enough to also finalise \inltf{atlas\_FieldSet} object;
we need to explicitly finalise it as well to completely
free the memory associated to all the objects defined
in this example (see line 83).
It is now possible to run this simple program typing
the following text on the terminal
%
\begin{lstlisting}[style=BashStyle]
./atlas_f-fields
\end{lstlisting}
%
This will produce the two fields described and a field
set and will destroy them at the end of the routine
(thus releasing the memory). It will also print to
the screen some useful information regarding the fields.
In particular, you should obtain an output similar to
the one below:
%
\begin{lstlisting}[style=BashStyle]
[0] (2016-03-15 T 17:16:01) (I) -- name = wind
[0] (2016-03-15 T 17:16:01) (I) -- size = 200
[0] (2016-03-15 T 17:16:01) (I) -- units = [m/s]
[0] (2016-03-15 T 17:16:01) (I) -- rank = 2
[0] (2016-03-15 T 17:16:01) (I) -- shape(1) = 2
[0] (2016-03-15 T 17:16:01) (I) -- shape(2) = 100
[0] (2016-03-15 T 17:16:01) (I) -- shape = 2 100
[0] (2016-03-15 T 17:16:01) (I) -- memory = 1600.0000 bytes
[0] (2016-03-15 T 17:16:01) (I) -- type = real64
[0] (2016-03-15 T 17:16:01) (I) -- kind = 8
[0] (2016-03-15 T 17:16:01) (I) -- pressure(10) = 101325.0000
[0] (2016-03-15 T 17:16:01) (I) -- wind(1, 10) = 10.01000000
[0] (2016-03-15 T 17:16:01) (I) -- wind(2, 10) = 10.02000000
\end{lstlisting}
%
You can now play with the code in \lista{code-fields-F}
to generate as many fields/field sets as you want!
\section{Fields on a given Grid}
\label{sect:grid-fields}
\subsection{C++ version}
The \lista{code-fields-on-grid-C} shows how to construct one field
on a given grid. To see how to create a generic field and
a field set and how to use some additional functionalities
related to fields, please refer to \sect{sect:standalone-fields}
above.
%
\lstinputlisting[caption=Generating a field on a given grid
using C++, style=CStyle, label=code-fields-on-grid-C]{fields-on-grid.cc}
%
On the first few lines of the code, we include the necessary
header files for this example. In particular, we include
\inltc{grids.h}, \inltc{Field.h}. We then initialize the \Atlas library
and define some constants needed to define the function
we are going to implement later in the code.
We then create
a \inltc{grid} object and a \inltc{field} object.
Note that we used a command-line argument to decide
what grid to use (see \chap{chap:global-grids} for
more details on how to create global grids).
On line 24, we define the grid using a command-line key
that can be specified by the user (see \chap{chap:global-grids}
for more details on how to create global grids).
On lines 27 and 28, we define the pressure field, while,
on line, 30 we initialize the associated \inltc{ArrayView}
object, needed to manipulate and access the data inside the
\inltc{Field} object.
From line 31 to line 50, we specify the a Gaussian-type
(e.g. a hill) function on our grid (specifically, the
field is defined between line 43 and 47).
We finally close the program outputting on the screen
the memory footprint of the field just created.
Note that we do not need to free the memory of the grid
and field objects, since it is automatically released
at the end of the execution (in contrast to Fortran,
where we explicitly need to destroy the objects created).
It is now possible to run this simple program typing
the following text on the terminal
%
\begin{lstlisting}[style=BashStyle]
./atlas_c-fields-on-grid
\end{lstlisting}
%
This will produce a field (called pressure) defined
on an octahedral grid that has the shape of a hill
or Gaussian-type function.
The output on the screen should be the memory footprint
of the field created on the grid and it should be similar
to the one below:
%
\begin{lstlisting}[style=BashStyle]
==========================================
memory field_pressure = 0.0338493 GB
==========================================
\end{lstlisting}
%
Not a big deal for this grid!
You can now play with the command-line argument and
generate different grids and see the impact on the
memory footprint of the pressure field.
\subsection{Fortran version}
The \lista{code-fields-on-grid-F} shows how to construct one field
on a given grid. To see how to create a generic field and
a field set and how to use some additional functionalities
related to fields, please refer to \sect{sect:standalone-fields}
above.
%
\lstinputlisting[caption=Generating a field on a given grid
using Fortran, style=FStyle, label=code-fields-on-grid-F]{fields-on-grid.F90}
%
On the first few lines of the code, we define the variables
needed for this program. In particular, we define some constants
needed for the function we are going to implement later in the
code and we declare an \inltf{atlas\_grid\_Structured} grid object and
an \inltf{atlas\_Field} object.
On lines 21 and 22 we define the grid using a command-line key
that can be specified by the user (see \chap{chap:global-grids}),
while on lines 24 and 25, we initialize the pressure field.
From line 28 to line 45, we specify the a Gaussian-type
(e.g. a hill) function on our grid (specifically, the
field is defined on lines 39 to 42).
We finally close the program outputting on the screen
the memory footprint of the field just created. As usual,
we also explicitly need to free the memory calling the
function \inltf{final} on the grid and field objects.
It is now possible to run this simple program typing
the following text on the terminal
%
\begin{lstlisting}[style=BashStyle]
./atlas_f-fields-on-grid
\end{lstlisting}
%
This will produce a field (called pressure) defined
on an octahedral grid that has the shape of a hill
or Gaussian-type function.
The output on the screen should be the memory footprint
of the field created on the grid and it should be similar
to the one below:
%
\begin{lstlisting}[style=BashStyle]
=================================================
memory field_pressure = 3.3849344000000003E-002 GB
=================================================
\end{lstlisting}
%
Not a big deal for this grid!
You can now play with the command-line argument and
generate different grids and see the impact on the
memory footprint of the pressure field.
|