399 DM swarm = user->
swarm;
401 PetscInt localNumParticles;
402 PetscReal *positions = NULL;
403 PetscInt64 *particleIDs = NULL;
404 PetscMPIInt *particleRanks = NULL;
405 PetscInt *cellIDs = NULL;
406 PetscReal *weights = NULL;
407 PetscReal *velocities = NULL;
410 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
413 ierr = DMSwarmGetLocalSize(swarm, &localNumParticles); CHKERRQ(ierr);
416 ierr = DMSwarmGetField(swarm,
"position", NULL, NULL, (
void**)&positions); CHKERRQ(ierr);
417 ierr = DMSwarmGetField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&particleIDs); CHKERRQ(ierr);
418 ierr = DMSwarmGetField(swarm,
"DMSwarm_rank", NULL, NULL, (
void**)&particleRanks); CHKERRQ(ierr);
419 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
420 ierr = DMSwarmGetField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
421 ierr = DMSwarmGetField(swarm,
"velocity", NULL, NULL, (
void**)&velocities); CHKERRQ(ierr);
424 int wRank, wPID, wCell, wPos, wVel, wWt;
425 wRank = wPID = wCell = wPos = wVel = wWt = 0;
427 positions, velocities, weights,
428 &wRank, &wPID, &wCell, &wPos, &wVel, &wWt); CHKERRQ(ierr);
433 BuildHeaderString(headerFmt,
sizeof(headerFmt), wRank, wPID, wCell, wPos, wVel, wWt);
437 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"--------------------------------------------------------------------------------------------------------------\n"); CHKERRQ(ierr);
438 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"%s", headerFmt); CHKERRQ(ierr);
439 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"--------------------------------------------------------------------------------------------------------------\n"); CHKERRQ(ierr);
443 for (PetscInt i = 0; i < localNumParticles; i++) {
444 if (i % printInterval == 0) {
488 snprintf(rowStr,
sizeof(rowStr), rowFmt,
495 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"%s", rowStr); CHKERRQ(ierr);
500 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"--------------------------------------------------------------------------------------------------------------\n"); CHKERRQ(ierr);
501 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"\n"); CHKERRQ(ierr);
502 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
507 ierr = DMSwarmRestoreField(swarm,
"position", NULL, NULL, (
void**)&positions); CHKERRQ(ierr);
508 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&particleIDs); CHKERRQ(ierr);
509 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_rank", NULL, NULL, (
void**)&particleRanks); CHKERRQ(ierr);
510 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
511 ierr = DMSwarmRestoreField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
512 ierr = DMSwarmRestoreField(swarm,
"velocity", NULL, NULL, (
void**)&velocities); CHKERRQ(ierr);
1369 PetscErrorCode ierr;
1373 Vec fieldVec = NULL;
1376 char data_layout[20];
1378 PetscFunctionBeginUser;
1381 if (strcasecmp(fieldName,
"Ucat") == 0) {
1382 fieldVec = user->
Ucat; dm = user->
fda; dof = 3; strcpy(data_layout,
"Cell-Centered");
1383 }
else if (strcasecmp(fieldName,
"P") == 0) {
1384 fieldVec = user->
P; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
1385 }
else if (strcasecmp(fieldName,
"Diffusivity") == 0) {
1386 fieldVec = user->
Diffusivity; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
1387 }
else if (strcasecmp(fieldName,
"DiffusivityGradient") == 0) {
1389 }
else if (strcasecmp(fieldName,
"Ucont") == 0) {
1390 fieldVec = user->
lUcont; dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered");
1391 }
else if (strcasecmp(fieldName,
"Coordinates") == 0) {
1392 ierr = DMGetCoordinates(user->
da, &fieldVec); CHKERRQ(ierr);
1393 dm = user->
fda; dof = 3; strcpy(data_layout,
"Node-Centered");
1394 }
else if (strcasecmp(fieldName,
"Psi") == 0) {
1395 fieldVec = user->
Psi; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
1397 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE,
"Field %s not recognized.", fieldName);
1401 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Vector for field '%s' is NULL.", fieldName);
1404 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"DM for field '%s' is NULL.", fieldName);
1407 ierr = DMDAGetLocalInfo(dm, &info); CHKERRQ(ierr);
1410 PetscInt i_start, i_end, j_start, j_end, k_start, k_end;
1412 if (strcmp(data_layout,
"Cell-Centered") == 0) {
1416 i_start = PetscMax(info.xs, 1); i_end = PetscMin(info.xs + info.xm, user->
IM);
1417 j_start = PetscMax(info.ys, 1); j_end = PetscMin(info.ys + info.ym, user->
JM);
1418 k_start = PetscMax(info.zs, 1); k_end = PetscMin(info.zs + info.zm, user->
KM);
1423 i_start = PetscMax(info.xs, 0); i_end = PetscMin(info.xs + info.xm, user->
IM);
1424 j_start = PetscMax(info.ys, 0); j_end = PetscMin(info.ys + info.ym, user->
JM);
1425 k_start = PetscMax(info.zs, 0); k_end = PetscMin(info.zs + info.zm, user->
KM);
1429 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
1431 PetscPrintf(PETSC_COMM_SELF,
"\n--- Field Ranges: [%s] (Layout: %s) ---\n", fieldName, data_layout);
1436 PetscReal localMin = PETSC_MAX_REAL, localMax = PETSC_MIN_REAL;
1437 PetscReal globalMin, globalMax;
1438 const PetscScalar ***array;
1440 ierr = DMDAVecGetArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
1441 for (k = k_start; k < k_end; k++) {
1442 for (j = j_start; j < j_end; j++) {
1443 for (i = i_start; i < i_end; i++) {
1444 localMin = PetscMin(localMin, array[k][j][i]);
1445 localMax = PetscMax(localMax, array[k][j][i]);
1449 ierr = DMDAVecRestoreArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
1451 ierr = MPI_Allreduce(&localMin, &globalMin, 1, MPIU_REAL, MPI_MIN, PETSC_COMM_WORLD); CHKERRQ(ierr);
1452 ierr = MPI_Allreduce(&localMax, &globalMax, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
1454 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin, localMax);
1455 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
1457 PetscPrintf(PETSC_COMM_SELF,
" Global Range: [ %11.4e , %11.4e ]\n", globalMin, globalMax);
1460 }
else if (dof == 3) {
1461 Cmpnts localMin = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL};
1462 Cmpnts localMax = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL};
1463 Cmpnts globalMin, globalMax;
1466 ierr = DMDAVecGetArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
1467 for (k = k_start; k < k_end; k++) {
1468 for (j = j_start; j < j_end; j++) {
1469 for (i = i_start; i < i_end; i++) {
1470 localMin.
x = PetscMin(localMin.
x, array[k][j][i].
x);
1471 localMin.
y = PetscMin(localMin.
y, array[k][j][i].
y);
1472 localMin.
z = PetscMin(localMin.
z, array[k][j][i].
z);
1473 localMax.
x = PetscMax(localMax.
x, array[k][j][i].
x);
1474 localMax.
y = PetscMax(localMax.
y, array[k][j][i].
y);
1475 localMax.
z = PetscMax(localMax.
z, array[k][j][i].
z);
1479 ierr = DMDAVecRestoreArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
1481 ierr = MPI_Allreduce(&localMin, &globalMin, 3, MPIU_REAL, MPI_MIN, PETSC_COMM_WORLD); CHKERRQ(ierr);
1482 ierr = MPI_Allreduce(&localMax, &globalMax, 3, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
1484 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local X-Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin.
x, localMax.
x);
1485 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local Y-Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin.
y, localMax.
y);
1486 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local Z-Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin.
z, localMax.
z);
1487 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
1490 PetscPrintf(PETSC_COMM_SELF,
" [Global] X-Range: [ %11.4e , %11.4e ]\n", globalMin.
x, globalMax.
x);
1491 PetscPrintf(PETSC_COMM_SELF,
" [Global] Y-Range: [ %11.4e , %11.4e ]\n", globalMin.
y, globalMax.
y);
1492 PetscPrintf(PETSC_COMM_SELF,
" [Global] Z-Range: [ %11.4e , %11.4e ]\n", globalMin.
z, globalMax.
z);
1496 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
"LogFieldStatistics only supports fields with 1 or 3 components, but field '%s' has %" PetscInt_FMT
".", fieldName, dof);
1500 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
1502 PetscPrintf(PETSC_COMM_SELF,
"--------------------------------------------\n\n");
1505 PetscFunctionReturn(0);
1517 PetscErrorCode ierr;
1521 Vec vec_local = NULL;
1524 char data_layout[20];
1525 char dominant_dir =
'\0';
1527 PetscFunctionBeginUser;
1528 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1531 if (strcasecmp(field_name,
"Ucat") == 0) {
1532 vec_local = user->
lUcat; dm = user->
fda; dof = 3; strcpy(data_layout,
"Cell-Centered");
1533 }
else if (strcasecmp(field_name,
"P") == 0) {
1534 vec_local = user->
lP; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
1535 }
else if (strcasecmp(field_name,
"Diffusivity") == 0) {
1536 vec_local = user->
lDiffusivity; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
1537 }
else if (strcasecmp(field_name,
"DiffusivityGradient") == 0) {
1539 }
else if (strcasecmp(field_name,
"Psi") == 0) {
1540 vec_local = user->
lPsi; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
1541 }
else if (strcasecmp(field_name,
"Center-Coordinates") == 0) {
1542 vec_local = user->
lCent; dm = user->
fda; dof = 3; strcpy(data_layout,
"Cell-Centered");
1543 }
else if (strcasecmp(field_name,
"Ucont") == 0) {
1544 vec_local = user->
lUcont; dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'm';
1545 }
else if (strcasecmp(field_name,
"Csi") == 0 || strcasecmp(field_name,
"X-Face-Centers") == 0) {
1546 vec_local = (strcasecmp(field_name,
"Csi") == 0) ? user->
lCsi : user->
Centx;
1547 dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'x';
1548 }
else if (strcasecmp(field_name,
"Eta") == 0 || strcasecmp(field_name,
"Y-Face-Centers") == 0) {
1549 vec_local = (strcasecmp(field_name,
"Eta") == 0) ? user->
lEta : user->
Centy;
1550 dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'y';
1551 }
else if (strcasecmp(field_name,
"Zet") == 0 || strcasecmp(field_name,
"Z-Face-Centers") == 0) {
1552 vec_local = (strcasecmp(field_name,
"Zet") == 0) ? user->
lZet : user->
Centz;
1553 dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'z';
1554 }
else if (strcasecmp(field_name,
"Coordinates") == 0) {
1555 ierr = DMGetCoordinatesLocal(user->
da, &vec_local); CHKERRQ(ierr);
1556 dm = user->
fda; dof = 3; strcpy(data_layout,
"Node-Centered");
1557 }
else if (strcasecmp(field_name,
"CornerField")== 0){
1562 if(dof == 1) dm = user->
da;
1563 else dm = user->
fda;
1565 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
"Unknown field name for LOG_FIELD_ANATOMY: %s", field_name);
1569 ierr = DMDAGetLocalInfo(dm, &info); CHKERRQ(ierr);
1571 ierr = PetscBarrier(NULL);
1572 PetscPrintf(PETSC_COMM_WORLD,
"\n--- Field Anatomy Log: [%s] | Stage: [%s] | Layout: [%s] ---\n", field_name, stage_name, data_layout);
1575 PetscInt im_phys = user->
IM;
1576 PetscInt jm_phys = user->
JM;
1577 PetscInt km_phys = user->
KM;
1580 PetscInt i_mid = (PetscInt)(info.xs + 0.5 * info.xm) - 1;
1581 PetscInt j_mid = (PetscInt)(info.ys + 0.5 * info.ym) - 1;
1582 PetscInt k_mid = (PetscInt)(info.zs + 0.5 * info.zm) - 1;
1589 if (strcmp(data_layout,
"Cell-Centered") == 0) {
1591 ierr = DMDAVecGetArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
1596 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Ghost for Cell[k][j][0]) = ", rank, 0);
1597 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][0]);
1598 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][j_mid][0].x, ((
const Cmpnts***)l_arr)[k_mid][j_mid][0].y, ((
const Cmpnts***)l_arr)[k_mid][j_mid][0].z);
1600 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Value for Cell[k][j][0]) = ", rank, 1);
1601 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][1]);
1602 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][j_mid][1].x, ((
const Cmpnts***)l_arr)[k_mid][j_mid][1].y, ((
const Cmpnts***)l_arr)[k_mid][j_mid][1].z);
1604 if (info.xs + info.xm == info.mx) {
1605 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Value for Cell[k][j][%d]) = ", rank, im_phys - 1, im_phys - 2);
1606 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][im_phys - 1]);
1607 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][j_mid][im_phys - 1].x, ((
const Cmpnts***)l_arr)[k_mid][j_mid][im_phys - 1].y, ((
const Cmpnts***)l_arr)[k_mid][j_mid][im_phys - 1].z);
1609 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Ghost for Cell[k][j][%d]) = ", rank, im_phys, im_phys - 2);
1610 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][im_phys]);
1611 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][j_mid][im_phys].x, ((
const Cmpnts***)l_arr)[k_mid][j_mid][im_phys].y, ((
const Cmpnts***)l_arr)[k_mid][j_mid][im_phys].z);
1616 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Ghost for Cell[k][0][i]) = ", rank, 0);
1617 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][0][i_mid]);
1618 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][0][i_mid].x, ((
const Cmpnts***)l_arr)[k_mid][0][i_mid].y, ((
const Cmpnts***)l_arr)[k_mid][0][i_mid].z);
1620 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Value for Cell[k][0][i]) = ", rank, 1);
1621 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][1][i_mid]);
1622 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][1][i_mid].x, ((
const Cmpnts***)l_arr)[k_mid][1][i_mid].y, ((
const Cmpnts***)l_arr)[k_mid][1][i_mid].z);
1625 if (info.ys + info.ym == info.my) {
1626 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Value for Cell[k][%d][i]) = ", rank, jm_phys - 1, jm_phys - 2);
1627 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][jm_phys - 1][i_mid]);
1628 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][jm_phys - 1][i_mid].x, ((
const Cmpnts***)l_arr)[k_mid][jm_phys - 1][i_mid].y, ((
const Cmpnts***)l_arr)[k_mid][jm_phys - 1][i_mid].z);
1630 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Ghost for Cell[k][%d][i]) = ", rank, jm_phys, jm_phys - 2);
1631 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][jm_phys][i_mid]);
1632 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[k_mid][jm_phys][i_mid].x, ((
const Cmpnts***)l_arr)[k_mid][jm_phys][i_mid].y, ((
const Cmpnts***)l_arr)[k_mid][jm_phys][i_mid].z);
1637 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Ghost for Cell[0][j][i]) = ", rank, 0);
1638 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[0][j_mid][i_mid]);
1639 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[0][j_mid][i_mid].x, ((
const Cmpnts***)l_arr)[0][j_mid][i_mid].y, ((
const Cmpnts***)l_arr)[0][j_mid][i_mid].z);
1640 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Value for Cell[0][j][i]) = ", rank, 1);
1641 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[1][j_mid][i_mid]);
1642 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[1][j_mid][i_mid].x, ((
const Cmpnts***)l_arr)[1][j_mid][i_mid].y, ((
const Cmpnts***)l_arr)[1][j_mid][i_mid].z);
1644 if (info.zs + info.zm == info.mz) {
1645 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Value for Cell[%d][j][i]) = ", rank, km_phys - 1, km_phys - 2);
1646 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[km_phys - 1][j_mid][i_mid]);
1647 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[km_phys - 1][j_mid][i_mid].x, ((
const Cmpnts***)l_arr)[km_phys - 1][j_mid][i_mid].y, ((
const Cmpnts***)l_arr)[km_phys - 1][j_mid][i_mid].z);
1648 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Ghost for Cell[%d][j][i]) = ", rank, km_phys, km_phys - 2);
1649 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[km_phys][j_mid][i_mid]);
1650 else PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f, %.5f, %.5f)\n", ((
const Cmpnts***)l_arr)[km_phys][j_mid][i_mid].x, ((
const Cmpnts***)l_arr)[km_phys][j_mid][i_mid].y, ((
const Cmpnts***)l_arr)[km_phys][j_mid][i_mid].z);
1652 ierr = DMDAVecRestoreArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
1657 else if (strcmp(data_layout,
"Face-Centered") == 0) {
1659 ierr = DMDAVecGetArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
1663 if (dominant_dir ==
'x') {
1664 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (First Phys. X-Face) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[k_mid][j_mid][0].x, l_arr[k_mid][j_mid][0].y, l_arr[k_mid][j_mid][0].z);
1665 }
else if (dominant_dir ==
'y' || dominant_dir ==
'z') {
1666 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Ghost for Cell[k][j][0]) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[k_mid][j_mid][0].x, l_arr[k_mid][j_mid][0].y, l_arr[k_mid][j_mid][0].z);
1667 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Value for Cell[k][j][0]) = (%.5f, %.5f, %.5f)\n", rank, 1, l_arr[k_mid][j_mid][1].x, l_arr[k_mid][j_mid][1].y, l_arr[k_mid][j_mid][1].z);
1668 }
else if (dominant_dir ==
'm') {
1669 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: u-comp @ Idx %2d (1st X-Face) = %.5f\n", rank, 0, l_arr[k_mid][j_mid][0].x);
1672 if (info.xs + info.xm == info.mx) {
1673 if (dominant_dir ==
'x') {
1674 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Last Phys. X-Face) = (%.5f, %.5f, %.5f)\n", rank, im_phys - 1, l_arr[k_mid][j_mid][im_phys - 1].x, l_arr[k_mid][j_mid][im_phys-1].y, l_arr[k_mid][j_mid][im_phys - 1].z);
1675 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Ghost Location) = (%.5f, %.5f, %.5f)\n", rank, im_phys, l_arr[k_mid][j_mid][im_phys].x, l_arr[k_mid][j_mid][im_phys].y, l_arr[k_mid][j_mid][im_phys].z);
1676 }
else if (dominant_dir ==
'y' || dominant_dir ==
'z') {
1677 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Value for Cell[k][j][%d]) = (%.5f, %.5f, %.5f)\n", rank, im_phys - 1, im_phys - 2, l_arr[k_mid][j_mid][im_phys - 1].x, l_arr[k_mid][j_mid][im_phys - 1].y, l_arr[k_mid][j_mid][im_phys-1].z);
1678 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Ghost for Cell[k][j][%d]) = (%.5f, %.5f, %.5f)\n", rank, im_phys, im_phys - 2, l_arr[k_mid][j_mid][im_phys].x, l_arr[k_mid][j_mid][im_phys].y, l_arr[k_mid][j_mid][im_phys].z);
1679 }
else if (dominant_dir ==
'm') {
1680 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: u-comp @ Idx %2d (Last X-Face) = %.5f\n", rank, im_phys - 1, l_arr[k_mid][j_mid][im_phys - 1].x);
1681 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: u-comp @ Idx %2d (Ghost Location) = %.5f\n", rank, im_phys, l_arr[k_mid][j_mid][im_phys].x);
1687 if (dominant_dir ==
'y') {
1688 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (First Phys. Y-Face) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[k_mid][0][i_mid].x, l_arr[k_mid][0][i_mid].y, l_arr[k_mid][0][i_mid].z);
1689 }
else if (dominant_dir ==
'x' || dominant_dir ==
'z') {
1690 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Ghost for Cell[k][0][i]) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[k_mid][0][i_mid].x, l_arr[k_mid][0][i_mid].y, l_arr[k_mid][0][i_mid].z);
1691 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Value for Cell[k][0][i]) = (%.5f, %.5f, %.5f)\n", rank, 1, l_arr[k_mid][1][i_mid].x, l_arr[k_mid][1][i_mid].y, l_arr[k_mid][1][i_mid].z);
1692 }
else if (dominant_dir ==
'm') {
1693 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: v-comp @ Jdx %2d (1st Y-Face) = %.5f\n", rank, 0, l_arr[k_mid][0][i_mid].y);
1696 if (info.ys + info.ym == info.my) {
1697 if (dominant_dir ==
'y') {
1698 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Last Phys. Y-Face) = (%.5f, %.5f, %.5f)\n", rank, jm_phys - 1, l_arr[k_mid][jm_phys - 1][i_mid].x, l_arr[k_mid][jm_phys - 1][i_mid].y, l_arr[k_mid][jm_phys - 1][i_mid].z);
1699 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Ghost Location) = (%.5f, %.5f, %.5f)\n", rank, jm_phys, l_arr[k_mid][jm_phys][i_mid].x, l_arr[k_mid][jm_phys][i_mid].y, l_arr[k_mid][jm_phys][i_mid].z);
1700 }
else if (dominant_dir ==
'x' || dominant_dir ==
'z') {
1701 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Value for Cell[k][%d][i]) = (%.5f, %.5f, %.5f)\n", rank, jm_phys-1, jm_phys-2, l_arr[k_mid][jm_phys - 1][i_mid].x, l_arr[k_mid][jm_phys - 1][i_mid].y, l_arr[k_mid][jm_phys - 1][i_mid].z);
1702 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Ghost for Cell[k][%d][i]) = (%.5f, %.5f, %.5f)\n", rank, jm_phys, jm_phys-2, l_arr[k_mid][jm_phys][i_mid].x, l_arr[k_mid][jm_phys][i_mid].y, l_arr[k_mid][jm_phys][i_mid].z);
1703 }
else if (dominant_dir ==
'm') {
1704 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: v-comp @ Jdx %2d (Last Y-Face) = %.5f\n", rank, jm_phys - 1, l_arr[k_mid][jm_phys - 1][i_mid].y);
1705 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: v-comp @ Jdx %2d (Ghost Location) = %.5f\n", rank, jm_phys, l_arr[k_mid][jm_phys][i_mid].y);
1711 if (dominant_dir ==
'z') {
1712 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (First Phys. Z-Face) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[0][j_mid][i_mid].x, l_arr[0][j_mid][i_mid].y, l_arr[0][j_mid][i_mid].z);
1713 }
else if (dominant_dir ==
'x' || dominant_dir ==
'y') {
1714 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Ghost for Cell[0][j][i]) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[0][j_mid][i_mid].x, l_arr[0][j_mid][i_mid].y, l_arr[0][j_mid][i_mid].z);
1715 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Value for Cell[0][j][i]) = (%.5f, %.5f, %.5f)\n", rank, 1, l_arr[1][j_mid][i_mid].x, l_arr[1][j_mid][i_mid].y, l_arr[1][j_mid][i_mid].z);
1716 }
else if (dominant_dir ==
'm') {
1717 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: w-comp @ Idx %2d (1st Z-Face) = %.5f\n", rank, 0, l_arr[0][j_mid][i_mid].z);
1720 if (info.zs + info.zm == info.mz) {
1721 if (dominant_dir ==
'z') {
1722 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Idx %2d (Last Phys. Z-Face) = (%.5f, %.5f, %.5f)\n", rank, km_phys - 1, l_arr[km_phys - 1][j_mid][i_mid].x, l_arr[km_phys - 1][j_mid][i_mid].y, l_arr[km_phys - 1][j_mid][i_mid].z);
1723 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Idx %2d (Ghost Location) = (%.5f, %.5f, %.5f)\n", rank, km_phys, l_arr[km_phys][j_mid][i_mid].x, l_arr[km_phys][j_mid][i_mid].y, l_arr[km_phys][j_mid][i_mid].z);
1724 }
else if (dominant_dir ==
'x' || dominant_dir ==
'y') {
1725 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Idx %2d (Value for Cell[%d][j][i]) = (%.5f, %.5f, %.5f)\n", rank, km_phys-1, km_phys-2, l_arr[km_phys-1][j_mid][i_mid].x, l_arr[km_phys-1][j_mid][i_mid].y, l_arr[km_phys - 1][j_mid][i_mid].z);
1726 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Idx %2d (Ghost for Cell[%d][j][i]) = (%.5f, %.5f, %.5f)\n", rank, km_phys, km_phys-2, l_arr[km_phys][j_mid][i_mid].x, l_arr[km_phys][j_mid][i_mid].y, l_arr[km_phys][j_mid][i_mid].z);
1727 }
else if (dominant_dir ==
'm') {
1728 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: w-comp @ Idx %2d (Last Z-Face) = %.5f\n", rank, km_phys - 1, l_arr[km_phys - 1][j_mid][i_mid].z);
1729 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: w-comp @ Idx %2d (Ghost Loc.) = %.5f\n", rank, km_phys, l_arr[km_phys][j_mid][i_mid].z);
1733 ierr = DMDAVecRestoreArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
1738 else if (strcmp(data_layout,
"Node-Centered") == 0) {
1740 ierr = DMDAVecGetArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
1744 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (First Phys. Node) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[k_mid][j_mid][0].x, l_arr[k_mid][j_mid][0].y, l_arr[k_mid][j_mid][0].z);
1746 if (info.xs + info.xm == info.mx) {
1747 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Last Phys. Node) = (%.5f, %.5f, %.5f)\n", rank, im_phys - 1, l_arr[k_mid][j_mid][im_phys - 1].x, l_arr[k_mid][j_mid][im_phys - 1].y, l_arr[k_mid][j_mid][im_phys - 1].z);
1748 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Unused/Ghost Loc) = (%.5f, %.5f, %.5f)\n", rank, im_phys, l_arr[k_mid][j_mid][im_phys].x, l_arr[k_mid][j_mid][im_phys].y, l_arr[k_mid][j_mid][im_phys].z);
1752 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (First Phys. Node) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[k_mid][0][i_mid].x, l_arr[k_mid][0][i_mid].y, l_arr[k_mid][0][i_mid].z);
1754 if (info.ys + info.ym == info.my) {
1755 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Last Phys. Node) = (%.5f, %.5f, %.5f)\n", rank, jm_phys - 1, l_arr[k_mid][jm_phys - 1][i_mid].x, l_arr[k_mid][jm_phys - 1][i_mid].y, l_arr[k_mid][jm_phys - 1][i_mid].z);
1756 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Unused/Ghost Loc) = (%.5f, %.5f, %.5f)\n", rank, jm_phys, l_arr[k_mid][jm_phys][i_mid].x, l_arr[k_mid][jm_phys][i_mid].y, l_arr[k_mid][jm_phys][i_mid].z);
1760 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (First Phys. Node) = (%.5f, %.5f, %.5f)\n", rank, 0, l_arr[0][j_mid][i_mid].x, l_arr[0][j_mid][i_mid].y, l_arr[0][j_mid][i_mid].z);
1762 if(info.zs + info.zm == info.mz) {
1763 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Last Phys. Node) = (%.5f, %.5f, %.5f)\n", rank, km_phys - 1, l_arr[km_phys - 1][j_mid][i_mid].x, l_arr[km_phys - 1][j_mid][i_mid].y, l_arr[km_phys - 1][j_mid][i_mid].z);
1764 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Unused/Ghost Loc) = (%.5f, %.5f, %.5f)\n", rank, km_phys, l_arr[km_phys][j_mid][i_mid].x, l_arr[km_phys][j_mid][i_mid].y, l_arr[km_phys][j_mid][i_mid].z);
1766 ierr = DMDAVecRestoreArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
1769 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
"LOG_FIELD_ANATOMY encountered an unknown data layout: %s", data_layout);
1772 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
1773 ierr = PetscBarrier(NULL);
1774 PetscFunctionReturn(0);
1863 PetscErrorCode ierr;
1866 PetscInt xs, xe, ys, ye, zs, ze, mx, my, mz;
1867 PetscInt lxs, lxe, lys, lye, lzs, lze;
1868 Vec reference_vec = NULL;
1869 PetscReal ***psi = NULL;
1870 PetscReal ***psi_ref = NULL;
1871 PetscReal ***aj = NULL;
1872 PetscReal ***count = NULL;
1873 PetscReal *particle_psi = NULL;
1874 PetscInt nlocal = 0;
1875 PetscReal local_l1 = 0.0, global_l1 = 0.0;
1876 PetscReal local_l2_sq = 0.0, global_l2_sq = 0.0;
1877 PetscReal local_linf = 0.0, global_linf = 0.0;
1878 PetscReal local_ref_l2_sq = 0.0, global_ref_l2_sq = 0.0;
1879 PetscReal local_grid_integral = 0.0, global_grid_integral = 0.0;
1880 PetscReal local_domain_volume = 0.0, global_domain_volume = 0.0;
1881 PetscReal local_particle_sum = 0.0, global_particle_sum = 0.0;
1882 PetscInt64 local_particle_count = 0, global_particle_count = 0;
1883 PetscInt64 local_cell_count = 0, global_cell_count = 0;
1884 PetscInt64 local_occupied_count = 0, global_occupied_count = 0;
1885 PetscReal particle_integral = 0.0;
1886 PetscReal occupancy_fraction = 0.0;
1887 PetscReal mean_particles_per_occupied_cell = 0.0;
1888 PetscReal l2_error = 0.0;
1889 PetscReal relative_l2_error = 0.0;
1891 PetscFunctionBeginUser;
1892 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx cannot be NULL.");
1895 PetscFunctionReturn(0);
1899 xs = info.xs; xe = info.xs + info.xm;
1900 ys = info.ys; ye = info.ys + info.ym;
1901 zs = info.zs; ze = info.zs + info.zm;
1902 mx = info.mx; my = info.my; mz = info.mz;
1903 lxs = (xs == 0) ? xs + 1 : xs; lxe = (xe == mx) ? xe - 1 : xe;
1904 lys = (ys == 0) ? ys + 1 : ys; lye = (ye == my) ? ye - 1 : ye;
1905 lzs = (zs == 0) ? zs + 1 : zs; lze = (ze == mz) ? ze - 1 : ze;
1907 ierr = VecDuplicate(user->
Psi, &reference_vec); CHKERRQ(ierr);
1910 ierr = DMDAVecGetArrayRead(user->
da, user->
Psi, &psi); CHKERRQ(ierr);
1911 ierr = DMDAVecGetArrayRead(user->
da, reference_vec, &psi_ref); CHKERRQ(ierr);
1912 ierr = DMDAVecGetArrayRead(user->
da, user->
Aj, &aj); CHKERRQ(ierr);
1913 ierr = DMDAVecGetArrayRead(user->
da, user->
ParticleCount, &count); CHKERRQ(ierr);
1915 for (PetscInt k = lzs; k < lze; ++k) {
1916 for (PetscInt j = lys; j < lye; ++j) {
1917 for (PetscInt i = lxs; i < lxe; ++i) {
1918 const PetscReal cell_volume = (PetscAbsReal(aj[k][j][i]) > 1.0e-14) ? (1.0 / aj[k][j][i]) : 0.0;
1919 const PetscReal err = psi[k][j][i] - psi_ref[k][j][i];
1920 local_cell_count += 1;
1921 local_domain_volume += cell_volume;
1922 local_grid_integral += psi[k][j][i] * cell_volume;
1923 local_l1 += PetscAbsReal(err) * cell_volume;
1924 local_l2_sq += err * err * cell_volume;
1925 local_ref_l2_sq += psi_ref[k][j][i] * psi_ref[k][j][i] * cell_volume;
1926 local_linf = PetscMax(local_linf, PetscAbsReal(err));
1927 if (count[k][j][i] > 0.0) local_occupied_count += 1;
1932 ierr = DMDAVecRestoreArrayRead(user->
da, user->
ParticleCount, &count); CHKERRQ(ierr);
1933 ierr = DMDAVecRestoreArrayRead(user->
da, user->
Aj, &aj); CHKERRQ(ierr);
1934 ierr = DMDAVecRestoreArrayRead(user->
da, reference_vec, &psi_ref); CHKERRQ(ierr);
1935 ierr = DMDAVecRestoreArrayRead(user->
da, user->
Psi, &psi); CHKERRQ(ierr);
1936 ierr = VecDestroy(&reference_vec); CHKERRQ(ierr);
1938 ierr = DMSwarmGetLocalSize(user->
swarm, &nlocal); CHKERRQ(ierr);
1939 local_particle_count = (PetscInt64)nlocal;
1941 ierr = DMSwarmGetField(user->
swarm,
"Psi", NULL, NULL, (
void **)&particle_psi); CHKERRQ(ierr);
1942 for (PetscInt p = 0; p < nlocal; ++p) local_particle_sum += particle_psi[p];
1943 ierr = DMSwarmRestoreField(user->
swarm,
"Psi", NULL, NULL, (
void **)&particle_psi); CHKERRQ(ierr);
1946 ierr = MPI_Allreduce(&local_l1, &global_l1, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1947 ierr = MPI_Allreduce(&local_l2_sq, &global_l2_sq, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1948 ierr = MPI_Allreduce(&local_linf, &global_linf, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1949 ierr = MPI_Allreduce(&local_ref_l2_sq, &global_ref_l2_sq, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1950 ierr = MPI_Allreduce(&local_grid_integral, &global_grid_integral, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1951 ierr = MPI_Allreduce(&local_domain_volume, &global_domain_volume, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1952 ierr = MPI_Allreduce(&local_particle_sum, &global_particle_sum, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1953 ierr = MPI_Allreduce(&local_particle_count, &global_particle_count, 1, MPIU_INT64, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1954 ierr = MPI_Allreduce(&local_cell_count, &global_cell_count, 1, MPIU_INT64, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1955 ierr = MPI_Allreduce(&local_occupied_count, &global_occupied_count, 1, MPIU_INT64, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
1957 l2_error = PetscSqrtReal(global_l2_sq);
1958 relative_l2_error = (global_ref_l2_sq > 0.0) ? (l2_error / PetscSqrtReal(global_ref_l2_sq)) : 0.0;
1959 occupancy_fraction = (global_cell_count > 0) ? ((PetscReal)global_occupied_count / (PetscReal)global_cell_count) : 0.0;
1960 mean_particles_per_occupied_cell =
1961 (global_occupied_count > 0) ? ((PetscReal)global_particle_count / (PetscReal)global_occupied_count) : 0.0;
1963 (global_particle_count > 0) ? (global_domain_volume * global_particle_sum / (PetscReal)global_particle_count) : 0.0;
1965 if (simCtx->
rank == 0) {
1966 char csv_path[PETSC_MAX_PATH_LEN + 32];
1968 ierr = PetscSNPrintf(csv_path,
sizeof(csv_path),
"%s/scatter_metrics.csv", simCtx->
log_dir); CHKERRQ(ierr);
1969 f = fopen(csv_path,
"a");
1971 if (ftell(f) == 0) {
1973 "step,time,total_particles,total_cells,occupied_cells,occupancy_fraction,"
1974 "mean_particles_per_occupied_cell,particle_integral,grid_integral,"
1975 "conservation_error_abs,L1_error,L2_error,Linf_error,relative_L2_error\n");
1977 fprintf(f,
"%d,%.6e,%lld,%lld,%lld,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e\n",
1980 (
long long)global_particle_count,
1981 (
long long)global_cell_count,
1982 (
long long)global_occupied_count,
1983 (
double)occupancy_fraction,
1984 (
double)mean_particles_per_occupied_cell,
1985 (
double)particle_integral,
1986 (
double)global_grid_integral,
1987 (
double)PetscAbsReal(global_grid_integral - particle_integral),
1990 (
double)global_linf,
1991 (
double)relative_l2_error);
2001 PetscFunctionReturn(0);