Skip to content

Commit bb7da4e

Browse files
committed
Gnomonic Projection - Advection
1 parent d359c5b commit bb7da4e

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

src/pmpo_wachspressBasis.hpp

Lines changed: 65 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,63 @@ void compute2DplanarTriangleArea(int numVtx,
363363
const Kokkos::View<double[maxVtxsPerElm][2], Kokkos::LayoutStride, Kokkos::MemoryTraits<Kokkos::Unmanaged>>& gnom_vtx_subview,
364364
double mpProjX, double mpProjY, double* basis){
365365

366+
// Temporary storage
367+
double vertCoords[2][maxVtxsPerElm + 1];
368+
for (int i = 0; i < numVtx; ++i) {
369+
vertCoords[0][i] = gnom_vtx_subview(i, 0);
370+
vertCoords[1][i] = gnom_vtx_subview(i, 1);
371+
}
372+
vertCoords[0][numVtx] = vertCoords[0][0];
373+
vertCoords[1][numVtx] = vertCoords[1][0];
374+
375+
//Helper lambda for signed triangle area
376+
auto triArea = [&](const double p1[2], const double p2[2], const double p3[2]) -> double {
377+
return 0.5 * (p1[0] * (p2[1] - p3[1]) - p2[0] * (p1[1] - p3[1]) + p3[0] * (p1[1] - p2[1]));
378+
};
379+
380+
// Compute areaV and areaXV
381+
double areaV[maxVtxsPerElm];
382+
double areaXV[maxVtxsPerElm];
383+
double xy[2] = { mpProjX, mpProjY };
384+
385+
//Special case
386+
double p1[2] = { vertCoords[0][numVtx - 1], vertCoords[1][numVtx - 1] };
387+
double p2[2] = { vertCoords[0][0], vertCoords[1][0] };
388+
double p3[2] = { vertCoords[0][1], vertCoords[1][1] };
389+
areaV[0] = triArea(p1, p2, p3);
390+
double q1[2] = { vertCoords[0][0], vertCoords[1][0] };
391+
double q2[2] = { xy[0], xy[1] };
392+
double q3[2] = { vertCoords[0][1], vertCoords[1][1] };
393+
areaXV[0] = triArea(q1, q2, q3);
394+
395+
for (int i = 1; i < numVtx; ++i) {
396+
double p1[2] = { vertCoords[0][i - 1], vertCoords[1][i - 1] };
397+
double p2[2] = { vertCoords[0][i], vertCoords[1][i] };
398+
double p3[2] = { vertCoords[0][i + 1], vertCoords[1][i + 1] };
399+
areaV[i] = triArea(p1, p2, p3);
400+
double q1[2] = { vertCoords[0][i], vertCoords[1][i] };
401+
double q2[2] = { xy[0], xy[1] };
402+
double q3[2] = { vertCoords[0][i + 1], vertCoords[1][i + 1] };
403+
areaXV[i] = triArea(q1, q2, q3);
404+
}
405+
406+
// Compute Wachspress-like weights
407+
double denominator = 0.0;
408+
for (int i = 0; i < numVtx; ++i){
409+
double product = areaV[i];
410+
for (int j = 0; j < numVtx - 2; ++j) {
411+
int ind1 = (i + j + 1) % numVtx;
412+
product *= areaXV[ind1];
413+
}
414+
basis[i] = product;
415+
denominator += product;
416+
}
417+
418+
// Normalize
419+
for (int i = 0; i < numVtx; ++i){
420+
basis[i] /= denominator;
421+
//printf("i %d basis %.15e \n", i, basis[i]);
422+
}
366423
}
367424

368425
inline void sphericalInterpolationDispVelIncr(MPMesh& mpMesh){
@@ -420,21 +477,24 @@ inline void sphericalInterpolationDispVelIncr(MPMesh& mpMesh){
420477
auto gnomProjElmCenter_sub = Kokkos::subview(gnomProjElmCenter, elm, Kokkos::ALL);
421478
computeGnomonicProjectionAtPoint(position3d, gnomProjElmCenter_sub, mpProjX, mpProjY);
422479
auto gnom_vtx_subview = Kokkos::subview(gnomProjVtx, elm, Kokkos::ALL, Kokkos::ALL);
423-
double basisbyArea2D[maxVtxsPerElm] = {0.0};
424-
compute2DplanarTriangleArea(numVtx, gnom_vtx_subview, mpProjX, mpProjY, basisbyArea2D);
425-
480+
double basisByArea2D[maxVtxsPerElm] = {0.0};
481+
482+
compute2DplanarTriangleArea(numVtx, gnom_vtx_subview, mpProjX, mpProjY, basisByArea2D);
483+
426484
for(int entry=0; entry<numEntries1; entry++){
427485
double mpValue = 0.0;
428486
for(int i=1; i<= numVtx; i++){
429-
mpValue += meshField1(elm2VtxConn(elm,i)-1,entry)*basisByArea3d[i-1];
487+
//mpValue += meshField1(elm2VtxConn(elm,i)-1,entry)*basisByArea3d[i-1];
488+
mpValue += meshField1(elm2VtxConn(elm,i)-1,entry)*basisByArea2D[i-1];
430489
}
431490
mpField1(mp,entry) = mpValue;
432491
}
433492

434493
for(int entry=0; entry<numEntries2; entry++){
435494
double mpValue = 0.0;
436495
for(int i=1; i<= numVtx; i++){
437-
mpValue += meshField2(elm2VtxConn(elm,i)-1,entry)*basisByArea3d[i-1];
496+
//mpValue += meshField2(elm2VtxConn(elm,i)-1,entry)*basisByArea3d[i-1];
497+
mpValue += meshField2(elm2VtxConn(elm,i)-1,entry)*basisByArea2D[i-1];
438498
}
439499
mpField2(mp,entry) = mpValue;
440500
}

0 commit comments

Comments
 (0)