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);
1065 PetscBool periodic_mode,
1066 PetscInt phase_step,
1067 PetscInt samples_before,
1068 PetscBool *has_reference_out,
1069 PetscReal *u_abs_l2_out,
1070 PetscReal *u_rel_l2_out,
1071 PetscReal *p_abs_l2_out,
1072 PetscReal *p_rel_l2_out,
1073 PetscReal *mean_speed_out,
1074 PetscReal *mean_speed_ref_out,
1075 PetscReal *mean_speed_abs_out,
1076 PetscReal *mean_speed_rel_out,
1077 PetscReal *mean_ke_out,
1078 PetscReal *mean_ke_ref_out,
1079 PetscReal *mean_ke_abs_out,
1080 PetscReal *mean_ke_rel_out)
1086 PetscReal current_pressure_mean = 0.0;
1087 PetscReal reference_pressure_mean = 0.0;
1090 PetscFunctionBeginUser;
1091 if (!simCtx || !has_reference_out || !u_abs_l2_out || !u_rel_l2_out || !p_abs_l2_out || !p_rel_l2_out ||
1092 !mean_speed_out || !mean_speed_ref_out || !mean_speed_abs_out || !mean_speed_rel_out ||
1093 !mean_ke_out || !mean_ke_ref_out || !mean_ke_abs_out || !mean_ke_rel_out) {
1094 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"ComputeDeterministicSolutionMetrics received a NULL output pointer.");
1097 *has_reference_out = periodic_mode
1100 phase_step < simCtx->solutionConvergencePeriodSteps &&
1102 : (PetscBool)(samples_before > 0);
1104 *u_abs_l2_out = 0.0;
1105 *u_rel_l2_out = 0.0;
1106 *p_abs_l2_out = 0.0;
1107 *p_rel_l2_out = 0.0;
1108 *mean_speed_out = 0.0;
1109 *mean_speed_ref_out = 0.0;
1110 *mean_speed_abs_out = 0.0;
1111 *mean_speed_rel_out = 0.0;
1113 *mean_ke_ref_out = 0.0;
1114 *mean_ke_abs_out = 0.0;
1115 *mean_ke_rel_out = 0.0;
1119 for (PetscInt bi = 0; bi < simCtx->
block_number; ++bi) {
1120 const DMDALocalInfo info = user[bi].
info;
1122 Cmpnts ***ucat_ref = NULL;
1123 PetscReal ***pressure = NULL;
1124 PetscReal ***pressure_ref = NULL;
1125 PetscReal ***aj = NULL;
1126 PetscReal ***nvert = NULL;
1127 Vec ucat_reference_vec = NULL;
1128 Vec pressure_reference_vec = NULL;
1130 if (*has_reference_out) {
1131 if (periodic_mode) {
1135 ucat_reference_vec = user[bi].
Ucat_o;
1136 pressure_reference_vec = user[bi].
P_o;
1140 PetscCall(DMDAVecGetArrayRead(user[bi].fda, user[bi].Ucat, &ucat));
1141 PetscCall(DMDAVecGetArrayRead(user[bi].da, user[bi].P, &pressure));
1142 PetscCall(DMDAVecGetArrayRead(user[bi].da, user[bi].Aj, &aj));
1143 PetscCall(DMDAVecGetArrayRead(user[bi].da, user[bi].Nvert, &nvert));
1144 if (*has_reference_out) {
1145 PetscCall(DMDAVecGetArrayRead(user[bi].fda, ucat_reference_vec, &ucat_ref));
1146 PetscCall(DMDAVecGetArrayRead(user[bi].da, pressure_reference_vec, &pressure_ref));
1149 for (PetscInt k = info.zs; k < info.zs + info.zm; ++k) {
1150 for (PetscInt j = info.ys; j < info.ys + info.ym; ++j) {
1151 for (PetscInt i = info.xs; i < info.xs + info.xm; ++i) {
1152 PetscReal jac = aj[k][j][i];
1153 PetscReal cell_volume = 0.0;
1154 PetscReal speed = 0.0;
1158 if (PetscAbsReal(jac) <= 1.0e-14)
continue;
1160 cell_volume = 1.0 / jac;
1161 speed = PetscSqrtReal(ucat[k][j][i].x * ucat[k][j][i].x +
1162 ucat[k][j][i].y * ucat[k][j][i].y +
1163 ucat[k][j][i].z * ucat[k][j][i].z);
1164 ke = 0.5 * speed * speed;
1170 ucat[k][j][i].
y * ucat[k][j][i].
y +
1171 ucat[k][j][i].
z * ucat[k][j][i].
z) * cell_volume;
1173 if (*has_reference_out) {
1174 PetscReal ref_speed = PetscSqrtReal(ucat_ref[k][j][i].x * ucat_ref[k][j][i].x +
1175 ucat_ref[k][j][i].y * ucat_ref[k][j][i].y +
1176 ucat_ref[k][j][i].z * ucat_ref[k][j][i].z);
1177 PetscReal ref_ke = 0.5 * ref_speed * ref_speed;
1178 PetscReal dux = ucat[k][j][i].
x - ucat_ref[k][j][i].
x;
1179 PetscReal duy = ucat[k][j][i].
y - ucat_ref[k][j][i].
y;
1180 PetscReal duz = ucat[k][j][i].
z - ucat_ref[k][j][i].
z;
1184 local_pass1.
delta_u_norm_sq += (dux * dux + duy * duy + duz * duz) * cell_volume;
1192 if (*has_reference_out) {
1193 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, pressure_reference_vec, &pressure_ref));
1194 PetscCall(DMDAVecRestoreArrayRead(user[bi].fda, ucat_reference_vec, &ucat_ref));
1196 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, user[bi].Nvert, &nvert));
1197 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, user[bi].Aj, &aj));
1198 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, user[bi].P, &pressure));
1199 PetscCall(DMDAVecRestoreArrayRead(user[bi].fda, user[bi].Ucat, &ucat));
1202 PetscCallMPI(MPI_Allreduce(&local_pass1, &global_pass1,
1204 MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD));
1206 if (global_pass1.
fluid_volume <= 0.0) PetscFunctionReturn(0);
1211 if (!*has_reference_out) PetscFunctionReturn(0);
1214 *mean_speed_abs_out = PetscAbsReal(*mean_speed_out - *mean_speed_ref_out);
1217 *mean_ke_abs_out = PetscAbsReal(*mean_ke_out - *mean_ke_ref_out);
1223 for (PetscInt bi = 0; bi < simCtx->
block_number; ++bi) {
1224 const DMDALocalInfo info = user[bi].
info;
1225 PetscReal ***pressure = NULL;
1226 PetscReal ***pressure_ref = NULL;
1227 PetscReal ***aj = NULL;
1228 PetscReal ***nvert = NULL;
1231 PetscCall(DMDAVecGetArrayRead(user[bi].da, user[bi].P, &pressure));
1232 PetscCall(DMDAVecGetArrayRead(user[bi].da, pressure_reference_vec, &pressure_ref));
1233 PetscCall(DMDAVecGetArrayRead(user[bi].da, user[bi].Aj, &aj));
1234 PetscCall(DMDAVecGetArrayRead(user[bi].da, user[bi].Nvert, &nvert));
1236 for (PetscInt k = info.zs; k < info.zs + info.zm; ++k) {
1237 for (PetscInt j = info.ys; j < info.ys + info.ym; ++j) {
1238 for (PetscInt i = info.xs; i < info.xs + info.xm; ++i) {
1239 PetscReal jac = aj[k][j][i];
1240 PetscReal cell_volume = 0.0;
1241 PetscReal current_pressure = 0.0;
1242 PetscReal reference_pressure = 0.0;
1243 PetscReal delta_pressure = 0.0;
1246 if (PetscAbsReal(jac) <= 1.0e-14)
continue;
1248 cell_volume = 1.0 / jac;
1249 current_pressure = pressure[k][j][i] - current_pressure_mean;
1250 reference_pressure = pressure_ref[k][j][i] - reference_pressure_mean;
1251 delta_pressure = current_pressure - reference_pressure;
1259 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, user[bi].Nvert, &nvert));
1260 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, user[bi].Aj, &aj));
1261 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, pressure_reference_vec, &pressure_ref));
1262 PetscCall(DMDAVecRestoreArrayRead(user[bi].da, user[bi].P, &pressure));
1265 PetscCallMPI(MPI_Allreduce(&local_pass2, &global_pass2,
1267 MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD));
1274 PetscFunctionReturn(0);
1411 PetscInt samples_available,
1412 PetscBool *has_reference_out,
1413 PetscReal *mean_speed_window_out,
1414 PetscReal *mean_speed_window_prev_out,
1415 PetscReal *mean_speed_window_abs_out,
1416 PetscReal *mean_speed_window_rel_out,
1417 PetscReal *mean_speed_rms_window_out,
1418 PetscReal *mean_speed_rms_window_prev_out,
1419 PetscReal *mean_speed_rms_window_abs_out,
1420 PetscReal *mean_speed_rms_window_rel_out,
1421 PetscReal *mean_ke_window_out,
1422 PetscReal *mean_ke_window_prev_out,
1423 PetscReal *mean_ke_window_abs_out,
1424 PetscReal *mean_ke_window_rel_out,
1425 PetscReal *mean_ke_rms_window_out,
1426 PetscReal *mean_ke_rms_window_prev_out,
1427 PetscReal *mean_ke_rms_window_abs_out,
1428 PetscReal *mean_ke_rms_window_rel_out)
1431 PetscInt history_capacity = 0;
1432 PetscReal speed_sum = 0.0;
1433 PetscReal speed_sum_sq = 0.0;
1434 PetscReal speed_prev_sum = 0.0;
1435 PetscReal speed_prev_sum_sq = 0.0;
1436 PetscReal ke_sum = 0.0;
1437 PetscReal ke_sum_sq = 0.0;
1438 PetscReal ke_prev_sum = 0.0;
1439 PetscReal ke_prev_sum_sq = 0.0;
1441 PetscFunctionBeginUser;
1442 if (!simCtx || !has_reference_out || !mean_speed_window_out || !mean_speed_window_prev_out ||
1443 !mean_speed_window_abs_out || !mean_speed_window_rel_out || !mean_speed_rms_window_out ||
1444 !mean_speed_rms_window_prev_out || !mean_speed_rms_window_abs_out || !mean_speed_rms_window_rel_out ||
1445 !mean_ke_window_out || !mean_ke_window_prev_out || !mean_ke_window_abs_out || !mean_ke_window_rel_out ||
1446 !mean_ke_rms_window_out || !mean_ke_rms_window_prev_out || !mean_ke_rms_window_abs_out ||
1447 !mean_ke_rms_window_rel_out) {
1448 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"ComputeStatisticalWindowMetrics received a NULL output pointer.");
1451 *has_reference_out = PETSC_FALSE;
1452 *mean_speed_window_out = 0.0;
1453 *mean_speed_window_prev_out = 0.0;
1454 *mean_speed_window_abs_out = 0.0;
1455 *mean_speed_window_rel_out = 0.0;
1456 *mean_speed_rms_window_out = 0.0;
1457 *mean_speed_rms_window_prev_out = 0.0;
1458 *mean_speed_rms_window_abs_out = 0.0;
1459 *mean_speed_rms_window_rel_out = 0.0;
1460 *mean_ke_window_out = 0.0;
1461 *mean_ke_window_prev_out = 0.0;
1462 *mean_ke_window_abs_out = 0.0;
1463 *mean_ke_window_rel_out = 0.0;
1464 *mean_ke_rms_window_out = 0.0;
1465 *mean_ke_rms_window_prev_out = 0.0;
1466 *mean_ke_rms_window_abs_out = 0.0;
1467 *mean_ke_rms_window_rel_out = 0.0;
1470 history_capacity = 2 * w;
1471 if (w <= 0 || samples_available < w) PetscFunctionReturn(0);
1473 for (PetscInt idx = 0; idx < w; ++idx) {
1482 speed_sum += speed_value;
1483 speed_sum_sq += speed_value * speed_value;
1485 ke_sum_sq += ke_value * ke_value;
1488 *mean_speed_window_out = speed_sum / (PetscReal)w;
1489 *mean_speed_rms_window_out = PetscSqrtReal(PetscMax(0.0, speed_sum_sq / (PetscReal)w -
1490 (*mean_speed_window_out) * (*mean_speed_window_out)));
1491 *mean_ke_window_out = ke_sum / (PetscReal)w;
1492 *mean_ke_rms_window_out = PetscSqrtReal(PetscMax(0.0, ke_sum_sq / (PetscReal)w -
1493 (*mean_ke_window_out) * (*mean_ke_window_out)));
1495 if (samples_available < 2 * w) PetscFunctionReturn(0);
1497 for (PetscInt idx = w; idx < 2 * w; ++idx) {
1506 speed_prev_sum += speed_value;
1507 speed_prev_sum_sq += speed_value * speed_value;
1508 ke_prev_sum += ke_value;
1509 ke_prev_sum_sq += ke_value * ke_value;
1512 *has_reference_out = PETSC_TRUE;
1513 *mean_speed_window_prev_out = speed_prev_sum / (PetscReal)w;
1514 *mean_speed_window_abs_out = PetscAbsReal(*mean_speed_window_out - *mean_speed_window_prev_out);
1516 *mean_speed_rms_window_prev_out = PetscSqrtReal(PetscMax(0.0, speed_prev_sum_sq / (PetscReal)w -
1517 (*mean_speed_window_prev_out) * (*mean_speed_window_prev_out)));
1518 *mean_speed_rms_window_abs_out = PetscAbsReal(*mean_speed_rms_window_out - *mean_speed_rms_window_prev_out);
1521 *mean_ke_window_prev_out = ke_prev_sum / (PetscReal)w;
1522 *mean_ke_window_abs_out = PetscAbsReal(*mean_ke_window_out - *mean_ke_window_prev_out);
1524 *mean_ke_rms_window_prev_out = PetscSqrtReal(PetscMax(0.0, ke_prev_sum_sq / (PetscReal)w -
1525 (*mean_ke_window_prev_out) * (*mean_ke_window_prev_out)));
1526 *mean_ke_rms_window_abs_out = PetscAbsReal(*mean_ke_rms_window_out - *mean_ke_rms_window_prev_out);
1529 PetscFunctionReturn(0);
1562 PetscMPIInt rank = 0;
1563 PetscBool has_reference = PETSC_FALSE;
1564 PetscInt phase_step = -1;
1565 PetscInt samples_before = 0;
1566 PetscReal u_abs_l2 = 0.0, u_rel_l2 = 0.0, p_abs_l2 = 0.0, p_rel_l2 = 0.0;
1567 PetscReal mean_speed = 0.0, mean_speed_reference = 0.0, mean_speed_abs_drift = 0.0, mean_speed_rel_drift = 0.0;
1568 PetscReal mean_ke = 0.0, mean_ke_reference = 0.0, mean_ke_abs_drift = 0.0, mean_ke_rel_drift = 0.0;
1569 PetscReal mean_speed_window = 0.0, mean_speed_window_prev = 0.0, mean_speed_window_abs_drift = 0.0, mean_speed_window_rel_drift = 0.0;
1570 PetscReal mean_speed_rms_window = 0.0, mean_speed_rms_window_prev = 0.0, mean_speed_rms_window_abs_drift = 0.0, mean_speed_rms_window_rel_drift = 0.0;
1571 PetscReal mean_ke_window = 0.0, mean_ke_window_prev = 0.0, mean_ke_window_abs_drift = 0.0, mean_ke_window_rel_drift = 0.0;
1572 PetscReal mean_ke_rms_window = 0.0, mean_ke_rms_window_prev = 0.0, mean_ke_rms_window_abs_drift = 0.0, mean_ke_rms_window_rel_drift = 0.0;
1574 PetscFunctionBeginUser;
1575 if (!simCtx) PetscFunctionReturn(0);
1585 &u_abs_l2, &u_rel_l2,
1586 &p_abs_l2, &p_rel_l2,
1587 &mean_speed, &mean_speed_reference,
1588 &mean_speed_abs_drift, &mean_speed_rel_drift,
1589 &mean_ke, &mean_ke_reference,
1590 &mean_ke_abs_drift, &mean_ke_rel_drift));
1596 &u_abs_l2, &u_rel_l2,
1597 &p_abs_l2, &p_rel_l2,
1598 &mean_speed, &mean_speed_reference,
1599 &mean_speed_abs_drift, &mean_speed_rel_drift,
1600 &mean_ke, &mean_ke_reference,
1601 &mean_ke_abs_drift, &mean_ke_rel_drift));
1608 &mean_speed_window, &mean_speed_window_prev,
1609 &mean_speed_window_abs_drift, &mean_speed_window_rel_drift,
1610 &mean_speed_rms_window, &mean_speed_rms_window_prev,
1611 &mean_speed_rms_window_abs_drift, &mean_speed_rms_window_rel_drift,
1612 &mean_ke_window, &mean_ke_window_prev,
1613 &mean_ke_window_abs_drift, &mean_ke_window_rel_drift,
1614 &mean_ke_rms_window, &mean_ke_rms_window_prev,
1615 &mean_ke_rms_window_abs_drift, &mean_ke_rms_window_rel_drift));
1618 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"Unknown solution convergence mode %d.", (
int)simCtx->
solutionConvergenceMode);
1621 PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank));
1623 char log_path[PETSC_MAX_PATH_LEN + 32];
1627 PetscCall(PetscSNPrintf(log_path,
sizeof(log_path),
"%s/solution_convergence.log", simCtx->
log_dir));
1628 f = fopen(log_path,
"a");
1630 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Cannot open solution convergence log: %s", log_path);
1633 if (ftell(f) == 0) {
1637 fprintf(f,
"==================== Solution Convergence Log [mode: %s] ====================\n", mode_str);
1639 fprintf(f,
"%-10s | %-18s | %-22s | %-3s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s\n",
1640 "step",
"time",
"mode",
"ref",
1641 "u_abs_l2",
"u_rel_l2",
"p_abs_l2",
"p_rel_l2",
1642 "mean_speed",
"spd_ref",
"spd_abs",
"spd_rel",
1643 "mean_ke",
"ke_ref",
"ke_abs",
"ke_rel");
1644 fprintf(f,
"----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
1647 fprintf(f,
"==================== Solution Convergence Log [mode: %s | period_steps: %d] ====================\n",
1650 fprintf(f,
"%-10s | %-18s | %-22s | %-3s | %-5s | %-5s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s\n",
1651 "step",
"time",
"mode",
"ref",
"ph",
"per",
1652 "u_abs_l2",
"u_rel_l2",
"p_abs_l2",
"p_rel_l2",
1653 "mean_speed",
"spd_ref",
"spd_abs",
"spd_rel",
1654 "mean_ke",
"ke_ref",
"ke_abs",
"ke_rel");
1655 fprintf(f,
"----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
1658 fprintf(f,
"==================== Solution Convergence Log [mode: %s | window_steps: %d] ====================\n",
1661 fprintf(f,
"%-10s | %-18s | %-22s | %-3s | %-5s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s | %-18s\n",
1662 "step",
"time",
"mode",
"ref",
"win",
1663 "mean_speed",
"mean_ke",
1664 "spd_win",
"spd_win_prev",
"spd_win_abs",
"spd_win_rel",
1665 "spd_rms_win",
"spd_rms_abs",
"spd_rms_rel",
1666 "ke_win",
"ke_win_prev",
"ke_win_abs",
"ke_win_rel",
1667 "ke_rms_win",
"ke_rms_abs",
"ke_rms_rel");
1668 fprintf(f,
"------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n");
1678 "%-10d | %-18.10e | %-22s | %-3d | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e\n",
1679 (
int)simCtx->
step, (
double)simCtx->
ti, mode_str, has_reference ? 1 : 0,
1680 (double)u_abs_l2, (
double)u_rel_l2, (double)p_abs_l2, (
double)p_rel_l2,
1681 (double)mean_speed, (
double)mean_speed_reference,
1682 (double)mean_speed_abs_drift, (
double)mean_speed_rel_drift,
1683 (double)mean_ke, (
double)mean_ke_reference,
1684 (double)mean_ke_abs_drift, (
double)mean_ke_rel_drift);
1688 "%-10d | %-18.10e | %-22s | %-3d | %-5d | %-5d | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e\n",
1689 (
int)simCtx->
step, (
double)simCtx->
ti, mode_str, has_reference ? 1 : 0,
1691 (double)u_abs_l2, (
double)u_rel_l2, (double)p_abs_l2, (
double)p_rel_l2,
1692 (double)mean_speed, (
double)mean_speed_reference,
1693 (double)mean_speed_abs_drift, (
double)mean_speed_rel_drift,
1694 (double)mean_ke, (
double)mean_ke_reference,
1695 (double)mean_ke_abs_drift, (
double)mean_ke_rel_drift);
1699 "%-10d | %-18.10e | %-22s | %-3d | %-5d | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e | %-18.10e\n",
1700 (
int)simCtx->
step, (
double)simCtx->
ti, mode_str, has_reference ? 1 : 0,
1702 (
double)mean_speed, (double)mean_ke,
1703 (
double)mean_speed_window, (double)mean_speed_window_prev,
1704 (
double)mean_speed_window_abs_drift, (double)mean_speed_window_rel_drift,
1705 (
double)mean_speed_rms_window,
1706 (double)mean_speed_rms_window_abs_drift, (
double)mean_speed_rms_window_rel_drift,
1707 (double)mean_ke_window, (
double)mean_ke_window_prev,
1708 (double)mean_ke_window_abs_drift, (
double)mean_ke_window_rel_drift,
1709 (double)mean_ke_rms_window,
1710 (
double)mean_ke_rms_window_abs_drift, (double)mean_ke_rms_window_rel_drift);
1718 phase_step >= 0 && phase_step < simCtx->solutionConvergencePeriodSteps) {
1720 for (PetscInt bi = 0; bi < simCtx->
block_number; ++bi) {
1721 PetscCall(VecCopy(user[bi].Ucat, user[bi].solutionConvergencePeriodicUcatRef[phase_step]));
1722 PetscCall(VecCopy(user[bi].P, user[bi].solutionConvergencePeriodicPRef[phase_step]));
1728 PetscFunctionReturn(0);
2303 PetscErrorCode ierr;
2307 Vec fieldVec = NULL;
2310 char data_layout[20];
2312 PetscFunctionBeginUser;
2315 if (strcasecmp(fieldName,
"Ucat") == 0) {
2316 fieldVec = user->
Ucat; dm = user->
fda; dof = 3; strcpy(data_layout,
"Cell-Centered");
2317 }
else if (strcasecmp(fieldName,
"P") == 0) {
2318 fieldVec = user->
P; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
2319 }
else if (strcasecmp(fieldName,
"Diffusivity") == 0) {
2320 fieldVec = user->
Diffusivity; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
2321 }
else if (strcasecmp(fieldName,
"DiffusivityGradient") == 0) {
2323 }
else if (strcasecmp(fieldName,
"Ucont") == 0) {
2324 fieldVec = user->
lUcont; dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered");
2325 }
else if (strcasecmp(fieldName,
"Coordinates") == 0) {
2326 ierr = DMGetCoordinates(user->
da, &fieldVec); CHKERRQ(ierr);
2327 dm = user->
fda; dof = 3; strcpy(data_layout,
"Node-Centered");
2328 }
else if (strcasecmp(fieldName,
"Psi") == 0) {
2329 fieldVec = user->
Psi; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
2331 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE,
"Field %s not recognized.", fieldName);
2335 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Vector for field '%s' is NULL.", fieldName);
2338 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"DM for field '%s' is NULL.", fieldName);
2341 ierr = DMDAGetLocalInfo(dm, &info); CHKERRQ(ierr);
2344 PetscInt i_start, i_end, j_start, j_end, k_start, k_end;
2346 if (strcmp(data_layout,
"Cell-Centered") == 0) {
2350 i_start = PetscMax(info.xs, 1); i_end = PetscMin(info.xs + info.xm, user->
IM);
2351 j_start = PetscMax(info.ys, 1); j_end = PetscMin(info.ys + info.ym, user->
JM);
2352 k_start = PetscMax(info.zs, 1); k_end = PetscMin(info.zs + info.zm, user->
KM);
2357 i_start = PetscMax(info.xs, 0); i_end = PetscMin(info.xs + info.xm, user->
IM);
2358 j_start = PetscMax(info.ys, 0); j_end = PetscMin(info.ys + info.ym, user->
JM);
2359 k_start = PetscMax(info.zs, 0); k_end = PetscMin(info.zs + info.zm, user->
KM);
2363 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
2365 PetscPrintf(PETSC_COMM_SELF,
"\n--- Field Ranges: [%s] (Layout: %s) ---\n", fieldName, data_layout);
2370 PetscReal localMin = PETSC_MAX_REAL, localMax = PETSC_MIN_REAL;
2371 PetscReal globalMin, globalMax;
2372 const PetscScalar ***array;
2374 ierr = DMDAVecGetArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
2375 for (k = k_start; k < k_end; k++) {
2376 for (j = j_start; j < j_end; j++) {
2377 for (i = i_start; i < i_end; i++) {
2378 localMin = PetscMin(localMin, array[k][j][i]);
2379 localMax = PetscMax(localMax, array[k][j][i]);
2383 ierr = DMDAVecRestoreArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
2385 ierr = MPI_Allreduce(&localMin, &globalMin, 1, MPIU_REAL, MPI_MIN, PETSC_COMM_WORLD); CHKERRQ(ierr);
2386 ierr = MPI_Allreduce(&localMax, &globalMax, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
2388 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin, localMax);
2389 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
2391 PetscPrintf(PETSC_COMM_SELF,
" Global Range: [ %11.4e , %11.4e ]\n", globalMin, globalMax);
2394 }
else if (dof == 3) {
2395 Cmpnts localMin = {PETSC_MAX_REAL, PETSC_MAX_REAL, PETSC_MAX_REAL};
2396 Cmpnts localMax = {PETSC_MIN_REAL, PETSC_MIN_REAL, PETSC_MIN_REAL};
2397 Cmpnts globalMin, globalMax;
2400 ierr = DMDAVecGetArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
2401 for (k = k_start; k < k_end; k++) {
2402 for (j = j_start; j < j_end; j++) {
2403 for (i = i_start; i < i_end; i++) {
2404 localMin.
x = PetscMin(localMin.
x, array[k][j][i].
x);
2405 localMin.
y = PetscMin(localMin.
y, array[k][j][i].
y);
2406 localMin.
z = PetscMin(localMin.
z, array[k][j][i].
z);
2407 localMax.
x = PetscMax(localMax.
x, array[k][j][i].
x);
2408 localMax.
y = PetscMax(localMax.
y, array[k][j][i].
y);
2409 localMax.
z = PetscMax(localMax.
z, array[k][j][i].
z);
2413 ierr = DMDAVecRestoreArrayRead(dm, fieldVec, &array); CHKERRQ(ierr);
2415 ierr = MPI_Allreduce(&localMin, &globalMin, 3, MPIU_REAL, MPI_MIN, PETSC_COMM_WORLD); CHKERRQ(ierr);
2416 ierr = MPI_Allreduce(&localMax, &globalMax, 3, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
2418 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local X-Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin.
x, localMax.
x);
2419 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local Y-Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin.
y, localMax.
y);
2420 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
" [Rank %d] Local Z-Range: [ %11.4e , %11.4e ]\n", user->
simCtx->
rank, localMin.
z, localMax.
z);
2421 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
2424 PetscPrintf(PETSC_COMM_SELF,
" [Global] X-Range: [ %11.4e , %11.4e ]\n", globalMin.
x, globalMax.
x);
2425 PetscPrintf(PETSC_COMM_SELF,
" [Global] Y-Range: [ %11.4e , %11.4e ]\n", globalMin.
y, globalMax.
y);
2426 PetscPrintf(PETSC_COMM_SELF,
" [Global] Z-Range: [ %11.4e , %11.4e ]\n", globalMin.
z, globalMax.
z);
2430 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);
2434 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
2436 PetscPrintf(PETSC_COMM_SELF,
"--------------------------------------------\n\n");
2439 PetscFunctionReturn(0);
2451 PetscErrorCode ierr;
2455 Vec vec_local = NULL;
2458 char data_layout[20];
2459 char dominant_dir =
'\0';
2461 PetscFunctionBeginUser;
2462 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
2465 if (strcasecmp(field_name,
"Ucat") == 0) {
2466 vec_local = user->
lUcat; dm = user->
fda; dof = 3; strcpy(data_layout,
"Cell-Centered");
2467 }
else if (strcasecmp(field_name,
"P") == 0) {
2468 vec_local = user->
lP; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
2469 }
else if (strcasecmp(field_name,
"Diffusivity") == 0) {
2470 vec_local = user->
lDiffusivity; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
2471 }
else if (strcasecmp(field_name,
"DiffusivityGradient") == 0) {
2473 }
else if (strcasecmp(field_name,
"Psi") == 0) {
2474 vec_local = user->
lPsi; dm = user->
da; dof = 1; strcpy(data_layout,
"Cell-Centered");
2475 }
else if (strcasecmp(field_name,
"Center-Coordinates") == 0) {
2476 vec_local = user->
lCent; dm = user->
fda; dof = 3; strcpy(data_layout,
"Cell-Centered");
2477 }
else if (strcasecmp(field_name,
"Ucont") == 0) {
2478 vec_local = user->
lUcont; dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'm';
2479 }
else if (strcasecmp(field_name,
"Csi") == 0 || strcasecmp(field_name,
"X-Face-Centers") == 0) {
2480 vec_local = (strcasecmp(field_name,
"Csi") == 0) ? user->
lCsi : user->
Centx;
2481 dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'x';
2482 }
else if (strcasecmp(field_name,
"Eta") == 0 || strcasecmp(field_name,
"Y-Face-Centers") == 0) {
2483 vec_local = (strcasecmp(field_name,
"Eta") == 0) ? user->
lEta : user->
Centy;
2484 dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'y';
2485 }
else if (strcasecmp(field_name,
"Zet") == 0 || strcasecmp(field_name,
"Z-Face-Centers") == 0) {
2486 vec_local = (strcasecmp(field_name,
"Zet") == 0) ? user->
lZet : user->
Centz;
2487 dm = user->
fda; dof = 3; strcpy(data_layout,
"Face-Centered"); dominant_dir =
'z';
2488 }
else if (strcasecmp(field_name,
"Coordinates") == 0) {
2489 ierr = DMGetCoordinatesLocal(user->
da, &vec_local); CHKERRQ(ierr);
2490 dm = user->
fda; dof = 3; strcpy(data_layout,
"Node-Centered");
2491 }
else if (strcasecmp(field_name,
"CornerField")== 0){
2496 if(dof == 1) dm = user->
da;
2497 else dm = user->
fda;
2499 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
"Unknown field name for LOG_FIELD_ANATOMY: %s", field_name);
2503 ierr = DMDAGetLocalInfo(dm, &info); CHKERRQ(ierr);
2505 ierr = PetscBarrier(NULL);
2506 PetscPrintf(PETSC_COMM_WORLD,
"\n--- Field Anatomy Log: [%s] | Stage: [%s] | Layout: [%s] ---\n", field_name, stage_name, data_layout);
2509 PetscInt im_phys = user->
IM;
2510 PetscInt jm_phys = user->
JM;
2511 PetscInt km_phys = user->
KM;
2514 PetscInt i_mid = (PetscInt)(info.xs + 0.5 * info.xm) - 1;
2515 PetscInt j_mid = (PetscInt)(info.ys + 0.5 * info.ym) - 1;
2516 PetscInt k_mid = (PetscInt)(info.zs + 0.5 * info.zm) - 1;
2523 if (strcmp(data_layout,
"Cell-Centered") == 0) {
2525 ierr = DMDAVecGetArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
2530 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Ghost for Cell[k][j][0]) = ", rank, 0);
2531 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][0]);
2532 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);
2534 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Value for Cell[k][j][0]) = ", rank, 1);
2535 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][1]);
2536 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);
2538 if (info.xs + info.xm == info.mx) {
2539 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Value for Cell[k][j][%d]) = ", rank, im_phys - 1, im_phys - 2);
2540 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][im_phys - 1]);
2541 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);
2543 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, I-DIR]: Idx %2d (Ghost for Cell[k][j][%d]) = ", rank, im_phys, im_phys - 2);
2544 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][j_mid][im_phys]);
2545 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);
2550 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Ghost for Cell[k][0][i]) = ", rank, 0);
2551 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][0][i_mid]);
2552 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);
2554 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Value for Cell[k][0][i]) = ", rank, 1);
2555 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][1][i_mid]);
2556 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);
2559 if (info.ys + info.ym == info.my) {
2560 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Value for Cell[k][%d][i]) = ", rank, jm_phys - 1, jm_phys - 2);
2561 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][jm_phys - 1][i_mid]);
2562 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);
2564 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, J-DIR]: Jdx %2d (Ghost for Cell[k][%d][i]) = ", rank, jm_phys, jm_phys - 2);
2565 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[k_mid][jm_phys][i_mid]);
2566 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);
2571 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Ghost for Cell[0][j][i]) = ", rank, 0);
2572 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[0][j_mid][i_mid]);
2573 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);
2574 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Value for Cell[0][j][i]) = ", rank, 1);
2575 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[1][j_mid][i_mid]);
2576 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);
2578 if (info.zs + info.zm == info.mz) {
2579 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Value for Cell[%d][j][i]) = ", rank, km_phys - 1, km_phys - 2);
2580 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[km_phys - 1][j_mid][i_mid]);
2581 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);
2582 PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"[Rank %d, K-DIR]: Kdx %2d (Ghost for Cell[%d][j][i]) = ", rank, km_phys, km_phys - 2);
2583 if(dof==1) PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"(%.5f)\n", ((
const PetscReal***)l_arr)[km_phys][j_mid][i_mid]);
2584 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);
2586 ierr = DMDAVecRestoreArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
2591 else if (strcmp(data_layout,
"Face-Centered") == 0) {
2593 ierr = DMDAVecGetArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
2597 if (dominant_dir ==
'x') {
2598 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);
2599 }
else if (dominant_dir ==
'y' || dominant_dir ==
'z') {
2600 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);
2601 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);
2602 }
else if (dominant_dir ==
'm') {
2603 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);
2606 if (info.xs + info.xm == info.mx) {
2607 if (dominant_dir ==
'x') {
2608 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);
2609 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);
2610 }
else if (dominant_dir ==
'y' || dominant_dir ==
'z') {
2611 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);
2612 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);
2613 }
else if (dominant_dir ==
'm') {
2614 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);
2615 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);
2621 if (dominant_dir ==
'y') {
2622 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);
2623 }
else if (dominant_dir ==
'x' || dominant_dir ==
'z') {
2624 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);
2625 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);
2626 }
else if (dominant_dir ==
'm') {
2627 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);
2630 if (info.ys + info.ym == info.my) {
2631 if (dominant_dir ==
'y') {
2632 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);
2633 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);
2634 }
else if (dominant_dir ==
'x' || dominant_dir ==
'z') {
2635 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);
2636 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);
2637 }
else if (dominant_dir ==
'm') {
2638 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);
2639 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);
2645 if (dominant_dir ==
'z') {
2646 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);
2647 }
else if (dominant_dir ==
'x' || dominant_dir ==
'y') {
2648 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);
2649 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);
2650 }
else if (dominant_dir ==
'm') {
2651 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);
2654 if (info.zs + info.zm == info.mz) {
2655 if (dominant_dir ==
'z') {
2656 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);
2657 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);
2658 }
else if (dominant_dir ==
'x' || dominant_dir ==
'y') {
2659 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);
2660 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);
2661 }
else if (dominant_dir ==
'm') {
2662 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);
2663 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);
2667 ierr = DMDAVecRestoreArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
2672 else if (strcmp(data_layout,
"Node-Centered") == 0) {
2674 ierr = DMDAVecGetArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
2678 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);
2680 if (info.xs + info.xm == info.mx) {
2681 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);
2682 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);
2686 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);
2688 if (info.ys + info.ym == info.my) {
2689 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);
2690 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);
2694 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);
2696 if(info.zs + info.zm == info.mz) {
2697 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);
2698 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);
2700 ierr = DMDAVecRestoreArrayRead(dm, vec_local, (
void*)&l_arr); CHKERRQ(ierr);
2703 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONG,
"LOG_FIELD_ANATOMY encountered an unknown data layout: %s", data_layout);
2706 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
2707 ierr = PetscBarrier(NULL);
2708 PetscFunctionReturn(0);
2797 PetscErrorCode ierr;
2800 PetscInt xs, xe, ys, ye, zs, ze, mx, my, mz;
2801 PetscInt lxs, lxe, lys, lye, lzs, lze;
2802 Vec reference_vec = NULL;
2803 PetscReal ***psi = NULL;
2804 PetscReal ***psi_ref = NULL;
2805 PetscReal ***aj = NULL;
2806 PetscReal ***count = NULL;
2807 PetscReal *particle_psi = NULL;
2808 PetscInt nlocal = 0;
2809 PetscReal local_l1 = 0.0, global_l1 = 0.0;
2810 PetscReal local_l2_sq = 0.0, global_l2_sq = 0.0;
2811 PetscReal local_linf = 0.0, global_linf = 0.0;
2812 PetscReal local_ref_l2_sq = 0.0, global_ref_l2_sq = 0.0;
2813 PetscReal local_grid_integral = 0.0, global_grid_integral = 0.0;
2814 PetscReal local_domain_volume = 0.0, global_domain_volume = 0.0;
2815 PetscReal local_particle_sum = 0.0, global_particle_sum = 0.0;
2816 PetscInt64 local_particle_count = 0, global_particle_count = 0;
2817 PetscInt64 local_cell_count = 0, global_cell_count = 0;
2818 PetscInt64 local_occupied_count = 0, global_occupied_count = 0;
2819 PetscReal particle_integral = 0.0;
2820 PetscReal occupancy_fraction = 0.0;
2821 PetscReal mean_particles_per_occupied_cell = 0.0;
2822 PetscReal l2_error = 0.0;
2823 PetscReal relative_l2_error = 0.0;
2825 PetscFunctionBeginUser;
2826 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"UserCtx cannot be NULL.");
2829 PetscFunctionReturn(0);
2833 xs = info.xs; xe = info.xs + info.xm;
2834 ys = info.ys; ye = info.ys + info.ym;
2835 zs = info.zs; ze = info.zs + info.zm;
2836 mx = info.mx; my = info.my; mz = info.mz;
2837 lxs = (xs == 0) ? xs + 1 : xs; lxe = (xe == mx) ? xe - 1 : xe;
2838 lys = (ys == 0) ? ys + 1 : ys; lye = (ye == my) ? ye - 1 : ye;
2839 lzs = (zs == 0) ? zs + 1 : zs; lze = (ze == mz) ? ze - 1 : ze;
2841 ierr = VecDuplicate(user->
Psi, &reference_vec); CHKERRQ(ierr);
2844 ierr = DMDAVecGetArrayRead(user->
da, user->
Psi, &psi); CHKERRQ(ierr);
2845 ierr = DMDAVecGetArrayRead(user->
da, reference_vec, &psi_ref); CHKERRQ(ierr);
2846 ierr = DMDAVecGetArrayRead(user->
da, user->
Aj, &aj); CHKERRQ(ierr);
2847 ierr = DMDAVecGetArrayRead(user->
da, user->
ParticleCount, &count); CHKERRQ(ierr);
2849 for (PetscInt k = lzs; k < lze; ++k) {
2850 for (PetscInt j = lys; j < lye; ++j) {
2851 for (PetscInt i = lxs; i < lxe; ++i) {
2852 const PetscReal cell_volume = (PetscAbsReal(aj[k][j][i]) > 1.0e-14) ? (1.0 / aj[k][j][i]) : 0.0;
2853 const PetscReal err = psi[k][j][i] - psi_ref[k][j][i];
2854 local_cell_count += 1;
2855 local_domain_volume += cell_volume;
2856 local_grid_integral += psi[k][j][i] * cell_volume;
2857 local_l1 += PetscAbsReal(err) * cell_volume;
2858 local_l2_sq += err * err * cell_volume;
2859 local_ref_l2_sq += psi_ref[k][j][i] * psi_ref[k][j][i] * cell_volume;
2860 local_linf = PetscMax(local_linf, PetscAbsReal(err));
2861 if (count[k][j][i] > 0.0) local_occupied_count += 1;
2866 ierr = DMDAVecRestoreArrayRead(user->
da, user->
ParticleCount, &count); CHKERRQ(ierr);
2867 ierr = DMDAVecRestoreArrayRead(user->
da, user->
Aj, &aj); CHKERRQ(ierr);
2868 ierr = DMDAVecRestoreArrayRead(user->
da, reference_vec, &psi_ref); CHKERRQ(ierr);
2869 ierr = DMDAVecRestoreArrayRead(user->
da, user->
Psi, &psi); CHKERRQ(ierr);
2870 ierr = VecDestroy(&reference_vec); CHKERRQ(ierr);
2872 ierr = DMSwarmGetLocalSize(user->
swarm, &nlocal); CHKERRQ(ierr);
2873 local_particle_count = (PetscInt64)nlocal;
2875 ierr = DMSwarmGetField(user->
swarm,
"Psi", NULL, NULL, (
void **)&particle_psi); CHKERRQ(ierr);
2876 for (PetscInt p = 0; p < nlocal; ++p) local_particle_sum += particle_psi[p];
2877 ierr = DMSwarmRestoreField(user->
swarm,
"Psi", NULL, NULL, (
void **)&particle_psi); CHKERRQ(ierr);
2880 ierr = MPI_Allreduce(&local_l1, &global_l1, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2881 ierr = MPI_Allreduce(&local_l2_sq, &global_l2_sq, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2882 ierr = MPI_Allreduce(&local_linf, &global_linf, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2883 ierr = MPI_Allreduce(&local_ref_l2_sq, &global_ref_l2_sq, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2884 ierr = MPI_Allreduce(&local_grid_integral, &global_grid_integral, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2885 ierr = MPI_Allreduce(&local_domain_volume, &global_domain_volume, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2886 ierr = MPI_Allreduce(&local_particle_sum, &global_particle_sum, 1, MPIU_REAL, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2887 ierr = MPI_Allreduce(&local_particle_count, &global_particle_count, 1, MPIU_INT64, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2888 ierr = MPI_Allreduce(&local_cell_count, &global_cell_count, 1, MPIU_INT64, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2889 ierr = MPI_Allreduce(&local_occupied_count, &global_occupied_count, 1, MPIU_INT64, MPI_SUM, PETSC_COMM_WORLD); CHKERRMPI(ierr);
2891 l2_error = PetscSqrtReal(global_l2_sq);
2892 relative_l2_error = (global_ref_l2_sq > 0.0) ? (l2_error / PetscSqrtReal(global_ref_l2_sq)) : 0.0;
2893 occupancy_fraction = (global_cell_count > 0) ? ((PetscReal)global_occupied_count / (PetscReal)global_cell_count) : 0.0;
2894 mean_particles_per_occupied_cell =
2895 (global_occupied_count > 0) ? ((PetscReal)global_particle_count / (PetscReal)global_occupied_count) : 0.0;
2897 (global_particle_count > 0) ? (global_domain_volume * global_particle_sum / (PetscReal)global_particle_count) : 0.0;
2899 if (simCtx->
rank == 0) {
2900 char csv_path[PETSC_MAX_PATH_LEN + 32];
2902 ierr = PetscSNPrintf(csv_path,
sizeof(csv_path),
"%s/scatter_metrics.csv", simCtx->
log_dir); CHKERRQ(ierr);
2903 f = fopen(csv_path,
"a");
2905 if (ftell(f) == 0) {
2907 "step,time,total_particles,total_cells,occupied_cells,occupancy_fraction,"
2908 "mean_particles_per_occupied_cell,particle_integral,grid_integral,"
2909 "conservation_error_abs,L1_error,L2_error,Linf_error,relative_L2_error\n");
2911 fprintf(f,
"%d,%.6e,%lld,%lld,%lld,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e,%.6e\n",
2914 (
long long)global_particle_count,
2915 (
long long)global_cell_count,
2916 (
long long)global_occupied_count,
2917 (
double)occupancy_fraction,
2918 (
double)mean_particles_per_occupied_cell,
2919 (
double)particle_integral,
2920 (
double)global_grid_integral,
2921 (
double)PetscAbsReal(global_grid_integral - particle_integral),
2924 (
double)global_linf,
2925 (
double)relative_l2_error);
2935 PetscFunctionReturn(0);