Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Mesh class #48

Merged
merged 38 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
17a04bf
Begin adding HorzMesh class
sbrus89 Jan 11, 2024
37abbee
Add cell coordinate read
sbrus89 Jan 11, 2024
6b09135
Add cell coordinate test
sbrus89 Jan 11, 2024
c22e797
Add edge and vertex coordinates read
sbrus89 Jan 12, 2024
3e129cc
Make readCoordinates method
sbrus89 Jan 12, 2024
0decadf
Fix indentation
sbrus89 Jan 12, 2024
74444f6
Read in bottomDepth
sbrus89 Jan 12, 2024
10bb309
Read in cell and triangle areas
sbrus89 Jan 12, 2024
4943262
Add dcEdge and dvEdge read
sbrus89 Jan 17, 2024
b5ddccb
Switch to reading using YAKL array data pointer
sbrus89 Jan 18, 2024
3d3c92b
Add Coriolis array reads
sbrus89 Jan 18, 2024
029b0bd
Add weightsOnEdge, kiteAreasOnVertex, and angleEdge
sbrus89 Jan 18, 2024
22e8dd5
Rearrage and comment
sbrus89 Jan 18, 2024
fb601f5
Fix rebase issues
sbrus89 Jan 19, 2024
df65ec8
Add copyToDevice method
sbrus89 Jan 19, 2024
39043f6
Add empty user and dev docs for HorzMesh
sbrus89 Jan 26, 2024
767dc07
Pre-commit clean-up
sbrus89 Jan 22, 2024
38f70b3
Clang-format modifications
sbrus89 Jan 22, 2024
01ef0e4
Include decomp header in HorzMesh.h
sbrus89 Jan 22, 2024
493e04c
Fix more pre-commit issues
sbrus89 Jan 23, 2024
780b80f
Fix whitespace issues
sbrus89 Jan 23, 2024
99a9da1
Add user and developer documentation
sbrus89 Jan 23, 2024
5633b40
Updates to test/CMakeLists.txt
sbrus89 Jan 26, 2024
2f5bff7
Add edge sign computations
sbrus89 Jan 26, 2024
fc5dfee
Fix pre-commit issues
sbrus89 Jan 26, 2024
e49d6ce
Fix duplicate device copy for connectivity arrays from Decomp
sbrus89 Jan 29, 2024
7501ef3
Add retrival functions
sbrus89 Jan 29, 2024
2790155
Add method to destroy parallel IO decomps
sbrus89 Jan 29, 2024
29e22fb
Fix pre-commit issues
sbrus89 Jan 29, 2024
bf0f6a8
Revise clear method and add erase
sbrus89 Jan 30, 2024
e8487a9
Update dev guide
sbrus89 Jan 30, 2024
2d1079a
Fix whitespace issues
sbrus89 Jan 30, 2024
f0ab170
Fix build errors
sbrus89 Jan 30, 2024
12b7f3a
Fix precommit issues
sbrus89 Jan 30, 2024
b3c934e
Make clear and erase methods static
sbrus89 Feb 2, 2024
7d2cb50
Fix array sizes and add halo test
sbrus89 Feb 2, 2024
8b97c96
Fix pre-commit issues
sbrus89 Feb 2, 2024
a683c59
Update to dev guide
sbrus89 Feb 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions components/omega/doc/design/HorzMeshClass.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(omega-design-horz-mesh)=
# Horizontal Mesh
# Horizontal Mesh

## 1 Overview

Expand All @@ -13,7 +13,7 @@ The OMEGA mesh information should be compatible with the [MPAS Mesh Specificatio

### 2.2 Requirement: Functionality is needed to read the mesh on the host and transfer relevant data to the device for computation

Not all mesh information is required in computing the tendency terms on the device, e.g. lonCell, latCell, etc.
Not all mesh information is required in computing the tendency terms on the device, e.g. lonCell, latCell, etc.
However, other arrays will need to be allocated and copied to the device for use in tendency computation.
The mesh class will explicitly include host and device YAKL arrays for each variable.
A class method will be included to copy the relevant mesh information to the device.
Expand All @@ -26,13 +26,13 @@ Although the existing MPAS Mesh spec uses a one-based mesh numbering, zero-based

The mesh class will reference the partitioned connectivity arrays created by the Decomp class.

### 2.5 Requirement: Mesh variables will be associated with metadata to describe data
### 2.5 Requirement: Mesh variables will be associated with metadata to describe data

Following the Metadata and IO designs, the YAKL arrays for the mesh variables will be associated with information about the represented values.

### 2.6 Requirement: I/O to obtain mesh data

The Mesh class will have a method to read in the mesh information not obtained by the Decomp class.
The Mesh class will have a method to read in the mesh information not obtained by the Decomp class.

### 2.7 Desired: Ability to support multiple independent mesh objects

Expand All @@ -42,13 +42,13 @@ Additionally, this flexibility can be used to support separate domain decomposit
### 2.8 Desired: OMEGA can read in a reduced number of mesh variables and compute the remaining array information online.

Many of the mesh variables are not independent, e.g. areaCell, weightsOnEdge, etc., and can be computed from a reduced set of mesh variables.
This functionality could be used to reduce mesh/restart file size for high resolution meshes.
This functionality could be used to reduce mesh/restart file size for high resolution meshes.
Building in this flexibility would allow for all mesh-related calculations to be available within the code base instead of spreading them amongst various utility programs in MPAS-Tools.
This will improve the ability to maintain and unit test the mesh calculations in MPAS-Tools.
The functions used to compute the dependent mesh information can also be used to verify any mesh information that is provided in the mesh input stream.

As standard practice, all necessary internally computed mesh information will be output in a single file for post-processing purposes.
A checksumming strategy will be implemented to avoid situations where simulation data and mesh information are mismatched during post processing.
A checksumming strategy will be implemented to avoid situations where simulation data and mesh information are mismatched during post processing.

Where appropriate, some additional derived quantities (e.g. reciprocals) will also be included to improve the performance of device-side calculations.

Expand Down Expand Up @@ -78,7 +78,7 @@ public:
Array1DR8 AreaCell;
ArrayHost1DR8 AreaCellH;

Array2DI4 CellsOnCell;
Array2DI4 CellsOnCell;
ArrayHost2DI4 CellsOnCellH;

}
Expand Down Expand Up @@ -106,7 +106,7 @@ A destructor will be available to release memory.
#### 4.2.2 Read
The mesh class requires a method to read in all other available mesh information that has been provided in the mesh file, but has not been initialized by the decomposition. This will be a private method called by the constructor.

#### 4.2.3 Compute
#### 4.2.3 Compute
The compute method will be a private method called by the constructor. It will be resonsible for calculating any dependent mesh information that is not provided in the mesh input file.

#### 4.2.4 Device copy creation
Expand All @@ -123,6 +123,6 @@ The metadata associated with each mesh variable will be registred within the I/O

## 5 Verification and Testing

### 5.1 Test mesh compute routines
### 5.1 Test mesh compute routines

The sample domain used for the Decomp test will be used to test obtaining the correct local values and the mesh computation routines.
55 changes: 55 additions & 0 deletions components/omega/doc/devGuide/HorzMesh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
(omega-dev-horz-mesh)=

## Horizontal Mesh

The OMEGA horizontal mesh uses the [MPAS Mesh
Specification](https://mpas-dev.github.io/files/documents/MPAS-MeshSpec.pdf).
A mesh object is created by the `init` method, which assumes that `Decomp` has
already been initialized.
```c++
Err = OMEGA::Decomp::init();
Err = OMEGA::HorzMesh::init();
```
The constructor replicates the subdomain mesh cell/edge/vertex counts and
connectivity information from Decomp so this information can be passed among the
computational routines, alongside the other local mesh information. It then
creates several parallel I/O decompositions and reads in the remaining subdomain
mesh information. Finally, any mesh information needed on the device is copied
from the host to a device YAKL array. Arrays such as the coordinate variables,
which are not involved in tendency calculations, are not transferred to the
device. These tasks are organized into several private methods. Eventually,
dependent mesh variables will be computed from the minimum set of required mesh
information.

After initialization, the default mesh object can be retrieved via:
```
OMEGA::HorzMesh *HMesh = OMEGA::HorzMesh::getDefault();
```
Once this retrieval has been performed, public member variables can be accessed
using:
```
OMEGA::I4 NCellsOwned = HMesh->NCellsOwned;
OMEGA::Array1DR8 AreaCell = HMesh->AreaCell;
```

The HorzMesh is meant to be a container that allows the mesh information to be
passed to the PDE solver routines:
```
void computeFluxTendency(OMEGA::HorzMesh *HMesh, ...) {
yakl::c::parallel_for(yakl::c::Bounds<2>(HMesh->NCellsOwned,HMesh->MaxEdges),
YAKL_LAMBDA (int Cell, int Edge) {
if (Edge < HMesh->NEdgesOnCell(Cell)) {
Var(Cell) = Var(Cell) + Flux(Cell,Edge);
}
}
```

For member variables that are host arrays, variable names are appended with an
`H`. Array variable names not ending in `H` are device arrays. The copy from
host to device array is performed in the constructor via:
```c++
AreaCell = AreaCellH.createDeviceCopy();
```

The device arrays are deallocated by the `HorzMesh::clear()` method, which is
necessary before calling `yakl::finalize`.
2 changes: 2 additions & 0 deletions components/omega/doc/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ userGuide/Logging
userGuide/Decomp
userGuide/IO
userGuide/Halo
userGuide/HorzMesh
```

```{toctree}
Expand All @@ -50,6 +51,7 @@ devGuide/Logging
devGuide/Decomp
devGuide/IO
devGuide/Halo
devGuide/HorzMesh
```

```{toctree}
Expand Down
43 changes: 43 additions & 0 deletions components/omega/doc/userGuide/HorzMesh.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
(omega-user-horz-mesh)=

## Horizontal Mesh

OMEGA uses the MPAS mesh specification found
[here](https://mpas-dev.github.io/files/documents/MPAS-MeshSpec.pdf). The names
of the mesh variables have been retained, with the caveat that they now begin
with a capital letter.

The Mesh class is meant to be a container for all mesh variables local to a
decomposed sub-domain that can be easily passed among the dycore routines. It
depends on a given [Decomp](#omega-user-decomp) and reproduces the
cell/edge/vertex totals and connectivity information from that class. The Mesh
class also creates parallel I/O decompositions that are used to read in the
additional mesh variables, which are not required for Decomp.

Currently, the Mesh class reads in all variables from the MPAS mesh
specification except those read by [Decomp](#omega-dev-decomp).
This includes the following variables:

| Variable Name | Description | Units |
| ------------- | ----------- | ----- |
| XCell, YCell, ZCell | Cartesian coordinates of cell centers | m |
| XEdge, YEdge, ZEdge | Cartesian coordinates of edge centers | m |
| XVertex, YVertex, ZVertex | Cartesian coordinates of vertices | m |
| BottomDepth | Depth of the bottom of the ocean at cell centers | m |
| FCell, FEdge, FVertex | Coriolis parameter at cell centers/edges/vertices | radians/s |
| LonCell, LatCell | Longitude/latitude coordinates of cell centers | radians |
| LonEdge, LatEdge | Longitude/latitude coordinates of edge centers | radians |
| LonVertex, LatVertex | Longitude/latitude coordinates of vertices | radians |
| AreaCell | Area of each cell | m^2 |
| AreaTriangle | Area of each triangle in the dual grid | m^2 |
| KiteAreasOnVertex | Area of the portions of each dual cell that are part of each cellsOnVertex | m^2 |
| DvEdge | Length of each edge, computed as the distance between verticesOnEdge | m |
| DcEdge | Length of each edge, computed as the distance between CellsOnEdge | m |
| AngleEdge | Angle the edge normal makes with local eastward direction | radians |
| MeshDensity | Value of density function used to generate a particular mesh at cell centers | - |
| WeightsOnEdge | Reconstruction weights associated with each of the edgesOnEdge | - |

In the future, the Mesh class will optionally compute the mesh variables that
are dependent on the Cartesian mesh coordinates internally.
This includes the various areas, lengths, angles, and weights needed for the
TRiSK discretization (e.g. rows 5-11 in the table above).
15 changes: 8 additions & 7 deletions components/omega/src/base/Decomp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -352,12 +352,12 @@ int Decomp::init() {
// NPart partitions of the mesh.

Decomp::Decomp(
const std::string &Name, //< [in] Name for new decomposition
const MachEnv *InEnv, //< [in] MachEnv for the new partition
I4 NParts, //< [in] num of partitions for new decomp
PartMethod Method, //< [in] method for partitioning
I4 InHaloWidth, //< [in] width of halo in new decomp
const std::string &MeshFileName //< [in] name of file with mesh info
const std::string &Name, //< [in] Name for new decomposition
const MachEnv *InEnv, //< [in] MachEnv for the new partition
I4 NParts, //< [in] num of partitions for new decomp
PartMethod Method, //< [in] method for partitioning
I4 InHaloWidth, //< [in] width of halo in new decomp
const std::string &MeshFileName_ //< [in] name of file with mesh info
) {

int Err = 0; // internal error code
Expand All @@ -371,7 +371,8 @@ Decomp::Decomp(

// Open the mesh file for reading (assume IO has already been initialized)
int FileID;
Err = IO::openFile(FileID, MeshFileName, IO::ModeRead);
MeshFileName = MeshFileName_;
Err = IO::openFile(FileID, MeshFileName, IO::ModeRead);
if (Err != 0)
LOG_CRITICAL("Decomp: error opening mesh file");

Expand Down
4 changes: 3 additions & 1 deletion components/omega/src/base/Decomp.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class Decomp {
// Since these are used frequently, we make them public to reduce the
// number of retrievals required.

std::string MeshFileName; ///< The name of the file with mesh info

// Sizes and global IDs
// Note that all sizes are actual counts (1-based) so that loop extents
// should always use the 0:NCellsXX-1 form.
Expand Down Expand Up @@ -226,7 +228,7 @@ class Decomp {
I4 NParts, ///< [in] num of partitions for new decomp
PartMethod Method, ///< [in] method for partitioning
I4 InHaloWidth, ///< [in] width of halo in new decomp
const std::string &MeshFileName ///< [in] name of file with mesh info
const std::string &MeshFileName_ ///< [in] name of file with mesh info
);

/// Destructor - deallocates all memory and deletes a Decomp.
Expand Down
Loading