README.md 10.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
## Preliminary layout for OpenFOAM data within ADIOS

* This is a work-in-progress (proof-of-concept) for reading/writing
  OpenFOAM data with ADIOS.
* For development purposes, a function object is used for the implementation framework.
* Restart is with a 'fast-forward' principle: OpenFOAM is used for the Time=0
  construction of meshes and fields, fields are overwritten with their
  values read from the adios file.
* Supports multiple regions, multiple clouds per region.
* Restarting with mesh changing is not yet implemented.
* Restarting with clouds needs more work.

---

15
2016-12-20
16 17 18 19 20

---

* Storage directory:  "adiosData/"

21 22 23
* Each "ofbp" (OpenFOAM binary packed) adios file is restricted to a
  ***single*** time-step/iteration.
  This makes for simple and efficient handling.
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

* In rare cases are values stored in global arrays with offsets.
  - Single values per-processor (eg, time index).
  - Cloud parcel data (currently).

  In all other cases, data are stored with their local dimensions only.

* Data stored as "unsigned byte" generally represent binary content
  that has been serialized via the OpenFOAM `Ostream` and are targeted
  for use by an `Istream` when reading. This binary content should be
  largely identical to a normal OpenFOAM field-file, but without the
  file-header.

---

### General Attributes

These attributes provide assistance when reading the data files.
All entries are considered mandatory.


| type    | name                        | example
|---------|-----------------------------|--------
| _any_   | /constant/...               | _reserved_
| _any_   | /system/...                 | _reserved_
| string  | /openfoam/version           | "plus-e40d8870f95a"
50 51 52
| string  | /openfoam/endian            | "LSB"
| int     | /openfoam/label             | 32
| int     | /openfoam/scalar            | 64
53 54 55 56 57
| int     | /openfoam/nProcs            | 4
| int     | /openfoam/nRegions          | 2
| string[]| /openfoam/regions           | {"region0", "solid"}


58 59 60 61 62
The number of regions can either be obtained directly from the
`/openfoam/nRegions` attribute, or aternatively from the list length
of the `/openfoam/regions` attribute. No particular sort order is
specified for the region names.

mark's avatar
mark committed
63 64 65 66 67 68

These additional attributes provide assistance when reading the data files.
These entries are advisable.

| type    | name                        | example
|---------|-----------------------------|--------
69
| string  | /openfoam/baseline/plus     | 1612
mark's avatar
mark committed
70 71 72
| string  | /openfoam/platform          | "linux64Gcc"


73 74 75 76 77 78 79 80 81 82
### General Variables

Coordinated data for all mesh, fields and cloud information.

| type    | name                        | comment
|---------|-----------------------------|-------------
| _any_   | /constant/...               | _reserved_
| _any_   | /system/...                 | _reserved_


83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
### Time Attributes

Since each file is restricted to a ***single*** time-step/iteration,
which inherently identical across all processes, the time management
values are tracked as attributes rather than as variables. This
additionally simplifies later post-processing, since the attribute
values are available directly from the meta-data.


| type    | name            | comment
|---------|-----------------|-------------
| int     | /time/index     | iteration value
| double  | /time/value     | time-value
| double  | /time/deltaT    | current time-step value
| double  | /time/deltaT0   | previous time-step value
98 99 100 101
| double[]| /time/faces     | time-value of mesh topology (per region)
| double[]| /time/points    | time-value of mesh points (per region)

The order of the `/time/faces` and `/time/points` attributes must
102
correspond exactly to the ordering used by the `/openfoam/regions` attribute.
103 104 105

The attribute `/time/value` can be considered to be a global time value
for all fields and clouds contained within the file.
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
When the `/time/faces` value for a particular region matches that of
`/time/value`, the file will also contain a mesh description for that
region.
If only the `/time/points` value for a particular region matches, this
indicates mesh motion (but with the same topology) and the file will
correspondingly contain the updated points for that region.

This mechanism can be used to locate an appropriate mesh description from
previously saved files.
The following pseudocode illustrates part of the logic:

    if /time/value == /time/faces/REGION
        # current file contains updated topology (points, faces, etc)
        REGION/polyMesh/points
        REGION/polyMesh/faces/...
        ...

    elif /time/value == /time/points/REGION
        # current file contains updated mesh points
        REGION/polyMesh/points

    else
        # mesh points, faces in an older file
        # - compare to currently loaded meshes to see if update is needed


Since the adios files are generally saved with names corresponding to
their time state, it is possible to identify the file containing a
particular mesh/time-state without searching the file contents.
135

136 137 138 139 140 141 142 143 144 145 146

### Region Attributes

Basic information that applies to mesh and field information.

| type    | name                        | comment
|---------|-----------------------------|--------
| int     | \<regionName\>/nPatches     | number of patches
| string[]| \<regionName\>/patch-names  | patch names
| string[]| \<regionName\>/patch-types  | patch types

mark's avatar
mark committed
147 148 149 150 151
The number of patches used in the mesh may be larger than the number
of patch names and types attributes since these attributes do not
include any processor patches.


152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
#### Example

| type    | name                        | example
|---------|-----------------------------|--------
| int     | region0/nPatches            | 3
| string[]| region0/patch-names         | {"movingWall", "fixedWalls", "frontAndBack"}
| string[]| region0/patch-types         | {"wall", "wall", "empty" }
|         | solid/...                   |


### Meshes

These variables are only available when the *updateMesh* attribute is
also true.

#### Global Array Variables


| type    | name                                | comment
|---------|-------------------------------------|-------------
| int     | \<regionName\>/polyMesh/nPoints     | per processor
| int     | \<regionName\>/polyMesh/nCells      | per processor
| int     | \<regionName\>/polyMesh/nFaces      | per processor
175
| int     | \<regionName\>/polyMesh/nInternalFaces | per processor
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194


#### Localized Variables

| type    | name                                  | comment
|---------|---------------------------------------|-------------
| double  | \<regionName\>/polyMesh/points        | {nPoints x 3}
| int     | \<regionName\>/polyMesh/faces/indices | indices for compact faceList
| int     | \<regionName\>/polyMesh/faces/content | content for compact faceList
| int     | \<regionName\>/polyMesh/owner         | face owners
| int     | \<regionName\>/polyMesh/neighbour     | face neighbours
| byte    | \<regionName\>/polyMesh/boundary      | boundary mesh information


### Fields


#### Localized Variables

mark's avatar
mark committed
195 196 197 198 199 200
| type    | name                                 | comment
|---------|--------------------------------------|-------------
| double  | \<regionName\>/field/p               | internalField - primitive field content
| byte    | \<regionName\>/field/p/boundaryField | as per OPENFOAM binary file content
| double  | \<regionName\>/field/U               | primitive field content
| byte    | \<regionName\>/field/U/boundaryField | internalField - primitive field content
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
|         | ...


#### Attributes

| type    | name                                | example
|---------|-------------------------------------|-------------
| string  | \<regionName\>/field/p/class        | "volScalarField"
| string[]| \<regionName\>/field/p/patch-types  | { "zeroGradient", "zeroGradient", "empty" }
| string  | \<regionName\>/field/U/class        | "volVectorField"
| string[]| \<regionName\>/field/U/patch-types  | {"fixedValue", "fixedValue", "empty"}
|         | ...


### Clouds

These entries are only available when the region also has any active
cloud information. A missing value of `nClouds` is equivalent to `nClouds=0`.

For efficiency, the parcel contents are stored directly as a binary
*blob*. The meaning of the binary content can be reconstructed
from its list of names and types.

#### Region Cloud Attributes

| type    | name                        | comment
|---------|-----------------------------|-------------
| int     | \<regionName\>/nClouds      | number of associated clouds in region
| string[]| \<regionName\>/clouds       | {"name0", "name1", ...}


#### Cloud Variables (Globally-addressable)

| type    | name                           | comment
|---------|--------------------------------|-------------
236 237 238
| byte    | \<regionName\>/cloud/\<cloudName\> | cloud binary content
| int     | \<regionName\>/cloud/\<cloudName\>/nParcels | per processor
| int     | \<regionName\>/cloud/\<cloudName\>/sizes | parcels sizes for variable-sized content
239 240


241 242 243 244 245 246 247 248
The cloud attribute `min-size` corresponds to the fixed parcel length
known _a priori_ (eg, via the respective parcel `sizeofFields` value.
The cloud attribute `max-size` corresponds to the
maximum parcel length at a given time-step. If the `max-size` is not
equal to the `min-size`, the cloud type has variable-sized content and
the `sizes` variable is necessary for decoding the parcel content
manually.

249 250 251 252
#### Cloud Attributes

| type    | name                           | example
|---------|--------------------------------|-------------
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
| string  | \<regionName\>/cloud/\<cloudName\>/class    | "Cloud\<basicKinematicCollidingParcel\>"
| int     | \<regionName\>/cloud/\<cloudName\>/nParcels | total count (sum of corresponding variable)
| int     | \<regionName\>/cloud/\<cloudName\>/min-size | 238 (bytes)
| int     | \<regionName\>/cloud/\<cloudName\>/max-size | 380 (bytes)
| string[]| \<regionName\>/cloud/\<cloudName\>/names  | {"position", "cellI", "faceI", "stepFraction", "tetFaceI", "tetPtI", "origProc", "origId", "active", "typeId", "nParticle", "d", "dTarget", "U", "rho", "age", "tTurb", "UTurb", "f", "angularMomentum", "torque", "*"}
| string[]| \<regionName\>/cloud/\<cloudName\>/types  | {"vector", "label", "label", "scalar", "label", "label", "label", "label", "label", "label", "scalar", "scalar", "scalar", "vector", "scalar", "scalar", "scalar", "vector", "vector", "vector", "vector", "*"}
| int[]   | \<regionName\>/cloud/\<cloudName\>/offset | {1, 25, 29, 33, 41, 45, 49, 53, 59, 63, 67, 75, 83, 91, 115, 123, 131, 139, 165, 189, 213, 238}
| int[]   | \<regionName\>/cloud/\<cloudName\>/byte-size | {24, 4, 4, 8, 4, 4, 4, 4, 4, 4, 8, 8, 8, 24, 8, 8, 8, 24, 24, 24, 24, 0}


The following pseudocode illustrates a possible means of traversing
the parcel content:

    get cloud attributes
    if max-size != min-size
        read "sizes" variable

    read cloud binary stream
    offset = 1    # leading '('
    for each parcel
        nbytes  = sizes ? sizes[parcel] : min-size
        encoded = stream[offset, offset + nbytes]
        offset += nbytes

        decode parcel content
278 279

---