5#define TMP_BUF_SIZE 128
51 const char *env = getenv(
"LOG_LEVEL");
55 else if (strcmp(env,
"DEBUG") == 0) {
58 else if (strcmp(env,
"INFO") == 0) {
61 else if (strcmp(env,
"WARNING") == 0) {
64 else if (strcmp(env,
"PROFILE") == 0) {
91 const char *level_name;
93 PetscFunctionBeginUser;
95 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRMPI(ierr);
99 level_name = (level ==
LOG_ERROR) ?
"ERROR" :
106 ierr = PetscPrintf(PETSC_COMM_SELF,
107 "Current log level: %s (%d) | rank: %d\n",
108 level_name, level, (
int)rank);
111 PetscFunctionReturn(PETSC_SUCCESS);
142 for (
int i = 0; i < count; ++i) {
195 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"LOG_CELL_VERTICES - Input parameter 'cell' is NULL.");
199 for(
int i = 0; i < 8; i++){
235 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
" LOG_FACE_DISTANCES - Input array 'd' is NULL.");
238 PetscPrintf(PETSC_COMM_SELF,
" LOG_FACE_DISTANCES - Face Distances:\n");
239 PetscPrintf(PETSC_COMM_SELF,
" LEFT(%d): %.15f\n",
LEFT, d[
LEFT]);
240 PetscPrintf(PETSC_COMM_SELF,
" RIGHT(%d): %.15f\n",
RIGHT, d[
RIGHT]);
241 PetscPrintf(PETSC_COMM_SELF,
" BOTTOM(%d): %.15f\n",
BOTTOM, d[
BOTTOM]);
242 PetscPrintf(PETSC_COMM_SELF,
" TOP(%d): %.15f\n",
TOP, d[
TOP]);
243 PetscPrintf(PETSC_COMM_SELF,
" FRONT(%d): %.15f\n",
FRONT, d[
FRONT]);
244 PetscPrintf(PETSC_COMM_SELF,
" BACK(%d): %.15f\n",
BACK, d[
BACK]);
252static void IntToStr(
int value,
char *buf,
size_t bufsize)
254 snprintf(buf, bufsize,
"%d", value);
260static void Int64ToStr(PetscInt64 value,
char *buf,
size_t bufsize)
262 snprintf(buf, bufsize,
"%ld", value);
268static void CellToStr(
const PetscInt *cell,
char *buf,
size_t bufsize)
270 snprintf(buf, bufsize,
"(%d, %d, %d)", cell[0], cell[1], cell[2]);
278 snprintf(buf, bufsize,
"(%.4f, %.4f, %.4f)", arr[0], arr[1], arr[2]);
302 const PetscMPIInt *ranks,
303 const PetscInt64 *pids,
304 const PetscInt *cellIDs,
305 const PetscReal *positions,
306 const PetscReal *velocities,
307 const PetscReal *weights,
308 int *wRank,
int *wPID,
int *wCell,
309 int *wPos,
int *wVel,
int *wWt)
313 *wRank = strlen(
"Rank");
314 *wPID = strlen(
"PID");
315 *wCell = strlen(
"Cell (i,j,k)");
316 *wPos = strlen(
"Position (x,y,z)");
317 *wVel = strlen(
"Velocity (x,y,z)");
318 *wWt = strlen(
"Weights (a1,a2,a3)");
320 for (PetscInt i = 0; i < nParticles; i++) {
323 if ((
int)strlen(tmp) > *wRank) *wRank = (int)strlen(tmp);
327 if ((
int)strlen(tmp) > *wPID) *wPID = (int)strlen(tmp);
331 if ((
int)strlen(tmp) > *wCell) *wCell = (int)strlen(tmp);
335 if ((
int)strlen(tmp) > *wPos) *wPos = (int)strlen(tmp);
339 if ((
int)strlen(tmp) > *wVel) *wVel = (int)strlen(tmp);
343 if ((
int)strlen(tmp) > *wWt) *wWt = (int)strlen(tmp);
365static void BuildRowFormatString(PetscMPIInt wRank, PetscInt wPID, PetscInt wCell, PetscInt wPos, PetscInt wVel, PetscInt wWt,
char *fmtStr,
size_t bufSize)
370 snprintf(fmtStr, bufSize,
371 "| %%-%dd | %%-%dd | %%-%ds | %%-%ds | %%-%ds | %%-%ds |\n",
372 wRank, wPID, wCell, wPos, wVel, wWt);
378static void BuildHeaderString(
char *headerStr,
size_t bufSize, PetscMPIInt wRank, PetscInt wPID, PetscInt wCell, PetscInt wPos, PetscInt wVel, PetscInt wWt)
380 snprintf(headerStr, bufSize,
381 "| %-*s | %-*s | %-*s | %-*s | %-*s | %-*s |\n",
384 (
int)wCell,
"Cell (i,j,k)",
385 (
int)wPos,
"Position (x,y,z)",
386 (
int)wVel,
"Velocity (x,y,z)",
387 (
int)wWt,
"Weights (a1,a2,a3)");
404 DM swarm = user->
swarm;
406 PetscInt localNumParticles;
407 PetscReal *positions = NULL;
408 PetscInt64 *particleIDs = NULL;
409 PetscMPIInt *particleRanks = NULL;
410 PetscInt *cellIDs = NULL;
411 PetscReal *weights = NULL;
412 PetscReal *velocities = NULL;
415 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
418 ierr = DMSwarmGetLocalSize(swarm, &localNumParticles); CHKERRQ(ierr);
421 ierr = DMSwarmGetField(swarm,
"position", NULL, NULL, (
void**)&positions); CHKERRQ(ierr);
422 ierr = DMSwarmGetField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&particleIDs); CHKERRQ(ierr);
423 ierr = DMSwarmGetField(swarm,
"DMSwarm_rank", NULL, NULL, (
void**)&particleRanks); CHKERRQ(ierr);
424 ierr = DMSwarmGetField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
425 ierr = DMSwarmGetField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
426 ierr = DMSwarmGetField(swarm,
"velocity", NULL, NULL, (
void**)&velocities); CHKERRQ(ierr);
429 int wRank, wPID, wCell, wPos, wVel, wWt;
430 wRank = wPID = wCell = wPos = wVel = wWt = 0;
432 positions, velocities, weights,
433 &wRank, &wPID, &wCell, &wPos, &wVel, &wWt); CHKERRQ(ierr);
438 BuildHeaderString(headerFmt,
sizeof(headerFmt), wRank, wPID, wCell, wPos, wVel, wWt);
442 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"--------------------------------------------------------------------------------------------------------------\n"); CHKERRQ(ierr);
443 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"%s", headerFmt); CHKERRQ(ierr);
444 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"--------------------------------------------------------------------------------------------------------------\n"); CHKERRQ(ierr);
448 for (PetscInt i = 0; i < localNumParticles; i++) {
449 if (i % printInterval == 0) {
493 snprintf(rowStr,
sizeof(rowStr), rowFmt,
500 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"%s", rowStr); CHKERRQ(ierr);
505 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"--------------------------------------------------------------------------------------------------------------\n"); CHKERRQ(ierr);
506 ierr = PetscSynchronizedPrintf(PETSC_COMM_WORLD,
"\n"); CHKERRQ(ierr);
507 ierr = PetscSynchronizedFlush(PETSC_COMM_WORLD, PETSC_STDOUT); CHKERRQ(ierr);
512 ierr = DMSwarmRestoreField(swarm,
"position", NULL, NULL, (
void**)&positions); CHKERRQ(ierr);
513 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_pid", NULL, NULL, (
void**)&particleIDs); CHKERRQ(ierr);
514 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_rank", NULL, NULL, (
void**)&particleRanks); CHKERRQ(ierr);
515 ierr = DMSwarmRestoreField(swarm,
"DMSwarm_CellID", NULL, NULL, (
void**)&cellIDs); CHKERRQ(ierr);
516 ierr = DMSwarmRestoreField(swarm,
"weight", NULL, NULL, (
void**)&weights); CHKERRQ(ierr);
517 ierr = DMSwarmRestoreField(swarm,
"velocity", NULL, NULL, (
void**)&velocities); CHKERRQ(ierr);
530 while (*p && isspace((
unsigned char)*p))
534 memmove(s, p, strlen(p) + 1);
537 size_t len = strlen(s);
538 while (len > 0 && isspace((
unsigned char)s[len - 1]))
576 char line[PETSC_MAX_PATH_LEN];
583 fp = fopen(filename,
"r");
584 if (!fp) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
585 "Cannot open %s", filename);
588 ierr = PetscMalloc1(cap, &funcs); CHKERRQ(ierr);
591 while (fgets(line,
sizeof line, fp)) {
593 char *hash = strchr(line,
'#');
594 if (hash) *hash =
'\0';
597 if (!*line)
continue;
602 ierr = PetscRealloc(cap *
sizeof(*funcs), (
void **)&funcs); CHKERRQ(ierr);
606 ierr = PetscStrallocpy(line, &funcs[n++]); CHKERRQ(ierr);
614 PetscFunctionReturn(0);
632 for (PetscInt i = 0; i < n; ++i) {
633 ierr = PetscFree(funcs[i]); CHKERRQ(ierr);
635 ierr = PetscFree(funcs); CHKERRQ(ierr);
637 PetscFunctionReturn(0);
653 default:
return "Unknown Face";
666 case WALL:
return "WALL";
667 case INLET:
return "INLET";
668 case OUTLET:
return "OUTLET";
672 case NOGRAD:
return "NOGRAD";
675 default:
return "Unknown BC Type";
690 switch (handler_type) {
715 default:
return "UNKNOWN_HANDLER";
733 PetscFunctionBeginUser;
734 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr);
739 ierr = PetscFree(monctx); CHKERRQ(ierr);
741 PetscFunctionReturn(0);
758#define __FUNCT__ "DualKSPMonitor"
763 PetscReal trnorm, relnorm;
768 PetscFunctionBeginUser;
769 ierr = MPI_Comm_rank(PETSC_COMM_WORLD,&rank); CHKERRQ(ierr);
772 ierr = KSPBuildResidual(ksp, NULL, NULL, &r); CHKERRQ(ierr);
773 ierr = VecNorm(r, NORM_2, &trnorm); CHKERRQ(ierr);
778 ierr = KSPGetRhs(ksp, &b); CHKERRQ(ierr);
779 ierr = VecNorm(b, NORM_2, &monctx->
bnorm); CHKERRQ(ierr);
784 if (monctx->
bnorm > 1.e-15) {
785 relnorm = trnorm / monctx->
bnorm;
786 sprintf(norm_buf,
"ts: %-5d | block: %-2d | iter: %-3d | Unprecond Norm: %12.5e | True Norm: %12.5e | Rel Norm: %12.5e",(
int)monctx->
step, (
int)monctx->
block_id, (
int)it, (
double)rnorm, (
double)trnorm, (
double)relnorm);
788 sprintf(norm_buf,
"ts: %-5d | block: %-2d | iter: %-3d | Unprecond Norm: %12.5e | True Norm: %12.5e",(
int)monctx->
step, (
int)monctx->
block_id, (
int)it, (
double)rnorm, (
double)trnorm);
793 ierr = PetscFPrintf(PETSC_COMM_SELF,monctx->
file_handle,
"%s\n", norm_buf); CHKERRQ(ierr);
797 PetscFPrintf(PETSC_COMM_SELF,stdout,
"%s\n", norm_buf); CHKERRQ(ierr);
802 PetscFunctionReturn(0);
818#define __FUNCT__ "LOG_CONTINUITY_METRICS"
824 const PetscInt bi = user->
_this;
825 const PetscInt ti = simCtx->
step;
827 PetscFunctionBeginUser;
828 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
834 sprintf(filen,
"logs/Continuity_Metrics.log");
837 f = fopen(filen,
"a");
839 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Cannot open log file: %s", filen);
844 if (ti == simCtx->
StartStep && bi == 0) {
845 PetscFPrintf(PETSC_COMM_SELF, f,
"%-10s | %-6s | %-18s | %-30s | %-18s | %-18s | %-18s | %-18s\n",
846 "Timestep",
"Block",
"Max Divergence",
"Max Divergence Location ([k][j][i]=idx)",
"Sum(RHS)",
"Total Flux In",
"Total Flux Out",
"Net Flux");
847 PetscFPrintf(PETSC_COMM_SELF, f,
"------------------------------------------------------------------------------------------------------------------------------------------\n");
852 char location_str[64];
856 PetscFPrintf(PETSC_COMM_SELF, f,
"%-10d | %-6d | %-18.10e | %-39s | %-18.10e | %-18.10e | %-18.10e | %-18.10e\n",
869 PetscFunctionReturn(0);
884 case LOST:
return "LOST";
886 default:
return "UNKNOWN_LEVEL";
911 PetscFunctionBeginUser;
916 PetscFunctionReturn(0);
937 PetscFunctionReturn(0);
957 PetscFunctionBeginUser;
958 if (!simCtx) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx cannot be null for ProfilingInitialize");
969 PetscFunctionReturn(0);
982 PetscTime(&end_time);
997 PetscBool should_print = PETSC_FALSE;
999 PetscFunctionBeginUser;
1006 should_print = PETSC_TRUE;
1014 PetscPrintf(MPI_COMM_WORLD,
"[PROFILE] ----- Timestep %d Summary -----\n", step);
1018 PetscPrintf(MPI_COMM_WORLD,
"[PROFILE] %-25s: %.6f s (%lld calls)\n",
1032 PetscFunctionReturn(0);
1048 PetscFunctionBeginUser;
1055 PetscInt max_name_len = strlen(
"Function");
1059 if (len > max_name_len) {
1068 const int time_width = 18;
1069 const int count_width = 15;
1070 const int avg_width = 22;
1073 PetscPrintf(MPI_COMM_WORLD,
"\n=======================================================================================\n");
1074 PetscPrintf(MPI_COMM_WORLD,
" FINAL PROFILING SUMMARY (Sorted by Total Time)\n");
1075 PetscPrintf(MPI_COMM_WORLD,
"=======================================================================================\n");
1078 PetscPrintf(MPI_COMM_WORLD,
"%-*s | %-*s | %-*s | %-*s\n",
1079 max_name_len,
"Function",
1080 time_width,
"Total Time (s)",
1081 count_width,
"Call Count",
1082 avg_width,
"Avg. Time/Call (ms)");
1085 for (
int i = 0; i < max_name_len; i++) PetscPrintf(MPI_COMM_WORLD,
"-");
1086 PetscPrintf(MPI_COMM_WORLD,
"-|-");
1087 for (
int i = 0; i < time_width; i++) PetscPrintf(MPI_COMM_WORLD,
"-");
1088 PetscPrintf(MPI_COMM_WORLD,
"-|-");
1089 for (
int i = 0; i < count_width; i++) PetscPrintf(MPI_COMM_WORLD,
"-");
1090 PetscPrintf(MPI_COMM_WORLD,
"-|-");
1091 for (
int i = 0; i < avg_width; i++) PetscPrintf(MPI_COMM_WORLD,
"-");
1092 PetscPrintf(MPI_COMM_WORLD,
"\n");
1098 PetscPrintf(MPI_COMM_WORLD,
"%-*s | %*.*f | %*lld | %*.*f\n",
1102 avg_width, 6, avg_time_ms);
1105 PetscPrintf(MPI_COMM_WORLD,
"=======================================================================================\n");
1113 PetscFunctionReturn(0);
PetscLogEvent EVENT_walkingsearch
void set_allowed_functions(const char **functionList, int count)
Sets the global list of function names that are allowed to log.
const char * BCHandlerTypeToString(BCHandlerType handler_type)
Converts a BCHandlerType enum to its string representation.
PetscBool is_function_allowed(const char *functionName)
Checks if the given function name is in the allow-list.
static PetscInt g_profiler_count
PetscErrorCode DualMonitorDestroy(void **ctx)
Destroys the DualMonitorCtx.
static char ** gAllowedFunctions
Global/static array of function names allowed to log.
static LogLevel current_log_level
Static variable to cache the current logging level.
const char * BCFaceToString(BCFace face)
Helper function to convert BCFace enum to a string representation.
PetscErrorCode FreeAllowedFunctions(char **funcs, PetscInt n)
Free an array previously returned by LoadAllowedFunctionsFromFile().
PetscErrorCode print_log_level(void)
Prints the current logging level to the console.
long long total_call_count
static PetscInt g_profiler_capacity
static void BuildRowFormatString(PetscMPIInt wRank, PetscInt wPID, PetscInt wCell, PetscInt wPos, PetscInt wVel, PetscInt wWt, char *fmtStr, size_t bufSize)
PetscLogEvent EVENT_IndividualLocation
static void trim(char *s)
PetscErrorCode LoadAllowedFunctionsFromFile(const char filename[], char ***funcsOut, PetscInt *nOut)
Load function names from a text file.
static int gNumAllowed
Number of entries in the gAllowedFunctions array.
static void BuildHeaderString(char *headerStr, size_t bufSize, PetscMPIInt wRank, PetscInt wPID, PetscInt wCell, PetscInt wPos, PetscInt wVel, PetscInt wWt)
static PetscErrorCode _FindOrCreateEntry(const char *func_name, PetscInt *idx)
static void CellToStr(const PetscInt *cell, char *buf, size_t bufsize)
LogLevel get_log_level()
Retrieves the current logging level from the environment variable LOG_LEVEL.
PetscErrorCode LOG_FACE_DISTANCES(PetscReal *d)
Prints the signed distances to each face of the cell.
PetscErrorCode LOG_PARTICLE_FIELDS(UserCtx *user, PetscInt printInterval)
Prints particle fields in a table that automatically adjusts its column widths.
void _ProfilingEnd(const char *func_name)
static void TripleRealToStr(const PetscReal *arr, char *buf, size_t bufsize)
static void Int64ToStr(PetscInt64 value, char *buf, size_t bufsize)
const char * BCTypeToString(BCType type)
Helper function to convert BCType enum to a string representation.
const char * ParticleLocationStatusToString(ParticleLocationStatus level)
A function that outputs the name of the current level in the ParticleLocation enum.
static int _CompareProfiledFunctions(const void *a, const void *b)
PetscErrorCode DualKSPMonitor(KSP ksp, PetscInt it, PetscReal rnorm, void *ctx)
A custom KSP monitor that logs to a file and optionally to the console.
PetscErrorCode LOG_CONTINUITY_METRICS(UserCtx *user)
Logs continuity metrics for a single block to a file.
long long current_step_call_count
PetscErrorCode ProfilingFinalize(void)
Prints the final, cumulative performance summary and cleans up resources.
static ProfiledFunction * g_profiler_registry
PetscErrorCode ProfilingInitialize(SimCtx *simCtx)
Initializes the custom profiling system using configuration from SimCtx.
PetscErrorCode LOG_CELL_VERTICES(const Cell *cell, PetscMPIInt rank)
Prints the coordinates of a cell's vertices.
static void IntToStr(int value, char *buf, size_t bufsize)
static PetscErrorCode ComputeMaxColumnWidths(PetscInt nParticles, const PetscMPIInt *ranks, const PetscInt64 *pids, const PetscInt *cellIDs, const PetscReal *positions, const PetscReal *velocities, const PetscReal *weights, int *wRank, int *wPID, int *wCell, int *wPos, int *wVel, int *wWt)
PetscLogEvent EVENT_GlobalParticleLocation
PetscLogEvent EVENT_Individualwalkingsearch
PetscErrorCode ProfilingLogTimestepSummary(PetscInt step)
Logs the performance summary for the current timestep and resets timers.
void _ProfilingStart(const char *func_name)
Logging utilities and macros for PETSc-based applications.
#define LOG_ALLOW_SYNC(scope, level, fmt,...)
----β DEBUG ---------------------------------------β #define LOG_ALLOW(scope, level,...
#define LOCAL
Logging scope definitions for controlling message output.
#define GLOBAL
Scope for global logging across all processes.
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
LogLevel
Enumeration of logging levels.
@ LOG_ERROR
Critical errors that may halt the program.
@ LOG_PROFILE
Exclusive log level for performance timing and profiling.
@ LOG_INFO
Informational messages about program execution.
@ LOG_WARNING
Non-critical issues that warrant attention.
@ LOG_DEBUG
Detailed debugging information.
Context for a dual-purpose KSP monitor.
BCType
Defines the general mathematical/physical category of a boundary.
SimCtx * simCtx
Back-pointer to the master simulation context.
ParticleLocationStatus
Defines the state of a particle with respect to its location and migration status during the iterativ...
BCHandlerType
Defines the specific computational "strategy" for a boundary handler.
@ BC_HANDLER_INLET_PULSANTILE_FLUX
@ BC_HANDLER_INLET_PARABOLIC
@ BC_HANDLER_INLET_CONSTANT_VELOCITY
@ BC_HANDLER_INTERFACE_OVERSET
@ BC_HANDLER_NOGRAD_COPY_GHOST
@ BC_HANDLER_OUTLET_CONSERVATION
@ BC_HANDLER_FARFIELD_NONREFLECTING
@ BC_HANDLER_OUTLET_PRESSURE
@ BC_HANDLER_SYMMETRY_PLANE
Cmpnts vertices[8]
Coordinates of the eight vertices of the cell.
BCFace
Identifies the six logical faces of a structured computational block.
Defines the vertices of a single hexahedral grid cell.
The master context for the entire simulation.
User-defined context containing data specific to a single computational grid level.