Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
930ae9d
Parallel reconstruction
dhyan1272 Aug 22, 2025
e0452c1
Templated parameter not required
dhyan1272 Aug 22, 2025
5c4d42b
Timers updated
dhyan1272 Aug 25, 2025
adbff4f
Sending cell counts to neighbouring procs, collecting cell countsfrom…
dhyan1272 Aug 29, 2025
5f1045f
Sending and receiving 4 ints
dhyan1272 Sep 2, 2025
ac55908
Some more updates
dhyan1272 Sep 4, 2025
45030a1
Missing bracket
dhyan1272 Sep 5, 2025
8352108
Send gloablIds of haloCells To Owners
dhyan1272 Sep 8, 2025
6410755
HaloToOwners gets localId of the owners
dhyan1272 Sep 8, 2025
1fe2f41
OwnerToHalo Mapping
dhyan1272 Sep 9, 2025
0fdfcd7
One time arrays created
dhyan1272 Sep 9, 2025
25b6fd4
Gather working
dhyan1272 Sep 11, 2025
5aef1c5
Gather and scatter operations
dhyan1272 Sep 12, 2025
d7d466b
Couple of more specific debugs for the 2562 mesh
dhyan1272 Sep 12, 2025
685349e
Working 4 proc 2562 mesh case
dhyan1272 Sep 15, 2025
7e48e47
Removed Duplicate meshField
dhyan1272 Sep 15, 2025
238b37f
Modularized assembly per process, then communicate, and then take con…
dhyan1272 Sep 17, 2025
e28a1fb
Matrix formualtion within MPI communication within polyMPO
dhyan1272 Sep 18, 2025
92937fc
Cleanup
dhyan1272 Sep 18, 2025
9f8bbdd
Keep debugging statements using polyMPO::MP_DEBUG
dhyan1272 Sep 18, 2025
501a5ed
Removed pair<int, int>, instead 2 vectors storing ownerOwnerLocalIDs …
dhyan1272 Sep 19, 2025
b50a5ed
std::copy instead of for loop, intilaize to 0 and some formatting
dhyan1272 Sep 19, 2025
b406e85
Added timers
dhyan1272 Sep 22, 2025
e1555a2
Timers with processID
dhyan1272 Sep 23, 2025
1aac185
Fence before timers
dhyan1272 Sep 24, 2025
9e7a093
Bug in tracking for multi-CPU, out of bounds error
dhyan1272 Oct 3, 2025
89adb70
Starting gnomonic projection in polyMPO
dhyan1272 Oct 7, 2025
d359c5b
Checked gnomonic projection of MPs, vertices
dhyan1272 Oct 8, 2025
bb7da4e
Gnomonic Projection - Advection
dhyan1272 Oct 13, 2025
c0fbe6a
Clean up and option to use 2D/3D basis functions
dhyan1272 Oct 14, 2025
abc23be
New regularization and matrix inversion
dhyan1272 Oct 28, 2025
b45c37b
With Debugging statements
dhyan1272 Nov 6, 2025
da48034
Matrix inversion, Chad's fork
dhyan1272 Nov 19, 2025
a5ea31a
Removed old routines that does reconstruction assembly in MPAS
dhyan1272 Nov 21, 2025
36837b3
RotatedFlag in p_mesh
dhyan1272 Nov 26, 2025
2010d21
Removed warnings
dhyan1272 Nov 26, 2025
1939c58
Remove cudaDeviceSynchronize check for github automatic testing
dhyan1272 Nov 26, 2025
9d039ff
Replace max by Kokkos::max inside kernels
dhyan1272 Nov 26, 2025
dd91008
All ctests pass
dhyan1272 Nov 26, 2025
f881586
All ctests pass (MP rec test bot done)
dhyan1272 Nov 26, 2025
5b3d76e
Strain Rate at MP calcualtion
dhyan1272 Dec 15, 2025
9cdbde5
CleanUp_v1
dhyan1272 Dec 15, 2025
f58ddb6
CleanUp_v2
dhyan1272 Dec 15, 2025
533c8ab
CleanUp_v3
dhyan1272 Dec 16, 2025
8ea47ec
CleanUp_v4
dhyan1272 Dec 16, 2025
59f056a
CleanUp_v5
dhyan1272 Dec 18, 2025
189d00a
Ctests passing in remus
dhyan1272 Dec 22, 2025
3935c5b
A couple of comments in the tests
dhyan1272 Dec 22, 2025
44d1f40
CleanUp for PR_v1
dhyan1272 Dec 22, 2025
5856e02
CleanUp for PR_v2
dhyan1272 Dec 22, 2025
7635543
CleanUp for PR_v3
dhyan1272 Dec 23, 2025
0ca0073
CleanUp for PR_v4
dhyan1272 Dec 23, 2025
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
271 changes: 176 additions & 95 deletions src/pmpo_MPMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,42 +7,125 @@ namespace polyMPO{

void printVTP_mesh(MPMesh& mpMesh, int printVTPIndex=-1);

void MPMesh::calcBasis() {
assert(p_mesh->getGeomType() == geom_spherical_surf);
auto MPsPosition = p_MPs->getPositions();
auto mp_basis_field = p_MPs->getData<MPF_Basis_Vals>(); // we can implement MPs->getBasisVals() like MPs->getPositions()
auto elm2VtxConn = p_mesh->getElm2VtxConn();
auto vtxCoords = p_mesh->getMeshField<MeshF_VtxCoords>();
double radius = p_mesh->getSphereRadius();

auto calcbasis = PS_LAMBDA(const int& elm, const int& mp, const int& mask) {
if(mask) { //if material point is 'active'/'enabled'
Vec3d position3d(MPsPosition(mp,0),MPsPosition(mp,1),MPsPosition(mp,2));
// formating
Vec3d v3d[maxVtxsPerElm+1];
int numVtx = elm2VtxConn(elm,0);
for(int i = 1; i<=numVtx; i++){
v3d[i-1][0] = vtxCoords(elm2VtxConn(elm,i)-1,0);
v3d[i-1][1] = vtxCoords(elm2VtxConn(elm,i)-1,1);
v3d[i-1][2] = vtxCoords(elm2VtxConn(elm,i)-1,2);
}
v3d[numVtx][0] = vtxCoords(elm2VtxConn(elm,1)-1,0);
v3d[numVtx][1] = vtxCoords(elm2VtxConn(elm,1)-1,1);
v3d[numVtx][2] = vtxCoords(elm2VtxConn(elm,1)-1,2);

double basisByArea3d[maxVtxsPerElm] = {0.0};
initArray(basisByArea3d,maxVtxsPerElm,0.0);
void MPMesh::calculateStrain(){
auto MPsPosition = p_MPs->getPositions();
auto MPsBasis = p_MPs->getData<MPF_Basis_Vals>();
auto MPsAppID = p_MPs->getData<MPF_MP_APP_ID>();

//Mesh Fields
auto tanLatVertexRotatedOverRadius = p_mesh->getMeshField<MeshF_TanLatVertexRotatedOverRadius>();
auto gnomProjVtx = p_mesh->getMeshField<MeshF_VtxGnomProj>();
auto gnomProjElmCenter = p_mesh->getMeshField<MeshF_ElmCenterGnomProj>();
auto elm2VtxConn = p_mesh->getElm2VtxConn();
auto velField = p_mesh->getMeshField<MeshF_Vel>();
double radius = 1.0;
if(p_mesh->getGeomType() == geom_spherical_surf)
radius=p_mesh->getSphereRadius();

bool isRotated = p_mesh->getRotatedFlag();

auto setMPStrainRate = PS_LAMBDA(const int& elm, const int& mp, const int& mask){
if(mask){
int numVtx = elm2VtxConn(elm,0);

Vec3d position3d(MPsPosition(mp,0),MPsPosition(mp,1),MPsPosition(mp,2));
if(isRotated){
position3d[0] = -MPsPosition(mp, 2);
position3d[2] = MPsPosition(mp, 0);
}
auto gnomProjElmCenter_sub = Kokkos::subview(gnomProjElmCenter, elm, Kokkos::ALL);
double mpProjX, mpProjY;
computeGnomonicProjectionAtPoint(position3d, gnomProjElmCenter_sub, mpProjX, mpProjY);
auto gnom_vtx_subview = Kokkos::subview(gnomProjVtx, elm, Kokkos::ALL, Kokkos::ALL);

double basisByArea[maxVtxsPerElm] = {0.0};
initArray(basisByArea,maxVtxsPerElm,0.0);
double gradBasisByArea[2*maxVtxsPerElm] = {0.0};
initArray(gradBasisByArea,maxVtxsPerElm,0.0);

wachpress_weights_grads_2D(numVtx, gnom_vtx_subview, mpProjX, mpProjY, radius, basisByArea, gradBasisByArea);

double v11 = 0.0;
double v12 = 0.0;
double v21 = 0.0;
double v22 = 0.0;
double uTanOverR = 0.0;
double vTanOverR = 0.0;
for (int i = 0; i < numVtx; i++){
int iVertex = elm2VtxConn(elm, i+1)-1;
v11 = v11 + gradBasisByArea[i*2 + 0] * velField(iVertex, 0);
v12 = v12 + gradBasisByArea[i*2 + 1] * velField(iVertex, 0);
v21 = v21 + gradBasisByArea[i*2 + 0] * velField(iVertex, 1);
v22 = v22 + gradBasisByArea[i*2 + 1] * velField(iVertex, 1);
uTanOverR = uTanOverR + basisByArea[i] * tanLatVertexRotatedOverRadius(iVertex, 0) * velField(iVertex, 0);
vTanOverR = vTanOverR + basisByArea[i] * tanLatVertexRotatedOverRadius(iVertex, 0) * velField(iVertex, 1);
}
}
};
p_MPs->parallel_for(setMPStrainRate, "setMPStrainRate");
}

// calc basis
getBasisByAreaGblFormSpherical(position3d, numVtx, v3d, radius, basisByArea3d);

// fill step
for(int i=0; i<= numVtx; i++){
mp_basis_field(mp,i) = basisByArea3d[i];
}
}
};
p_MPs->parallel_for(calcbasis, "calcbasis");
void MPMesh::calcBasis() {
assert(p_mesh->getGeomType() == geom_spherical_surf);

auto MPsPosition = p_MPs->getPositions();
auto MPsBasis = p_MPs->getData<MPF_Basis_Vals>();
auto MPsAppID = p_MPs->getData<MPF_MP_APP_ID>();

auto elm2VtxConn = p_mesh->getElm2VtxConn();
auto vtxCoords = p_mesh->getMeshField<MeshF_VtxCoords>();
double radius = 1.0;
if(p_mesh->getGeomType() == geom_spherical_surf)
radius=p_mesh->getSphereRadius();

//For Gnomonic Projection
auto gnomProjVtx = p_mesh->getMeshField<polyMPO::MeshF_VtxGnomProj>();
auto gnomProjElmCenter = p_mesh->getMeshField<polyMPO::MeshF_ElmCenterGnomProj>();

bool isRotated = p_mesh->getRotatedFlag();

auto calcbasis = PS_LAMBDA(const int& elm, const int& mp, const int& mask) {
if(mask) { //if material point is 'active'/'enabled'
int numVtx = elm2VtxConn(elm,0);
Vec3d position3d(MPsPosition(mp, 0),MPsPosition(mp, 1),MPsPosition(mp, 2));
if(isRotated){
position3d[0] = -MPsPosition(mp, 2);
position3d[2] = MPsPosition(mp, 0);
}

double mpProjX, mpProjY;
auto gnomProjElmCenter_sub = Kokkos::subview(gnomProjElmCenter, elm, Kokkos::ALL);
computeGnomonicProjectionAtPoint(position3d, gnomProjElmCenter_sub, mpProjX, mpProjY);
auto gnom_vtx_subview = Kokkos::subview(gnomProjVtx, elm, Kokkos::ALL, Kokkos::ALL);

double basisByArea[maxVtxsPerElm] = {0.0};
initArray(basisByArea,maxVtxsPerElm, 0.0);
double gradBasisByArea[2*maxVtxsPerElm] = {0.0};
initArray(gradBasisByArea,maxVtxsPerElm, 0.0);

wachpress_weights_grads_2D(numVtx, gnom_vtx_subview, mpProjX, mpProjY, radius, basisByArea, gradBasisByArea);

for(int i=0; i<= numVtx; i++){
MPsBasis(mp,i) = basisByArea[i];
}

//Old method where basis functions calculated using 3D Area
/*
Vec3d v3d[maxVtxsPerElm+1];
int numVtx = elm2VtxConn(elm,0);
for(int i = 1; i<=numVtx; i++){
v3d[i-1][0] = vtxCoords(elm2VtxConn(elm,i)-1,0);
v3d[i-1][1] = vtxCoords(elm2VtxConn(elm,i)-1,1);
v3d[i-1][2] = vtxCoords(elm2VtxConn(elm,i)-1,2);
}
v3d[numVtx][0] = vtxCoords(elm2VtxConn(elm,1)-1,0);
v3d[numVtx][1] = vtxCoords(elm2VtxConn(elm,1)-1,1);
v3d[numVtx][2] = vtxCoords(elm2VtxConn(elm,1)-1,2);
getBasisByAreaGblFormSpherical(position3d, numVtx, v3d, radius, basisByArea);
*/
}
};
p_MPs->parallel_for(calcbasis, "calcbasis");
}

void MPMesh::CVTTrackingEdgeCenterBased(Vec2dView dx){
Expand All @@ -51,10 +134,10 @@ void MPMesh::CVTTrackingEdgeCenterBased(Vec2dView dx){
auto elm2VtxConn = p_mesh->getElm2VtxConn();
auto elm2ElmConn = p_mesh->getElm2ElmConn();
auto MPs2Elm = p_MPs->getData<MPF_Tgt_Elm_ID>();
const auto vtxCoords = p_mesh->getMeshField<polyMPO::MeshF_VtxCoords>();
const auto vtxCoords = p_mesh->getMeshField<polyMPO::MeshF_VtxCoords>();
auto mpPositions = p_MPs->getData<MPF_Cur_Pos_XYZ>();
Kokkos::View<Vec2d*[maxVtxsPerElm]> edgeCenters("EdgeCenters",numElms);

Kokkos::parallel_for("calcEdgeCenter", numElms, KOKKOS_LAMBDA(const int elm){
int numVtx = elm2VtxConn(elm,0);
int v[maxVtxsPerElm];
Expand All @@ -67,7 +150,7 @@ void MPMesh::CVTTrackingEdgeCenterBased(Vec2dView dx){
edgeCenters(elm,i) = (v_ip1 + v_i)*0.5;
}
});

auto CVTEdgeTracking = PS_LAMBDA(const int& elm, const int& mp, const int& mask){
Vec2d MP(mpPositions(mp,0),mpPositions(mp,1));//XXX:the input is XYZ, but we only support 2d vector
if(mask){
Expand All @@ -90,7 +173,7 @@ void MPMesh::CVTTrackingEdgeCenterBased(Vec2dView dx){
}
if(currentDistSq < minDistSq){
edgeIndex = i+1;
minDistSq = currentDistSq;
minDistSq = currentDistSq;
}
}
if(edgeIndex <0){
Expand Down Expand Up @@ -149,13 +232,14 @@ void MPMesh::CVTTrackingElmCenterBased(const int printVTPIndex){

Vec3d center(elmCenter(iElm, 0), elmCenter(iElm, 1), elmCenter(iElm, 2));
Vec3d delta = MPnew - center;

double minDistSq = delta[0]*delta[0] + delta[1]*delta[1] + delta[2]*delta[2];
int closestElm = -1;
//go through all the connected elm, calc distance
for(int i=1; i<=numConnElms; i++){
int elmID = elm2ElmConn(iElm,i)-1;

if (elmID >= numElms)
continue;
//New delta
Vec3d center(elmCenter(elmID, 0), elmCenter(elmID, 1), elmCenter(elmID, 2));
delta = MPnew - center;
Expand Down Expand Up @@ -243,7 +327,7 @@ void MPMesh::T2LTracking(Vec2dView dx){
auto mpPositions = p_MPs->getData<MPF_Cur_Pos_XYZ>();
auto MPs2Elm = p_MPs->getData<MPF_Tgt_Elm_ID>();
auto mpStatus = p_MPs->getData<MPF_Status>();

auto T2LCalc = PS_LAMBDA(const int& elm, const int& mp, const int&mask){
Vec2d MP(mpPositions(mp,0),mpPositions(mp,1));//XXX:the input is XYZ, but we only support 2d vector
if(mask){
Expand Down Expand Up @@ -299,15 +383,13 @@ void MPMesh::T2LTracking(Vec2dView dx){
}

void MPMesh::reconstructSlices() {
if (reconstructSlice.size() == 0) return;
Kokkos::Timer timer;
calcBasis();
resetPreComputeFlag();
for (auto const& [index, reconstruct] : reconstructSlice) {
if (reconstruct) reconstruct();
}
reconstructSlice.clear();
pumipic::RecordTime("PolyMPO_Reconstruct", timer.seconds());
if (reconstructSlice.size() == 0) return;
Kokkos::Timer timer;
for (auto const& [index, reconstruct] : reconstructSlice) {
if (reconstruct) reconstruct();
}
reconstructSlice.clear();
pumipic::RecordTime("PolyMPO_Reconstruct", timer.seconds());
}

bool getAnyIsMigrating(MaterialPoints* p_MPs, bool isMigrating) {
Expand All @@ -329,12 +411,13 @@ void MPMesh::push_ahead(){
//Latitude Longitude increment at mesh vertices and interpolate to particle position
p_mesh->computeRotLatLonIncr();

//Interpolates latitude longitude increments and mesh velocity increments to
//MP positions
sphericalInterpolationDispVelIncr(*this);
//Interpolates latitude longitude, mesh velocity increments to MPs
calcBasis();
sphericalInterpolation<MeshF_RotLatLonIncr>(*this);
sphericalInterpolation<MeshF_OnSurfVeloIncr>(*this);

//Push the MPs
p_MPs->updateRotLatLonAndXYZ2Tgt(p_mesh->getSphereRadius());
p_MPs->updateRotLatLonAndXYZ2Tgt(p_mesh->getSphereRadius(), p_mesh->getRotatedFlag());
pumipic::RecordTime("PolyMPO_interpolateAndPush", timer.seconds());
}

Expand All @@ -361,16 +444,14 @@ void MPMesh::push_swap_pos(){
p_MPs->updateMPSlice<MPF_Cur_Pos_Rot_Lat_Lon, MPF_Tgt_Pos_Rot_Lat_Lon>();
}


void MPMesh::push(){

void MPMesh::push(){
Kokkos::Timer timer;

p_mesh->computeRotLatLonIncr();

sphericalInterpolation<MeshF_RotLatLonIncr>(*this);

p_MPs->updateRotLatLonAndXYZ2Tgt(p_mesh->getSphereRadius()); // set Tgt_XYZ
p_MPs->updateRotLatLonAndXYZ2Tgt(p_mesh->getSphereRadius(), p_mesh->getRotatedFlag());

auto elm2Process = p_mesh->getElm2Process();

Expand All @@ -396,43 +477,43 @@ void MPMesh::push(){
}

void MPMesh::printVTP_mesh(int printVTPIndex){
auto vtxCoords = p_mesh->getMeshField<polyMPO::MeshF_VtxCoords>();
auto elm2VtxConn = p_mesh->getElm2VtxConn();

auto MPsPosition = p_MPs->getPositions();

char* fileOutput = (char *)malloc(sizeof(char) * 256);
sprintf(fileOutput,"polyMPO_MPMesh_mesh_%d.vtp", printVTPIndex);
FILE * pFile = fopen(fileOutput,"w");
free(fileOutput);

auto h_vtxCoords = Kokkos::create_mirror_view(vtxCoords);
IntVtx2ElmView::HostMirror h_elm2VtxConn = Kokkos::create_mirror_view(elm2VtxConn);
const int nCells = p_mesh->getNumElements();
const int nVertices = p_mesh->getNumVertices();
Kokkos::deep_copy(h_vtxCoords,vtxCoords);
Kokkos::deep_copy(h_elm2VtxConn,elm2VtxConn);
fprintf(pFile, "<VTKFile type=\"PolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n <PolyData>\n <Piece NumberOfPoints=\"%d\" NumberOfVerts=\"0\" NumberOfLines=\"0\" NumberOfStrips=\"0\" NumberOfPolys=\"%d\">\n <Points>\n <DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\">\n",nVertices,nCells);
for(int i=0; i<nVertices; i++){
fprintf(pFile, " %f %f %f\n",h_vtxCoords(i,0),h_vtxCoords(i,1),h_vtxCoords(i,2));
}
fprintf(pFile, " </DataArray>\n </Points>\n <Polys>\n <DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\">\n");
for(int i=0; i<nCells; i++){
fprintf(pFile, " ");
for(int j=0; j< h_elm2VtxConn(i,0); j++){
fprintf(pFile, "%d ", h_elm2VtxConn(i,j+1)-1);
}
fprintf(pFile, "\n");
}
fprintf(pFile, " </DataArray>\n <DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">\n");
auto vtxCoords = p_mesh->getMeshField<polyMPO::MeshF_VtxCoords>();
auto elm2VtxConn = p_mesh->getElm2VtxConn();

auto MPsPosition = p_MPs->getPositions();

char* fileOutput = (char *)malloc(sizeof(char) * 256);
sprintf(fileOutput,"polyMPO_MPMesh_mesh_%d.vtp", printVTPIndex);
FILE * pFile = fopen(fileOutput,"w");
free(fileOutput);

auto h_vtxCoords = Kokkos::create_mirror_view(vtxCoords);
IntVtx2ElmView::HostMirror h_elm2VtxConn = Kokkos::create_mirror_view(elm2VtxConn);
const int nCells = p_mesh->getNumElements();
const int nVertices = p_mesh->getNumVertices();
Kokkos::deep_copy(h_vtxCoords,vtxCoords);
Kokkos::deep_copy(h_elm2VtxConn,elm2VtxConn);
fprintf(pFile, "<VTKFile type=\"PolyData\" version=\"1.0\" byte_order=\"LittleEndian\" header_type=\"UInt64\">\n <PolyData>\n <Piece NumberOfPoints=\"%d\" NumberOfVerts=\"0\" NumberOfLines=\"0\" NumberOfStrips=\"0\" NumberOfPolys=\"%d\">\n <Points>\n <DataArray type=\"Float32\" Name=\"Points\" NumberOfComponents=\"3\" format=\"ascii\">\n",nVertices,nCells);
for(int i=0; i<nVertices; i++){
fprintf(pFile, " %f %f %f\n",h_vtxCoords(i,0),h_vtxCoords(i,1),h_vtxCoords(i,2));
}
fprintf(pFile, " </DataArray>\n </Points>\n <Polys>\n <DataArray type=\"Int64\" Name=\"connectivity\" format=\"ascii\">\n");
for(int i=0; i<nCells; i++){
fprintf(pFile, " ");
for(int j=0; j< h_elm2VtxConn(i,0); j++){
fprintf(pFile, "%d ", h_elm2VtxConn(i,j+1)-1);
}
fprintf(pFile, "\n");
}
fprintf(pFile, " </DataArray>\n <DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">\n");

int count = 0;
for(int i=0;i<nCells; i++){
count += h_elm2VtxConn(i,0);
fprintf(pFile, " %d\n",count);
}
fprintf(pFile, " </DataArray>\n </Polys>\n </Piece>\n </PolyData>\n</VTKFile>\n");
fclose(pFile);
int count = 0;
for(int i=0;i<nCells; i++){
count += h_elm2VtxConn(i,0);
fprintf(pFile, " %d\n",count);
}
fprintf(pFile, " </DataArray>\n </Polys>\n </Piece>\n </PolyData>\n</VTKFile>\n");
fclose(pFile);
}

}
Loading