|
1 | 1 | /*! |
2 | 2 | * @file DynamicsKernel.hpp |
3 | 3 | * |
4 | | - * @date Jan 5, 2024 |
| 4 | + * @date 21 Feb 2025 |
5 | 5 | * @author Tim Spain <[email protected]> |
6 | 6 | */ |
7 | 7 |
|
@@ -53,9 +53,9 @@ template <int DGadvection, int DGstress> class DynamicsKernel { |
53 | 53 | smesh->RotatePoleToGreenland(); |
54 | 54 | smesh->landmaskFromModelArray(mask); |
55 | 55 | smesh->dirichletFromMask(); |
56 | | - // TODO: handle periodic and open edges |
57 | | - for (ParametricMesh::Edge edge : ParametricMesh::edges) { |
58 | | - smesh->dirichletFromEdge(edge); |
| 56 | + // TODO: handle periodic edges |
| 57 | + for (const ParametricMesh::Edge edge : ParametricMesh::edges) { |
| 58 | + smesh->neumannFromEdge(edge); |
59 | 59 | } |
60 | 60 |
|
61 | 61 | //! Initialize transport |
@@ -180,6 +180,9 @@ template <int DGadvection, int DGstress> class DynamicsKernel { |
180 | 180 | Nextsim::LimitMax(cice, 1.0); |
181 | 181 | Nextsim::LimitMin(cice, 0.0); |
182 | 182 | Nextsim::LimitMin(hice, 0.0); |
| 183 | + |
| 184 | + neumannZero(cice); |
| 185 | + neumannZero(hice); |
183 | 186 | } |
184 | 187 |
|
185 | 188 | protected: |
@@ -232,6 +235,39 @@ template <int DGadvection, int DGstress> class DynamicsKernel { |
232 | 235 | */ |
233 | 236 | virtual void prepareAdvection() = 0; |
234 | 237 |
|
| 238 | + template <int DG> void neumannZero(DGVector<DG>& v) const |
| 239 | + { |
| 240 | + // the four segments bottom, right, top, left, are each processed in parallel |
| 241 | + for (size_t seg = 0; seg < 4; ++seg) { |
| 242 | +#pragma omp parallel for |
| 243 | + for (size_t i = 0; i < smesh->neumann[seg].size(); ++i) { |
| 244 | + |
| 245 | + const size_t eid = smesh->neumann[seg][i]; |
| 246 | + const size_t ix = eid % smesh->nx; // compute coordinates of element |
| 247 | + const size_t iy = eid / smesh->nx; |
| 248 | + |
| 249 | + switch (seg) { |
| 250 | + case 0: // bottom <= top |
| 251 | + for (size_t j = 0; j < DG; ++j) |
| 252 | + v(iy * smesh->nx + ix, j) = v((iy + 1) * smesh->nx + ix, j); |
| 253 | + break; |
| 254 | + case 1: // right <= left |
| 255 | + for (size_t j = 0; j < DG; ++j) |
| 256 | + v(iy * smesh->nx + ix, j) = v(iy * smesh->nx + ix - 1, j); |
| 257 | + break; |
| 258 | + case 2: // top <= bottom |
| 259 | + for (size_t j = 0; j < DG; ++j) |
| 260 | + v(iy * smesh->nx + ix, j) = v((iy - 1) * smesh->nx + ix, j); |
| 261 | + break; |
| 262 | + case 3: // left <= right |
| 263 | + for (size_t j = 0; j < DG; ++j) |
| 264 | + v(iy * smesh->nx + ix, j) = v(iy * smesh->nx + ix + 1, j); |
| 265 | + break; |
| 266 | + } |
| 267 | + } |
| 268 | + } |
| 269 | + } |
| 270 | + |
235 | 271 | private: |
236 | 272 | std::unordered_map<std::string, DGVector<DGadvection>> advectedFields; |
237 | 273 |
|
|
0 commit comments