43 while (isspace((
unsigned char)*start)) {
48 char *end = str + strlen(str) - 1;
50 while (end > start && isspace((
unsigned char)*end)) {
59 memmove(str, start, (end - start) + 2);
75 return (PetscBool)(simCtx->
tiout > 0 && completed_step > 0 && completed_step % simCtx->
tiout == 0);
80#define __FUNCT__ "ReadGridGenerationInputs"
90 PetscInt block_index = user->
_this;
94 PetscInt *IMs = NULL, *JMs = NULL, *KMs = NULL, *cgrids = NULL;
95 PetscReal *xMins = NULL, *xMaxs = NULL, *rxs = NULL;
96 PetscReal *yMins = NULL, *yMaxs = NULL, *rys = NULL;
97 PetscReal *zMins = NULL, *zMaxs = NULL, *rzs = NULL;
99 PetscFunctionBeginUser;
104 if (block_index >= nblk) {
105 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
"Block index %d is out of range for nblk=%d", block_index, nblk);
109 ierr = PetscMalloc4(nblk, &IMs, nblk, &JMs, nblk, &KMs, nblk, &cgrids); CHKERRQ(ierr);
110 ierr = PetscMalloc6(nblk, &xMins, nblk, &xMaxs, nblk, &rxs, nblk, &yMins, nblk, &yMaxs, nblk, &rys); CHKERRQ(ierr);
111 ierr = PetscMalloc3(nblk, &zMins, nblk, &zMaxs, nblk, &rzs); CHKERRQ(ierr);
114 for (PetscInt i = 0; i < nblk; ++i) {
115 IMs[i] = 10; JMs[i] = 10; KMs[i] = 10; cgrids[i] = 0;
116 xMins[i] = 0.0; xMaxs[i] = 1.0; rxs[i] = 1.0;
117 yMins[i] = 0.0; yMaxs[i] = 1.0; rys[i] = 1.0;
118 zMins[i] = 0.0; zMaxs[i] = 1.0; rzs[i] = 1.0;
123 count = nblk; ierr = PetscOptionsGetIntArray(NULL, NULL,
"-im", IMs, &count, &found); CHKERRQ(ierr);
124 count = nblk; ierr = PetscOptionsGetIntArray(NULL, NULL,
"-jm", JMs, &count, &found); CHKERRQ(ierr);
125 count = nblk; ierr = PetscOptionsGetIntArray(NULL, NULL,
"-km", KMs, &count, &found); CHKERRQ(ierr);
126 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-xMins", xMins, &count, &found); CHKERRQ(ierr);
127 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-xMaxs", xMaxs, &count, &found); CHKERRQ(ierr);
128 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-rxs", rxs, &count, &found); CHKERRQ(ierr);
129 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-yMins", yMins, &count, &found); CHKERRQ(ierr);
130 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-yMaxs", yMaxs, &count, &found); CHKERRQ(ierr);
131 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-rys", rys, &count, &found); CHKERRQ(ierr);
132 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-zMins", zMins, &count, &found); CHKERRQ(ierr);
133 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-zMaxs", zMaxs, &count, &found); CHKERRQ(ierr);
134 count = nblk; ierr = PetscOptionsGetRealArray(NULL, NULL,
"-rzs", rzs, &count, &found); CHKERRQ(ierr);
135 count = nblk; ierr = PetscOptionsGetIntArray(NULL, NULL,
"-cgrids", cgrids, &count, &found); CHKERRQ(ierr);
138 user->
IM = IMs[block_index];
139 user->
JM = JMs[block_index];
140 user->
KM = KMs[block_index];
141 user->
Min_X = xMins[block_index];
142 user->
Max_X = xMaxs[block_index];
143 user->
rx = rxs[block_index];
144 user->
Min_Y = yMins[block_index];
145 user->
Max_Y = yMaxs[block_index];
146 user->
ry = rys[block_index];
147 user->
Min_Z = zMins[block_index];
148 user->
Max_Z = zMaxs[block_index];
149 user->
rz = rzs[block_index];
150 user->
cgrid = cgrids[block_index];
153 simCtx->
rank, block_index, user->
IM, user->
JM, user->
KM);
158 ierr = PetscFree4(IMs, JMs, KMs, cgrids); CHKERRQ(ierr);
159 ierr = PetscFree6(xMins, xMaxs, rxs, yMins, yMaxs, rys); CHKERRQ(ierr);
160 ierr = PetscFree3(zMins, zMaxs, rzs); CHKERRQ(ierr);
163 PetscFunctionReturn(0);
174 PetscInt *IMs = NULL, *JMs = NULL, *KMs = NULL;
177 PetscFunctionBeginUser;
180 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"finest_users cannot be NULL.");
183 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
"nblk must be positive. Got %d.", nblk);
185 simCtx = finest_users[0].
simCtx;
187 ierr = PetscMalloc3(nblk, &IMs, nblk, &JMs, nblk, &KMs); CHKERRQ(ierr);
188 for (PetscInt i = 0; i < nblk; ++i) {
189 IMs[i] = 10; JMs[i] = 10; KMs[i] = 10;
193 count = nblk; ierr = PetscOptionsGetIntArray(NULL, NULL,
"-im", IMs, &count, &found); CHKERRQ(ierr);
194 count = nblk; ierr = PetscOptionsGetIntArray(NULL, NULL,
"-jm", JMs, &count, &found); CHKERRQ(ierr);
195 count = nblk; ierr = PetscOptionsGetIntArray(NULL, NULL,
"-km", KMs, &count, &found); CHKERRQ(ierr);
197 for (PetscInt bi = 0; bi < nblk; ++bi) {
198 finest_users[bi].
IM = IMs[bi];
199 finest_users[bi].
JM = JMs[bi];
200 finest_users[bi].
KM = KMs[bi];
203 "Rank %d: Preloaded analytical grid resolution for block %d: IM=%d, JM=%d, KM=%d\n",
204 simCtx->
rank, bi, finest_users[bi].
IM, finest_users[bi].
JM, finest_users[bi].
KM);
208 ierr = PetscFree3(IMs, JMs, KMs); CHKERRQ(ierr);
209 PetscFunctionReturn(0);
214#define __FUNCT__ "ReadGridFile"
223 PetscInt block_index = user->
_this;
225 PetscFunctionBeginUser;
231 PetscMPIInt rank = simCtx->
rank;
235 FILE *fd = fopen(simCtx->
grid_file,
"r");
236 if (!fd) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Cannot open file: %s", simCtx->
grid_file);
239 char firstTok[32] = {0};
240 if (fscanf(fd,
"%31s", firstTok) != 1)
241 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
"Empty grid file: %s", simCtx->
grid_file);
242 if (strcmp(firstTok,
"PICGRID") != 0)
243 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
244 "Grid file %s must begin with the canonical PICGRID header.", simCtx->
grid_file);
246 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
"Expected number of blocks after \"PICGRID\" in %s", simCtx->
grid_file);
248 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
"Mismatch: -nblk is %d but grid file specifies %d blocks.", nblk,
g_nblk_from_file);
252 for (PetscInt i = 0; i < nblk; ++i) {
254 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
"Expected 3 integers for block %d in %s", i, simCtx->
grid_file);
261 ierr = MPI_Bcast(&
g_nblk_from_file, 1, MPI_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
269 ierr = MPI_Bcast(
g_IMs_from_file, nblk, MPI_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
270 ierr = MPI_Bcast(
g_JMs_from_file, nblk, MPI_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
271 ierr = MPI_Bcast(
g_KMs_from_file, nblk, MPI_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
283 simCtx->
rank, block_index, user->
IM, user->
JM, user->
KM);
286 PetscFunctionReturn(0);
304 while (current != NULL) {
306 PetscFree(current->
key);
307 PetscFree(current->
value);
319 else if (strcasecmp(str,
"+Xi") == 0) *face_out =
BC_FACE_POS_X;
320 else if (strcasecmp(str,
"-Eta") == 0) *face_out =
BC_FACE_NEG_Y;
321 else if (strcasecmp(str,
"+Eta") == 0) *face_out =
BC_FACE_POS_Y;
322 else if (strcasecmp(str,
"-Zeta") == 0) *face_out =
BC_FACE_NEG_Z;
323 else if (strcasecmp(str,
"+Zeta") == 0) *face_out =
BC_FACE_POS_Z;
324 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE,
"Unknown face specifier: %s", str);
333 if (strcasecmp(str,
"WALL") == 0) *type_out =
WALL;
334 else if (strcasecmp(str,
"SYMMETRY") == 0) *type_out =
SYMMETRY;
335 else if (strcasecmp(str,
"INLET") == 0) *type_out =
INLET;
336 else if (strcasecmp(str,
"OUTLET") == 0) *type_out =
OUTLET;
337 else if (strcasecmp(str,
"PERIODIC") == 0) *type_out =
PERIODIC;
339 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE,
"Unknown BC Type string: %s", str);
357 else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE,
"Unknown BC Handler string: %s", str);
391 *found = PETSC_FALSE;
397 if (strcasecmp(current->
key, key) == 0) {
398 *value_out = atof(current->
value);
402 current = current->
next;
412 *found = PETSC_FALSE;
413 *value_out = PETSC_FALSE;
418 if (strcasecmp(current->
key, key) == 0) {
423 if (current->
value &&
424 (strcasecmp(current->
value,
"true") == 0 ||
425 strcmp(current->
value,
"1") == 0 ||
426 strcasecmp(current->
value,
"yes") == 0))
428 *value_out = PETSC_TRUE;
430 *value_out = PETSC_FALSE;
434 current = current->
next;
445#define __FUNCT__ "ParseAllBoundaryConditions"
458 PetscFunctionBeginUser;
460 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
464 char line_buffer[1024];
467 for (
int i = 0; i < 6; i++) {
471 configs_rank0[i].
params = NULL;
472 configs_rank0[i].
handler = NULL;
476 file = fopen(bcs_input_filename,
"r");
477 if (!file) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
"Could not open BCs file '%s'.", bcs_input_filename);
479 while (fgets(line_buffer,
sizeof(line_buffer), file)) {
480 char *current_pos = line_buffer;
481 while (isspace((
unsigned char)*current_pos)) current_pos++;
482 if (*current_pos ==
'#' || *current_pos ==
'\0' || *current_pos ==
'\n' || *current_pos ==
'\r')
continue;
484 char *face_str = strtok(current_pos,
" \t\n\r");
485 char *type_str = strtok(NULL,
" \t\n\r");
486 char *handler_str = strtok(NULL,
" \t\n\r");
488 if (!face_str || !type_str || !handler_str) {
496 const char* handler_name_for_log;
503 if (ierr) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"Validation failed: Handler '%s' is not valid for Type '%s' on Face '%s'.\n", handler_str, type_str, face_str);
509 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
" Parsed Face '%s': Type=%s, Handler=%s \n", face_str, type_str, handler_name_for_log);
513 configs_rank0[face_enum].
params = NULL;
517 while ((token = strtok(NULL,
" \t\n\r")) != NULL) {
518 char* equals_ptr = strchr(token,
'=');
525 char* key_str = token;
526 char* value_str = equals_ptr + 1;
529 ierr = PetscMalloc1(1, &new_param); CHKERRQ(ierr);
530 ierr = PetscStrallocpy(key_str, &new_param->
key); CHKERRQ(ierr);
531 ierr = PetscStrallocpy(value_str, &new_param->
value); CHKERRQ(ierr);
532 new_param->
next = NULL;
534 *param_next_ptr = new_param;
535 param_next_ptr = &new_param->
next;
549 for (
int i = 0; i < 6; i++) {
558 PetscInt n_params = 0;
562 ierr = MPI_Bcast(&n_params, 1, MPI_INT, 0, PETSC_COMM_WORLD);CHKERRQ(ierr);
571 for (
int j = 0; j < n_params; j++) {
572 char key_buf[256] = {0}, val_buf[256] = {0};
576 for (
int k = 0; k < j; k++) p = p->
next;
577 strncpy(key_buf, p->
key, 255);
578 strncpy(val_buf, p->
value, 255);
581 ierr = MPI_Bcast(key_buf, 256, MPI_CHAR, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
582 ierr = MPI_Bcast(val_buf, 256, MPI_CHAR, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
587 ierr = PetscMalloc1(1, &new_param); CHKERRQ(ierr);
588 ierr = PetscStrallocpy(key_buf, &new_param->
key); CHKERRQ(ierr);
589 ierr = PetscStrallocpy(val_buf, &new_param->
value); CHKERRQ(ierr);
590 new_param->
next = NULL;
591 *param_next_ptr = new_param;
592 param_next_ptr = &new_param->
next;
595 param_next_ptr = &((*param_next_ptr)->next);
603 for (
int i=0; i<6; i++) {
621 PetscFunctionReturn(0);
632#define __FUNCT__ "DeterminePeriodicity"
641 PetscInt periodic_flags[3] = {0, 0, 0};
643 PetscFunctionBeginUser;
644 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
647 for (PetscInt bi = 0; bi < simCtx->
block_number; bi++) {
648 const char *bcs_filename = simCtx->
bcs_files[bi];
649 if (!bcs_filename) SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL,
"BCS filename for block %d is not set in SimCtx.", bi);
651 PetscBool file_exists;
652 snprintf(desc_buf,
sizeof(desc_buf),
"BCS file for block %d", bi);
653 ierr =
VerifyPathExistence(bcs_filename, PETSC_FALSE, PETSC_FALSE, desc_buf, &file_exists); CHKERRQ(ierr);
658 PetscBool global_is_periodic[3] = {PETSC_FALSE, PETSC_FALSE, PETSC_FALSE};
659 PetscBool is_set = PETSC_FALSE;
661 for (PetscInt bi = 0; bi < simCtx->
block_number; bi++) {
662 const char *bcs_filename = simCtx->
bcs_files[bi];
663 FILE *file = fopen(bcs_filename,
"r");
665 PetscBool face_is_periodic[6] = {PETSC_FALSE};
666 char line_buffer[1024];
668 while (fgets(line_buffer,
sizeof(line_buffer), file)) {
669 char *current_pos = line_buffer;
670 while (isspace((
unsigned char)*current_pos)) current_pos++;
671 if (*current_pos ==
'#' || *current_pos ==
'\0' || *current_pos ==
'\n')
continue;
674 char *face_str = strtok(current_pos,
" \t\n\r");
675 char *type_str = strtok(NULL,
" \t\n\r");
678 if (!face_str || !type_str)
continue;
681 if (strcasecmp(type_str,
"PERIODIC") == 0) {
685 face_is_periodic[face_enum] = PETSC_TRUE;
693 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP,
"Inconsistent X-periodicity in file '%s' for block %d. Both -Xi and +Xi must be periodic or neither.", bcs_filename, bi);
695 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP,
"Inconsistent Y-periodicity in file '%s' for block %d. Both -Eta and +Eta must be periodic or neither.", bcs_filename, bi);
697 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP,
"Inconsistent Z-periodicity in file '%s' for block %d. Both -Zeta and +Zeta must be periodic or neither.", bcs_filename, bi);
703 global_is_periodic[0] = local_is_periodic[0];
704 global_is_periodic[1] = local_is_periodic[1];
705 global_is_periodic[2] = local_is_periodic[2];
708 if (global_is_periodic[0] != local_is_periodic[0] || global_is_periodic[1] != local_is_periodic[1] || global_is_periodic[2] != local_is_periodic[2]) {
709 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_INCOMP,
710 "Periodicity mismatch between blocks. Block 0 requires (I:%d, J:%d, K:%d), but block %d (file '%s') has (I:%d, J:%d, K:%d).",
711 (
int)global_is_periodic[0], (
int)global_is_periodic[1], (
int)global_is_periodic[2],
713 (
int)local_is_periodic[0], (
int)local_is_periodic[1], (
int)local_is_periodic[2]);
718 periodic_flags[0] = (global_is_periodic[0]) ? 1 : 0;
719 periodic_flags[1] = (global_is_periodic[1]) ? 1 : 0;
720 periodic_flags[2] = (global_is_periodic[2]) ? 1 : 0;
723 periodic_flags[0], periodic_flags[1], periodic_flags[2]);
727 ierr = MPI_Bcast(periodic_flags, 3, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
734 PetscFunctionReturn(0);
741PetscErrorCode
VerifyPathExistence(
const char *path, PetscBool is_dir, PetscBool is_optional,
const char *description, PetscBool *exists)
745 MPI_Comm comm = PETSC_COMM_WORLD;
747 PetscFunctionBeginUser;
748 ierr = MPI_Comm_rank(comm, &rank); CHKERRQ(ierr);
752 ierr = PetscTestDirectory(path,
'r', exists); CHKERRQ(ierr);
754 ierr = PetscTestFile(path,
'r', exists); CHKERRQ(ierr);
769 PetscMPIInt exists_int = (rank == 0) ? (PetscMPIInt)(*exists) : 0;
770 ierr = MPI_Bcast(&exists_int, 1, MPI_INT, 0, comm); CHKERRMPI(ierr);
771 *exists = (PetscBool)exists_int;
774 if (!(*exists) && !is_optional) {
775 SETERRQ(comm, PETSC_ERR_FILE_OPEN,
"Mandatory %s not found. Rank 0 expected it at '%s'. Check path and permissions.", description, path);
778 PetscFunctionReturn(0);
785static PetscErrorCode
CheckDataFile(
UserCtx *user, PetscInt ti,
const char *fieldName,
const char *ext, PetscBool *fileExists)
789 MPI_Comm comm = PETSC_COMM_WORLD;
790 PetscInt placeholder_int = 0;
793 PetscFunctionBeginUser;
796 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL,
"I/O context directory is NULL. Ensure it is set before calling CheckDataFile().");
799 ierr = MPI_Comm_rank(comm, &rank); CHKERRQ(ierr);
802 char filename[PETSC_MAX_PATH_LEN];
805 ierr = PetscSNPrintf(filename,
sizeof(filename),
"%s/%s%05"PetscInt_FMT
"_%d.%s",simCtx->
current_io_directory,fieldName, ti, placeholder_int, ext);
806 ierr = PetscTestFile(filename,
'r', fileExists); CHKERRQ(ierr);
807 if (!(*fileExists)) {
814 PetscMPIInt fileExists_int = (rank == 0) ? (PetscMPIInt)(*fileExists) : 0;
815 ierr = MPI_Bcast(&fileExists_int, 1, MPI_INT, 0, comm); CHKERRMPI(ierr);
816 *fileExists = (PetscBool)fileExists_int;
818 PetscFunctionReturn(0);
825static PetscErrorCode
ReadOptionalField(
UserCtx *user,
const char *field_name,
const char *field_label, Vec field_vec, PetscInt ti,
const char *ext)
828 PetscBool fileExists;
830 PetscFunctionBeginUser;
833 ierr =
CheckDataFile(user,ti, field_name, ext, &fileExists); CHKERRQ(ierr);
843 SETERRQ(PETSC_COMM_WORLD, ierr,
"Failed to read data for %s from existing file for step %d. The file may be corrupt or have an incorrect size.", field_label, ti);
852 PetscFunctionReturn(0);
862 PetscBool fileExists;
864 PetscFunctionBeginUser;
867 ierr =
CheckDataFile(user,ti, field_name, ext, &fileExists); CHKERRQ(ierr);
872 if(strcasecmp(field_name,
"DMSwarm_CellID") == 0 || strcasecmp(field_name,
"DMSwarm_pid")== 0 || strcasecmp(field_name,
"DMSwarm_location_status")== 0 ) {
883 SETERRQ(PETSC_COMM_WORLD, ierr,
"Failed to read data for %s from existing file for step %d. The file may be corrupt or have an incorrect size.", field_label, ti);
892 PetscFunctionReturn(0);
896#define __FUNCT__ "ReadFieldData"
902 const char *field_name,
908 char filename[PETSC_MAX_PATH_LEN];
910 PetscMPIInt rank,size;
914 PetscFunctionBeginUser;
918 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,
"I/O context directory was not set before calling ReadFieldData().");
922 ierr = PetscObjectGetComm((PetscObject)field_vec,&comm);CHKERRQ(ierr);
923 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
924 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
926 const char *source_path = NULL;
930 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,
"source_path was not set for the current execution mode.");
936 ierr = PetscSNPrintf(filename,
sizeof(filename),
937 "%s/%s%05" PetscInt_FMT
"_0.%s",
938 source_path,field_name,ti,ext);CHKERRQ(ierr);
941 "Attempting to read <%s> on rank %d/%d\n",
942 filename,(
int)rank,(
int)size);
952 PetscInt expectedSize,loadedSize;
954 ierr = PetscTestFile(filename,
'r',&found);CHKERRQ(ierr);
955 if(!found) SETERRQ(comm,PETSC_ERR_FILE_OPEN,
956 "Restart/Source file not found: %s",filename);
958 ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,filename,FILE_MODE_READ,&viewer);CHKERRQ(ierr);
962 ierr = VecCreate(PETSC_COMM_SELF, &temp_vec); CHKERRQ(ierr);
963 ierr = VecLoad(temp_vec,viewer);CHKERRQ(ierr);
964 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
967 ierr = VecGetSize(field_vec, &expectedSize);CHKERRQ(ierr);
968 ierr = VecGetSize(temp_vec, &loadedSize);CHKERRQ(ierr);
969 if (loadedSize != expectedSize) {
970 SETERRQ(comm,PETSC_ERR_FILE_UNEXPECTED,
971 "File %s holds %d entries – expected %d for field '%s'",
972 filename, loadedSize, expectedSize, field_name);
976 ierr = VecCopy(temp_vec, field_vec);CHKERRQ(ierr);
979 ierr = VecDestroy(&temp_vec);CHKERRQ(ierr);
995 "Loaded <%s> (serial path)\n",filename);
998 PetscFunctionReturn(0);
1004 PetscInt globalSize;
1005 ierr = VecGetSize(field_vec,&globalSize);CHKERRQ(ierr);
1008 const char *dmtype = NULL;
1013 const PetscScalar *seqArray = NULL;
1020 ierr = PetscTestFile(filename,
'r',&found);CHKERRQ(ierr);
1021 if(!found) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FILE_OPEN,
1022 "Restart file not found: %s",filename);
1025 ierr = VecCreate(PETSC_COMM_SELF,&seq_vec);CHKERRQ(ierr);
1026 ierr = VecSetType(seq_vec,VECSEQ);CHKERRQ(ierr);
1028 ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,filename,
1029 FILE_MODE_READ,&viewer);CHKERRQ(ierr);
1030 ierr = VecLoad(seq_vec,viewer);CHKERRQ(ierr);
1031 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1035 ierr = VecGetSize(seq_vec,&loaded);CHKERRQ(ierr);
1036 if(loaded != globalSize)
1037 SETERRQ(comm,PETSC_ERR_FILE_UNEXPECTED,
1038 "File %s holds %d entries – expected %d",
1039 filename,loaded,globalSize);
1042 ierr = VecGetArrayRead(seq_vec,&seqArray);CHKERRQ(ierr);
1045 "Rank 0 successfully loaded <%s>\n",filename);
1049 ierr = VecGetDM(field_vec, &dm); CHKERRQ(ierr);
1050 if (dm) { ierr = DMGetType(dm, &dmtype); CHKERRQ(ierr); }
1052 if (dmtype && !strcmp(dmtype, DMDA)) {
1058 ierr = DMDACreateNaturalVector(dm, &nat); CHKERRQ(ierr);
1064 ierr = VecScatterCreateToZero(nat, &scatter, &nat_seq); CHKERRQ(ierr);
1067 ierr = VecScatterBegin(scatter, (rank == 0 ? seq_vec : nat_seq), nat,
1068 INSERT_VALUES, SCATTER_REVERSE); CHKERRQ(ierr);
1069 ierr = VecScatterEnd(scatter, (rank == 0 ? seq_vec : nat_seq), nat,
1070 INSERT_VALUES, SCATTER_REVERSE); CHKERRQ(ierr);
1073 ierr = DMDANaturalToGlobalBegin(dm, nat, INSERT_VALUES, field_vec); CHKERRQ(ierr);
1074 ierr = DMDANaturalToGlobalEnd(dm, nat, INSERT_VALUES, field_vec); CHKERRQ(ierr);
1077 ierr = VecScatterDestroy(&scatter); CHKERRQ(ierr);
1078 ierr = VecDestroy(&nat_seq); CHKERRQ(ierr);
1079 ierr = VecDestroy(&nat); CHKERRQ(ierr);
1086 PetscScalar *buffer = NULL;
1088 buffer = (PetscScalar *)seqArray;
1090 ierr = PetscMalloc1(globalSize, &buffer); CHKERRQ(ierr);
1093 ierr = MPI_Bcast(buffer, (
int)globalSize, MPIU_SCALAR, 0, comm); CHKERRQ(ierr);
1096 PetscInt rstart, rend, loc;
1097 PetscScalar *locArray;
1099 ierr = VecGetOwnershipRange(field_vec, &rstart, &rend); CHKERRQ(ierr);
1100 loc = rend - rstart;
1102 ierr = VecGetArray(field_vec, &locArray); CHKERRQ(ierr);
1103 ierr = PetscMemcpy(locArray, buffer + rstart, loc *
sizeof(PetscScalar)); CHKERRQ(ierr);
1104 ierr = VecRestoreArray(field_vec, &locArray); CHKERRQ(ierr);
1107 ierr = PetscFree(buffer); CHKERRQ(ierr);
1113 ierr = VecRestoreArrayRead(seq_vec, &seqArray); CHKERRQ(ierr);
1114 ierr = VecDestroy(&seq_vec); CHKERRQ(ierr);
1118 "Loaded <%s> (parallel path)\n",filename);
1121 PetscFunctionReturn(0);
1131 PetscErrorCode ierr;
1134 const char *source_path = NULL;
1135 const char *eulerian_ext =
"dat";
1145 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE,
"Invalid execution mode for reading simulation fields.");
1155 ierr =
ReadFieldData(user,
"ufield", user->
Ucat, ti, eulerian_ext); CHKERRQ(ierr);
1161 ierr =
ReadFieldData(user,
"pfield", user->
P, ti, eulerian_ext); CHKERRQ(ierr);
1171 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"ParticleCount Vec is NULL but np>0");
1175 ierr =
ReadOptionalField(user,
"psifield",
"Scalar Psi Field", user->
Psi, ti, eulerian_ext); CHKERRQ(ierr);
1210 PetscErrorCode ierr;
1211 const char *eulerian_ext =
"dat";
1234 PetscErrorCode ierr;
1235 const char *eulerian_ext =
"dat";
1242 ierr =
ReadOptionalField(user,
"Nu_t",
"Turbulent Viscosity", user->
Nu_t, ti, eulerian_ext); CHKERRQ(ierr);
1243 ierr =
ReadOptionalField(user,
"cs",
"Smagorinsky Constant (Cs)", user->
CS, ti, eulerian_ext); CHKERRQ(ierr);
1259 PetscErrorCode ierr;
1260 const char *eulerian_ext =
"dat";
1268 ierr =
ReadOptionalField(user,
"Nu_t",
"Turbulent Viscosity", user->
Nu_t, ti, eulerian_ext); CHKERRQ(ierr);
1288 PetscErrorCode ierr;
1294 swarm = user->
swarm;
1299 ierr = DMSwarmCreateGlobalVectorFromField(swarm, field_name, &fieldVec);CHKERRQ(ierr);
1304 ierr =
ReadFieldData(user, field_name, fieldVec, ti, ext);CHKERRQ(ierr);
1307 ierr = DMSwarmDestroyGlobalVectorFromField(swarm, field_name, &fieldVec);CHKERRQ(ierr);
1309 PetscFunctionReturn(0);
1318 PetscErrorCode ierr;
1319 DM swarm = user->
swarm;
1321 PetscInt nlocal, nglobal, bs, i;
1322 const PetscScalar *scalar_array;
1323 void *field_array_void;
1326 PetscFunctionBeginUser;
1331 ierr = DMSwarmGetLocalSize(swarm, &nlocal); CHKERRQ(ierr);
1332 ierr = DMSwarmGetSize(swarm, &nglobal); CHKERRQ(ierr);
1334 ierr = DMSwarmGetField(swarm, field_name, &bs, NULL, NULL); CHKERRQ(ierr);
1335 ierr = DMSwarmRestoreField(swarm, field_name, &bs, NULL, NULL); CHKERRQ(ierr);
1338 ierr = VecCreate(PETSC_COMM_WORLD, &temp_vec); CHKERRQ(ierr);
1339 ierr = VecSetType(temp_vec, VECMPI); CHKERRQ(ierr);
1340 ierr = VecSetSizes(temp_vec, nlocal * bs, nglobal * bs); CHKERRQ(ierr);
1341 ierr = VecSetBlockSize(temp_vec, bs); CHKERRQ(ierr);
1342 ierr = VecSetUp(temp_vec); CHKERRQ(ierr);
1345 ierr =
ReadFieldData(user, field_name, temp_vec, ti, ext); CHKERRQ(ierr);
1348 ierr = VecGetArrayRead(temp_vec, &scalar_array); CHKERRQ(ierr);
1349 ierr = DMSwarmGetField(swarm, field_name, NULL, NULL, &field_array_void); CHKERRQ(ierr);
1352 if (strcmp(field_name,
"DMSwarm_pid") == 0) {
1353 PetscInt64 *int64_array = (PetscInt64 *)field_array_void;
1354 for (i = 0; i < nlocal * bs; i++) {
1355 int64_array[i] = (PetscInt64)scalar_array[i];
1358 PetscInt *int_array = (PetscInt *)field_array_void;
1359 for (i = 0; i < nlocal * bs; i++) {
1360 int_array[i] = (PetscInt)scalar_array[i];
1365 ierr = DMSwarmRestoreField(swarm, field_name, NULL, NULL, &field_array_void); CHKERRQ(ierr);
1366 ierr = VecRestoreArrayRead(temp_vec, &scalar_array); CHKERRQ(ierr);
1369 ierr = VecDestroy(&temp_vec); CHKERRQ(ierr);
1371 PetscFunctionReturn(0);
1380 PetscErrorCode ierr;
1383 const char *source_path = NULL;
1384 const char *particle_ext =
"dat";
1386 PetscFunctionBeginUser;
1387 ierr = DMSwarmGetSize(user->
swarm, &nGlobal); CHKERRQ(ierr);
1392 PetscFunctionReturn(0);
1404 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_WRONGSTATE,
"Invalid execution mode for reading simulation fields.");
1417 SETERRQ(PETSC_COMM_WORLD, ierr,
"Failed to read MANDATORY 'position' field for step %d. Cannot continue.", ti);
1428 ierr =
ReadOptionalSwarmField(user,
"DMSwarm_location_status",
"Migration Status", ti, particle_ext); CHKERRQ(ierr);
1433 PetscFunctionReturn(0);
1438#define __FUNCT__ "WriteFieldData"
1444 const char *field_name,
1449 PetscErrorCode ierr;
1451 PetscMPIInt rank, size;
1453 const PetscInt placeholder_int = 0;
1454 char filename[PETSC_MAX_PATH_LEN];
1457 PetscFunctionBeginUser;
1461 SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,
"I/O context directory was not set before calling WriteFieldData().");
1467 ierr = PetscObjectGetComm((PetscObject)field_vec,&comm);CHKERRQ(ierr);
1468 ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr);
1469 ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
1471 ierr = PetscSNPrintf(filename,
sizeof(filename),
1472 "%s/%s%05" PetscInt_FMT
"_%d.%s",
1476 " Preparing to write <%s> on rank %d/%d\n",
1477 filename,rank,size);
1485 ierr = PetscViewerBinaryOpen(comm,filename,
1486 FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
1487 ierr = VecView(field_vec,viewer);CHKERRQ(ierr);
1488 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1491 " Wrote <%s> (serial path)\n",filename);
1492 PetscFunctionReturn(0);
1501 const char *dmtype = NULL;
1505 ierr = VecGetDM(field_vec, &dm); CHKERRQ(ierr);
1506 if (dm) { ierr = DMGetType(dm, &dmtype); CHKERRQ(ierr); }
1508 if (dmtype && !strcmp(dmtype, DMDA)) {
1510 ierr = DMDACreateNaturalVector(dm, &nat); CHKERRQ(ierr);
1511 ierr = DMDAGlobalToNaturalBegin(dm, field_vec, INSERT_VALUES, nat); CHKERRQ(ierr);
1512 ierr = DMDAGlobalToNaturalEnd(dm, field_vec, INSERT_VALUES, nat); CHKERRQ(ierr);
1515 ierr = VecScatterCreateToZero(nat, &scatter, &seq_vec); CHKERRQ(ierr);
1518 ierr = VecScatterCreateToZero(field_vec, &scatter, &seq_vec); CHKERRQ(ierr);
1522 ierr = VecScatterBegin(scatter, (nat ? nat : field_vec), seq_vec,
1523 INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1524 ierr = VecScatterEnd(scatter, (nat ? nat : field_vec), seq_vec,
1525 INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1532 PetscReal vmin,vmax;
1533 ierr = VecMin(seq_vec,NULL,&vmin);CHKERRQ(ierr);
1534 ierr = VecMax(seq_vec,NULL,&vmax);CHKERRQ(ierr);
1536 " <%s> range = [%.4e … %.4e]\n",
1537 field_name,(
double)vmin,(
double)vmax);
1539 ierr = PetscViewerBinaryOpen(PETSC_COMM_SELF,filename,
1540 FILE_MODE_WRITE,&viewer);CHKERRQ(ierr);
1541 ierr = VecView(seq_vec,viewer);CHKERRQ(ierr);
1542 ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr);
1545 " Wrote <%s> (parallel path)\n",filename);
1549 ierr = VecScatterDestroy(&scatter);CHKERRQ(ierr);
1550 ierr = VecDestroy(&seq_vec);CHKERRQ(ierr);
1551 if (nat) { ierr = VecDestroy(&nat); CHKERRQ(ierr); }
1554 PetscFunctionReturn(0);
1565 PetscErrorCode ierr;
1624 PetscErrorCode ierr;
1646 PetscErrorCode ierr;
1653 DMLocalToGlobalBegin(user->
da, user->
lCs, INSERT_VALUES, user->
CS);
1654 DMLocalToGlobalEnd(user->
da, user->
lCs, INSERT_VALUES, user->
CS);
1656 DMLocalToGlobalBegin(user->
da, user->
lNu_t, INSERT_VALUES, user->
Nu_t);
1657 DMLocalToGlobalEnd(user->
da, user->
lNu_t, INSERT_VALUES, user->
Nu_t);
1676 PetscErrorCode ierr;
1697 PetscErrorCode ierr;
1701 PetscFunctionBeginUser;
1707 swarm = user->
swarm;
1715 "Attempting to create global vector from field: %s\n",
1717 ierr = DMSwarmCreateGlobalVectorFromField(swarm, field_name, &fieldVec);CHKERRQ(ierr);
1724 "Calling WriteFieldData for field: %s\n",
1726 ierr =
WriteFieldData(user, field_name, fieldVec, ti, ext);CHKERRQ(ierr);
1734 "Destroying the global vector for field: %s\n",
1736 ierr = DMSwarmDestroyGlobalVectorFromField(swarm, field_name, &fieldVec);CHKERRQ(ierr);
1740 "Successfully wrote swarm data for field: %s\n",
1743 PetscFunctionReturn(0);
1752 PetscErrorCode ierr;
1753 DM swarm = user->
swarm;
1755 PetscInt nlocal, nglobal,bs,i;
1756 void *field_array_void;
1757 PetscScalar *scalar_array;
1759 PetscFunctionBeginUser;
1764 ierr = DMSwarmGetLocalSize(swarm, &nlocal); CHKERRQ(ierr);
1765 ierr = DMSwarmGetSize(swarm, &nglobal); CHKERRQ(ierr);
1766 ierr = DMSwarmGetField(swarm, field_name, &bs, NULL, &field_array_void); CHKERRQ(ierr);
1769 ierr = VecCreate(PETSC_COMM_WORLD, &temp_vec); CHKERRQ(ierr);
1770 ierr = VecSetType(temp_vec, VECMPI); CHKERRQ(ierr);
1771 ierr = VecSetSizes(temp_vec, nlocal*bs, nglobal*bs); CHKERRQ(ierr);
1772 ierr = VecSetUp(temp_vec); CHKERRQ(ierr);
1775 DMSwarmVectorDefineField(swarm,
"position");
1777 ierr = VecGetArray(temp_vec, &scalar_array); CHKERRQ(ierr);
1779 if(strcasecmp(field_name,
"DMSwarm_pid") == 0){
1780 PetscInt64 *int64_array = (PetscInt64 *)field_array_void;
1782 for (i = 0; i < nlocal*bs; i++) {
1783 scalar_array[i] = (PetscScalar)int64_array[i];
1786 PetscInt *int_array = (PetscInt *)field_array_void;
1788 for (i = 0; i < nlocal*bs; i++) {
1789 scalar_array[i] = (PetscScalar)int_array[i];
1794 ierr = VecRestoreArray(temp_vec, &scalar_array); CHKERRQ(ierr);
1795 ierr = DMSwarmRestoreField(swarm, field_name, &bs, NULL, &field_array_void); CHKERRQ(ierr);
1798 ierr =
WriteFieldData(user, field_name, temp_vec, ti, ext); CHKERRQ(ierr);
1801 ierr = VecDestroy(&temp_vec); CHKERRQ(ierr);
1803 PetscFunctionReturn(0);
1812 PetscErrorCode ierr;
1815 PetscFunctionBeginUser;
1818 if (!user->
swarm || simCtx->
np <= 0) {
1819 PetscFunctionReturn(0);
1856 PetscFunctionReturn(0);
1865 PetscErrorCode ierr;
1868 PetscInt globalSize;
1870 const char *dmtype = NULL;
1873 Vec nat = NULL, seqNat = NULL;
1874 VecScatter scatNat = NULL;
1875 const PetscScalar *nar = NULL;
1876 PetscScalar *buf = NULL;
1880 VecScatter scat = NULL;
1881 const PetscScalar *sar = NULL;
1883 PetscFunctionBeginUser;
1885 ierr = PetscObjectGetComm((PetscObject)inVec, &comm); CHKERRQ(ierr);
1886 ierr = MPI_Comm_rank(comm, &rank); CHKERRQ(ierr);
1887 ierr = VecGetSize(inVec, &globalSize); CHKERRQ(ierr);
1891 ierr = VecGetDM(inVec, &dm); CHKERRQ(ierr);
1892 if (dm) { ierr = DMGetType(dm, &dmtype); CHKERRQ(ierr); }
1894 if (dmtype && !strcmp(dmtype, DMDA)) {
1896 ierr = DMDACreateNaturalVector(dm, &nat); CHKERRQ(ierr);
1897 ierr = DMDAGlobalToNaturalBegin(dm, inVec, INSERT_VALUES, nat); CHKERRQ(ierr);
1898 ierr = DMDAGlobalToNaturalEnd (dm, inVec, INSERT_VALUES, nat); CHKERRQ(ierr);
1900 ierr = VecScatterCreateToZero(nat, &scatNat, &seqNat); CHKERRQ(ierr);
1901 ierr = VecScatterBegin(scatNat, nat, seqNat, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1902 ierr = VecScatterEnd (scatNat, nat, seqNat, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1906 ierr = VecGetLocalSize(seqNat, &nseq); CHKERRQ(ierr);
1907 ierr = VecGetArrayRead(seqNat, &nar); CHKERRQ(ierr);
1909 ierr = PetscMalloc1(nseq, &buf); CHKERRQ(ierr);
1910 ierr = PetscMemcpy(buf, nar, (
size_t)nseq *
sizeof(PetscScalar)); CHKERRQ(ierr);
1912 ierr = VecRestoreArrayRead(seqNat, &nar); CHKERRQ(ierr);
1913 *arrayOut = (
double*)buf;
1916 ierr = VecScatterDestroy(&scatNat); CHKERRQ(ierr);
1917 ierr = VecDestroy(&seqNat); CHKERRQ(ierr);
1918 ierr = VecDestroy(&nat); CHKERRQ(ierr);
1921 ierr = VecScatterCreateToZero(inVec, &scat, &seq); CHKERRQ(ierr);
1922 ierr = VecScatterBegin(scat, inVec, seq, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1923 ierr = VecScatterEnd (scat, inVec, seq, INSERT_VALUES, SCATTER_FORWARD); CHKERRQ(ierr);
1927 ierr = VecGetLocalSize(seq, &nseq); CHKERRQ(ierr);
1928 ierr = VecGetArrayRead(seq, &sar); CHKERRQ(ierr);
1930 ierr = PetscMalloc1(nseq, &buf); CHKERRQ(ierr);
1931 ierr = PetscMemcpy(buf, sar, (
size_t)nseq *
sizeof(PetscScalar)); CHKERRQ(ierr);
1933 ierr = VecRestoreArrayRead(seq, &sar); CHKERRQ(ierr);
1934 *arrayOut = (
double*)buf;
1937 ierr = VecScatterDestroy(&scat); CHKERRQ(ierr);
1938 ierr = VecDestroy(&seq); CHKERRQ(ierr);
1941 PetscFunctionReturn(0);
1948PetscErrorCode
SwarmFieldToArrayOnRank0(DM swarm,
const char *field_name, PetscInt *n_total_particles, PetscInt *n_components,
void **gathered_array)
1950 PetscErrorCode ierr;
1951 PetscMPIInt rank, size;
1952 PetscInt nlocal, nglobal, bs;
1953 void *local_array_void;
1954 size_t element_size = 0;
1956 PetscFunctionBeginUser;
1958 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
1959 ierr = MPI_Comm_size(PETSC_COMM_WORLD, &size); CHKERRQ(ierr);
1962 ierr = DMSwarmGetLocalSize(swarm, &nlocal); CHKERRQ(ierr);
1963 ierr = DMSwarmGetSize(swarm, &nglobal); CHKERRQ(ierr);
1964 ierr = DMSwarmGetField(swarm, field_name, &bs, NULL, &local_array_void); CHKERRQ(ierr);
1967 if (strcasecmp(field_name,
"DMSwarm_pid") == 0) {
1968 element_size =
sizeof(PetscInt64);
1969 }
else if (strcasecmp(field_name,
"DMSwarm_CellID") == 0 || strcasecmp(field_name,
"DMSwarm_location_status") == 0) {
1970 element_size =
sizeof(PetscInt);
1972 element_size =
sizeof(PetscScalar);
1976 *n_total_particles = nglobal;
1978 *gathered_array = NULL;
1983 ierr = PetscMalloc(nglobal * bs * element_size, gathered_array); CHKERRQ(ierr);
1984 ierr = PetscMemcpy(*gathered_array, local_array_void, nglobal * bs * element_size); CHKERRQ(ierr);
1987 PetscInt *recvcounts = NULL, *displs = NULL;
1989 ierr = PetscMalloc1(size, &recvcounts); CHKERRQ(ierr);
1990 ierr = PetscMalloc1(size, &displs); CHKERRQ(ierr);
1992 PetscInt sendcount = nlocal * bs;
1995 ierr = MPI_Gather(&sendcount, 1, MPIU_INT, recvcounts, 1, MPIU_INT, 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
2000 for (PetscMPIInt i = 0; i < size; i++) recvcounts[i] *= element_size;
2001 for (PetscMPIInt i = 1; i < size; i++) displs[i] = displs[i-1] + recvcounts[i-1];
2003 ierr = PetscMalloc(nglobal * bs * element_size, gathered_array); CHKERRQ(ierr);
2007 ierr = MPI_Gatherv(local_array_void, nlocal * bs * element_size, MPI_BYTE,
2008 *gathered_array, recvcounts, displs, MPI_BYTE,
2009 0, PETSC_COMM_WORLD); CHKERRQ(ierr);
2012 ierr = PetscFree(recvcounts); CHKERRQ(ierr);
2013 ierr = PetscFree(displs); CHKERRQ(ierr);
2017 ierr = DMSwarmRestoreField(swarm, field_name, &bs, NULL, &local_array_void); CHKERRQ(ierr);
2019 PetscFunctionReturn(0);
2028 PetscErrorCode ierr;
2030 Cmpnts global_min_coords, global_max_coords;
2031 PetscReal StartTime;
2032 PetscInt StartStep,StepsToRun,total_num_particles;
2033 PetscMPIInt num_mpi_procs;
2037 num_mpi_procs = simCtx->
size;
2041 total_num_particles = simCtx->
np;
2045 PetscFunctionBeginUser;
2047 if (!user) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"DisplayBanner - UserCtx pointer is NULL.");
2050 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
2055 if (bboxlist_on_rank0 && num_mpi_procs > 0) {
2056 global_min_coords = bboxlist_on_rank0[0].
min_coords;
2057 global_max_coords = bboxlist_on_rank0[0].
max_coords;
2058 for (PetscMPIInt p = 1; p < num_mpi_procs; ++p) {
2059 global_min_coords.
x = PetscMin(global_min_coords.
x, bboxlist_on_rank0[p].
min_coords.
x);
2060 global_min_coords.
y = PetscMin(global_min_coords.
y, bboxlist_on_rank0[p].
min_coords.
y);
2061 global_min_coords.
z = PetscMin(global_min_coords.
z, bboxlist_on_rank0[p].
min_coords.
z);
2062 global_max_coords.
x = PetscMax(global_max_coords.
x, bboxlist_on_rank0[p].
max_coords.
x);
2063 global_max_coords.
y = PetscMax(global_max_coords.
y, bboxlist_on_rank0[p].
max_coords.
y);
2064 global_max_coords.
z = PetscMax(global_max_coords.
z, bboxlist_on_rank0[p].
max_coords.
z);
2071 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"(Rank 0) - bboxlist not provided or num_mpi_procs <=0; using user->bbox for domain bounds.\n");
2076 ierr = PetscPrintf(PETSC_COMM_SELF,
"\n"); CHKERRQ(ierr);
2077 ierr = PetscPrintf(PETSC_COMM_SELF,
"=============================================================\n"); CHKERRQ(ierr);
2078 ierr = PetscPrintf(PETSC_COMM_SELF,
" CASE SUMMARY \n"); CHKERRQ(ierr);
2079 ierr = PetscPrintf(PETSC_COMM_SELF,
"=============================================================\n"); CHKERRQ(ierr);
2080 ierr = PetscPrintf(PETSC_COMM_SELF,
" Grid Points : %d X %d X %d\n", user->
IM, user->
JM, user->
KM); CHKERRQ(ierr);
2081 ierr = PetscPrintf(PETSC_COMM_SELF,
" Cells : %d X %d X %d\n", user->
IM - 1, user->
JM - 1, user->
KM - 1); CHKERRQ(ierr);
2082 ierr = PetscPrintf(PETSC_COMM_SELF,
" Global Domain Bounds (X) : %.6f to %.6f\n", (
double)global_min_coords.
x, (
double)global_max_coords.
x); CHKERRQ(ierr);
2083 ierr = PetscPrintf(PETSC_COMM_SELF,
" Global Domain Bounds (Y) : %.6f to %.6f\n", (
double)global_min_coords.
y, (
double)global_max_coords.
y); CHKERRQ(ierr);
2084 ierr = PetscPrintf(PETSC_COMM_SELF,
" Global Domain Bounds (Z) : %.6f to %.6f\n", (
double)global_min_coords.
z, (
double)global_max_coords.
z); CHKERRQ(ierr);
2085 ierr = PetscPrintf(PETSC_COMM_SELF,
" Periodic Axes (BC-derived) : I=%s, J=%s, K=%s\n",
2088 simCtx->
k_periodic ?
"YES" :
"NO"); CHKERRQ(ierr);
2089 for (PetscInt axis = 0; axis < 3; axis++) {
2091 ierr = PetscPrintf(PETSC_COMM_SELF,
2092 " Periodic %c Translation : (%.6e, %.6e, %.6e)\n",
2098 if (total_num_particles > 0 &&
2100 ierr = PetscPrintf(PETSC_COMM_SELF,
2101 " Particle Periodic Wrapping : UNSUPPORTED (Eulerian periodicity only)\n"); CHKERRQ(ierr);
2104 ierr = PetscPrintf(PETSC_COMM_SELF,
"-------------------- Boundary Conditions --------------------\n"); CHKERRQ(ierr);
2105 const int face_name_width = 17;
2106 for (PetscInt i_face = 0; i_face < 6; ++i_face) {
2114 Cmpnts inlet_velocity = {0.0,0.0,0.0};
2119 ierr = PetscPrintf(PETSC_COMM_SELF,
" Face %-*s : %s - %s - [%.4f,%.4f,%.4f]\n",
2120 face_name_width, face_str, bc_type_str, bc_handler_type_str,inlet_velocity.
x,inlet_velocity.
y,inlet_velocity.
z); CHKERRQ(ierr);
2122 PetscReal v_max = 0.0;
2125 ierr = PetscPrintf(PETSC_COMM_SELF,
" Face %-*s : %s - %s - v_max=%.4f\n",
2126 face_name_width, face_str, bc_type_str, bc_handler_type_str, v_max); CHKERRQ(ierr);
2128 const char *source_file =
"(missing)";
2130 if (strcasecmp(param->key,
"source_file") == 0 && param->value) {
2131 source_file = param->value;
2135 ierr = PetscPrintf(PETSC_COMM_SELF,
" Face %-*s : %s - %s - source_file=%s\n",
2136 face_name_width, face_str, bc_type_str, bc_handler_type_str, source_file); CHKERRQ(ierr);
2140 PetscBool trimflag,foundflux,foundtrimflag;
2143 ierr = PetscPrintf(PETSC_COMM_SELF,
" Face %-*s : %s - %s - [%.4f] - %s\n",
2144 face_name_width, face_str, bc_type_str, bc_handler_type_str,flux,trimflag?
"Trim Ucont":
"No Trim"); CHKERRQ(ierr);
2146 ierr = PetscPrintf(PETSC_COMM_SELF,
" Face %-*s : %s - %s\n",
2147 face_name_width, face_str, bc_type_str,bc_handler_type_str); CHKERRQ(ierr);
2151 ierr = PetscPrintf(PETSC_COMM_SELF,
"-------------------------------------------------------------\n"); CHKERRQ(ierr);
2152 ierr = PetscPrintf(PETSC_COMM_SELF,
" Run Mode : %s\n", simCtx->
OnlySetup ?
"SETUP ONLY" :
"Full Simulation"); CHKERRQ(ierr);
2153 ierr = PetscPrintf(PETSC_COMM_SELF,
" Start Time : %.4f\n", (
double)StartTime); CHKERRQ(ierr);
2154 ierr = PetscPrintf(PETSC_COMM_SELF,
" Timestep Size : %.4f\n", (
double)simCtx->
dt); CHKERRQ(ierr);
2155 ierr = PetscPrintf(PETSC_COMM_SELF,
" Starting Step : %d\n", StartStep); CHKERRQ(ierr);
2156 ierr = PetscPrintf(PETSC_COMM_SELF,
" Total Steps to Run : %d\n", StepsToRun); CHKERRQ(ierr);
2157 ierr = PetscPrintf(PETSC_COMM_SELF,
" Ending Step : %d\n", StartStep + StepsToRun); CHKERRQ(ierr);
2158 if (simCtx->
tiout > 0) {
2159 ierr = PetscPrintf(PETSC_COMM_SELF,
" Field/Restart Cadence : every %d step(s)\n", simCtx->
tiout); CHKERRQ(ierr);
2161 ierr = PetscPrintf(PETSC_COMM_SELF,
" Field/Restart Cadence : DISABLED\n"); CHKERRQ(ierr);
2163 ierr = PetscPrintf(PETSC_COMM_SELF,
" Immersed Boundary : %s\n", simCtx->
immersed ?
"ENABLED" :
"DISABLED"); CHKERRQ(ierr);
2167 " Runtime Walltime Guard : %s (warmup=%d, multiplier=%.2f, min=%.1f s, alpha=%.2f)\n",
2175 ierr = PetscPrintf(PETSC_COMM_SELF,
" Runtime Walltime Guard : DISABLED\n"); CHKERRQ(ierr);
2177 ierr = PetscPrintf(PETSC_COMM_SELF,
" Number of MPI Processes : %d\n", num_mpi_procs); CHKERRQ(ierr);
2178 ierr = PetscPrintf(PETSC_COMM_WORLD,
" Number of Particles : %d\n", total_num_particles); CHKERRQ(ierr);
2179 if (simCtx->
np > 0) {
2183 ierr = PetscPrintf(PETSC_COMM_SELF,
" Particle Console Cadence : every %d step(s)\n", simCtx->
particleConsoleOutputFreq); CHKERRQ(ierr);
2185 ierr = PetscPrintf(PETSC_COMM_SELF,
" Particle Console Cadence : DISABLED\n"); CHKERRQ(ierr);
2187 ierr = PetscPrintf(PETSC_COMM_SELF,
" Particle Log Row Sampling : every %d particle(s)\n", simCtx->
LoggingFrequency); CHKERRQ(ierr);
2189 ierr = PetscPrintf(PETSC_COMM_SELF,
" Particle Restart Mode : %s\n", simCtx->
particleRestartMode); CHKERRQ(ierr);
2191 ierr = PetscPrintf(PETSC_COMM_SELF,
" Particle Initialization Mode: %s\n", particle_init_str); CHKERRQ(ierr);
2192 ierr = PetscPrintf(PETSC_COMM_SELF,
" Interpolation Method : %s\n",
2199 ierr = PetscPrintf(PETSC_COMM_SELF,
" Particles Initialized At : --- (No INLET face identified)\n"); CHKERRQ(ierr);
2204 ierr = PetscPrintf(PETSC_COMM_WORLD,
" Reynolds Number : %le\n", simCtx->
ren); CHKERRQ(ierr);
2209 ierr = PetscPrintf(PETSC_COMM_WORLD,
" Initial Pseudo-CFL (Courant): %le\n", simCtx->
pseudo_cfl); CHKERRQ(ierr);
2210 ierr = PetscPrintf(PETSC_COMM_WORLD,
" Large Eddy Simulation Model : %s\n",
LESModelToString(simCtx->
les)); CHKERRQ(ierr);
2213 ierr = PetscPrintf(PETSC_COMM_SELF,
" Eulerian State Source : load (%s)\n",
2216 ierr = PetscPrintf(PETSC_COMM_SELF,
" Eulerian State Source : restart step %d (%s)\n",
2220 ierr = PetscPrintf(PETSC_COMM_SELF,
" Eulerian State Source : initial condition (%s)\n",
2221 field_init_str); CHKERRQ(ierr);
2225 ierr = PetscPrintf(PETSC_COMM_SELF,
2226 " Constant Velocity (Cart.) : x=%.4f y=%.4f z=%.4f\n",
2232 ierr = PetscPrintf(PETSC_COMM_SELF,
2233 " Constant Velocity (Curv.) : speed=%.4f direction=%s\n",
2238 ierr = PetscPrintf(PETSC_COMM_SELF,
2239 " Poiseuille Peak Velocity : speed=%.4f direction=%s\n",
2244 ierr = PetscPrintf(PETSC_COMM_SELF,
2245 " Initial Velocity File : field=%s directory=%s\n",
2250 ierr = PetscPrintf(PETSC_COMM_WORLD,
" Analytical Solution Type : %s\n", simCtx->
AnalyticalSolutionType); CHKERRQ(ierr);
2252 ierr = PetscPrintf(PETSC_COMM_SELF,
"=============================================================\n"); CHKERRQ(ierr);
2253 ierr = PetscPrintf(PETSC_COMM_SELF,
"\n"); CHKERRQ(ierr);
2255 PetscFunctionReturn(0);
2259#define __FUNCT__ "ParsePostProcessingSettings"
2268 PetscBool startTimeSet, endTimeSet, timeStepSet;
2270 PetscFunctionBeginUser;
2273 if (!simCtx || !simCtx->
pps) {
2274 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_NULL,
"SimCtx or its pps member is NULL in ParsePostProcessingSettings.");
2303 file = fopen(configFile,
"r");
2306 while (fgets(line,
sizeof(line), file)) {
2307 char *key, *value, *comment;
2308 comment = strchr(line,
'#');
if (comment) *comment =
'\0';
2310 key = strtok(line,
"="); value = strtok(NULL,
"=");
2313 if (strcmp(key,
"startTime") == 0) pps->
startTime = atoi(value);
2314 else if (strcmp(key,
"endTime") == 0) pps->
endTime = atoi(value);
2315 else if (strcmp(key,
"timeStep") == 0) pps->
timeStep = atoi(value);
2316 else if (strcmp(key,
"output_particles") == 0) {
2317 if (strcasecmp(value,
"true") == 0) pps->
outputParticles = PETSC_TRUE;
2319 else if (strcasecmp(key,
"process_pipeline") == 0) {
2322 }
else if (strcasecmp(key,
"output_fields_instantaneous") == 0) {
2325 }
else if (strcasecmp(key,
"output_fields_averaged") == 0) {
2328 }
else if (strcasecmp(key,
"output_prefix") == 0) {
2331 }
else if (strcasecmp(key,
"particle_output_prefix") == 0) {
2334 }
else if (strcasecmp(key,
"particle_fields_instantaneous") == 0) {
2337 }
else if (strcasecmp(key,
"particle_pipeline") == 0) {
2340 }
else if (strcasecmp(key,
"particle_output_freq") == 0) {
2342 }
else if (strcasecmp(key,
"statistics_pipeline") == 0) {
2345 }
else if (strcasecmp(key,
"statistics_output_prefix") == 0) {
2348 }
else if (strcasecmp(key,
"particleExt") == 0) {
2351 }
else if (strcasecmp(key,
"eulerianExt") == 0) {
2354 }
else if (strcmp(key,
"reference_ip") == 0) {pps->
reference[0] = atoi(value);
2355 }
else if (strcmp(key,
"reference_jp") == 0) {pps->
reference[1] = atoi(value);
2356 }
else if (strcmp(key,
"reference_kp") == 0) {pps->
reference[2] = atoi(value);
2357 }
else if (strcasecmp(key,
"source_directory") == 0) {
2368 LOG_ALLOW(
GLOBAL,
LOG_WARNING,
"Could not open post-processing config file '%s'. Using defaults and command-line overrides.\n", configFile);
2372 PetscOptionsGetInt(NULL, NULL,
"-startTime", &pps->
startTime, &startTimeSet);
2373 PetscOptionsGetInt(NULL, NULL,
"-endTime", &pps->
endTime, &endTimeSet);
2374 PetscOptionsGetInt(NULL, NULL,
"-timeStep", &pps->
timeStep, &timeStepSet);
2375 PetscOptionsGetBool(NULL, NULL,
"-output_particles", &pps->
outputParticles, NULL);
2382 if (startTimeSet && !endTimeSet) {
2386 LOG_ALLOW(
GLOBAL,
LOG_INFO,
"Post-processing configured to run from t=%d to t=%d with step %d. Particle output: %s.\n",
2400 PetscFunctionReturn(0);
2405#define __FUNCT__ "ParseScalingInformation"
2414 PetscErrorCode ierr;
2417 PetscFunctionBeginUser;
2420 if (!simCtx) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"SimCtx is NULL in ParseScalingInformation");
2429 ierr = PetscOptionsGetReal(NULL, NULL,
"-scaling_L_ref", &simCtx->
scaling.
L_ref, &flg); CHKERRQ(ierr);
2430 ierr = PetscOptionsGetReal(NULL, NULL,
"-scaling_U_ref", &simCtx->
scaling.
U_ref, &flg); CHKERRQ(ierr);
2431 ierr = PetscOptionsGetReal(NULL, NULL,
"-scaling_rho_ref", &simCtx->
scaling.
rho_ref, &flg); CHKERRQ(ierr);
2436 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_ARG_OUTOFRANGE,
"Reference velocity U_ref must be positive. Got %g", (
double)simCtx->
scaling.
U_ref);
2441 LOG(
GLOBAL,
LOG_INFO,
"---------------- Physical Scales Initialized -----------------\n");
2442 LOG(
GLOBAL,
LOG_INFO,
" L_ref: %.4f, U_ref: %.4f, rho_ref: %.4f, P_ref: %.4f\n",
2444 LOG(
GLOBAL,
LOG_INFO,
"--------------------------------------------------------------\n");
2447 PetscFunctionReturn(0);
2462 PetscMPIInt rank, size;
2463 PetscErrorCode ierr;
2466 double *array = NULL;
2467 PetscInt fileExistsFlag = 0;
2470 "Start reading from file: %s\n",
2474 if (!filename || !data_out || !Nout) {
2476 "Null pointer argument provided.\n");
2481 MPI_Comm_rank(comm, &rank);
2482 MPI_Comm_size(comm, &size);
2486 fp = fopen(filename,
"r");
2495 ierr = MPI_Bcast(&fileExistsFlag, 1, MPI_INT, 0, comm); CHKERRQ(ierr);
2497 if (!fileExistsFlag) {
2501 "File '%s' not found.\n",
2509 fp = fopen(filename,
"r");
2512 "File '%s' could not be opened for reading.\n",
2520 while (fgets(line,
sizeof(line), fp)) {
2526 "File '%s' has %d lines.\n",
2530 array = (
double*)malloc(N *
sizeof(
double));
2534 "malloc failed for array.\n");
2543 while (fgets(line,
sizeof(line), fp)) {
2545 if (sscanf(line,
"%lf", &val) == 1) {
2553 "Successfully read %d values from '%s'.\n",
2558 ierr = MPI_Bcast(&N, 1, MPI_INT, 0, comm); CHKERRQ(ierr);
2562 array = (
double*)malloc(N *
sizeof(
double));
2565 "malloc failed on rank %d.\n",
2572 ierr = MPI_Bcast(array, N, MPI_DOUBLE, 0, comm); CHKERRQ(ierr);
2579 "Done. Provided array of length=%d to all ranks.\n",
2590 double **coordsArray,
2593 PetscFunctionBeginUser;
2595 PetscErrorCode ierr;
2599 ierr = VecCreate(PETSC_COMM_WORLD, &coordsVec);CHKERRQ(ierr);
2600 ierr = VecSetFromOptions(coordsVec);CHKERRQ(ierr);
2603 ierr =
ReadFieldData(user,
"position", coordsVec, timeIndex,
"dat");
2606 "Error reading position data (ti=%d).\n",
2608 PetscFunctionReturn(ierr);
2614 ierr = VecDestroy(&coordsVec);CHKERRQ(ierr);
2617 "Successfully gathered coordinates. Ncoords=%d.\n", *Ncoords);
2618 PetscFunctionReturn(0);
2627 const char *fieldName,
2629 double **scalarArray,
2632 PetscFunctionBeginUser;
2634 PetscErrorCode ierr;
2638 ierr = VecCreate(PETSC_COMM_WORLD, &fieldVec);CHKERRQ(ierr);
2639 ierr = VecSetFromOptions(fieldVec);CHKERRQ(ierr);
2641 ierr =
ReadFieldData(user, fieldName, fieldVec, timeIndex,
"dat");
2644 "Error reading field '%s' (ti=%d).\n",
2645 fieldName, timeIndex);
2646 PetscFunctionReturn(ierr);
2652 ierr = VecDestroy(&fieldVec);CHKERRQ(ierr);
2655 "Successfully gathered field '%s'. Nscalars=%d.\n",
2656 fieldName, *Nscalars);
2657 PetscFunctionReturn(0);
PetscErrorCode ReadStatisticalFields(UserCtx *user, PetscInt ti)
Implementation of ReadStatisticalFields().
PetscErrorCode ParsePostProcessingSettings(SimCtx *simCtx)
Internal helper implementation: ParsePostProcessingSettings().
PetscErrorCode WriteAllSwarmFields(UserCtx *user)
Internal helper implementation: WriteAllSwarmFields().
PetscErrorCode SwarmFieldToArrayOnRank0(DM swarm, const char *field_name, PetscInt *n_total_particles, PetscInt *n_components, void **gathered_array)
Internal helper implementation: SwarmFieldToArrayOnRank0().
PetscErrorCode ParseScalingInformation(SimCtx *simCtx)
Implementation of ParseScalingInformation().
PetscInt ReadDataFileToArray(const char *filename, double **data_out, PetscInt *Nout, MPI_Comm comm)
Implementation of ReadDataFileToArray().
PetscErrorCode ReadGridFile(UserCtx *user)
Internal helper implementation: ReadGridFile().
PetscErrorCode StringToBCHandlerType(const char *str, BCHandlerType *handler_out)
Internal helper implementation: StringToBCHandlerType().
PetscErrorCode ReadRANSFields(UserCtx *user, PetscInt ti)
Internal helper implementation: ReadRANSFields().
PetscErrorCode GetBCParamReal(BC_Param *params, const char *key, PetscReal *value_out, PetscBool *found)
Internal helper implementation: GetBCParamReal().
PetscErrorCode ReadSwarmIntField(UserCtx *user, const char *field_name, PetscInt ti, const char *ext)
Internal helper implementation: ReadSwarmIntField().
PetscErrorCode WriteSwarmField(UserCtx *user, const char *field_name, PetscInt ti, const char *ext)
Implementation of WriteSwarmField().
static PetscInt * g_IMs_from_file
Caches the IM dimensions for all blocks read from the grid file.
PetscErrorCode WriteStatisticalFields(UserCtx *user)
Implementation of WriteStatisticalFields().
PetscErrorCode ReadSimulationFields(UserCtx *user, PetscInt ti)
Internal helper implementation: ReadSimulationFields().
static PetscInt g_nblk_from_file
Stores the number of blocks read from the grid file.
PetscBool ShouldWriteDataOutput(const SimCtx *simCtx, PetscInt completed_step)
Implementation of ShouldWriteDataOutput().
PetscErrorCode WriteFieldData(UserCtx *user, const char *field_name, Vec field_vec, PetscInt ti, const char *ext)
Internal helper implementation: WriteFieldData().
PetscErrorCode ReadLESFields(UserCtx *user, PetscInt ti)
Internal helper implementation: ReadLESFields().
PetscErrorCode ReadFieldData(UserCtx *user, const char *field_name, Vec field_vec, PetscInt ti, const char *ext)
Internal helper implementation: ReadFieldData().
PetscErrorCode ParseAllBoundaryConditions(UserCtx *user, const char *bcs_input_filename)
Internal helper implementation: ParseAllBoundaryConditions().
PetscErrorCode ValidateBCHandlerForBCType(BCType type, BCHandlerType handler)
Internal helper implementation: ValidateBCHandlerForBCType().
void TrimWhitespace(char *str)
Implementation of TrimWhitespace().
PetscErrorCode WriteSimulationFields(UserCtx *user)
Implementation of WriteSimulationFields().
PetscErrorCode ReadAllSwarmFields(UserCtx *user, PetscInt ti)
Internal helper implementation: ReadAllSwarmFields().
static PetscBool g_file_has_been_read
A flag to ensure the grid file is read only once.
PetscErrorCode ReadGridGenerationInputs(UserCtx *user)
Internal helper implementation: ReadGridGenerationInputs().
PetscErrorCode ReadSwarmField(UserCtx *user, const char *field_name, PetscInt ti, const char *ext)
Internal helper implementation: ReadSwarmField().
PetscErrorCode WriteRANSFields(UserCtx *user)
Implementation of WriteRANSFields().
PetscErrorCode PopulateFinestUserGridResolutionFromOptions(UserCtx *finest_users, PetscInt nblk)
Internal helper implementation: PopulateFinestUserGridResolutionFromOptions().
PetscErrorCode DeterminePeriodicity(SimCtx *simCtx)
Internal helper implementation: DeterminePeriodicity().
PetscErrorCode ReadFieldDataToRank0(PetscInt timeIndex, const char *fieldName, UserCtx *user, double **scalarArray, PetscInt *Nscalars)
Internal helper implementation: ReadFieldDataToRank0().
PetscErrorCode VecToArrayOnRank0(Vec inVec, PetscInt *N, double **arrayOut)
Internal helper implementation: VecToArrayOnRank0().
PetscErrorCode WriteSwarmIntField(UserCtx *user, const char *field_name, PetscInt ti, const char *ext)
Internal helper implementation: WriteSwarmIntField().
PetscErrorCode WriteLESFields(UserCtx *user)
Internal helper implementation: WriteLESFields().
static PetscInt * g_KMs_from_file
Caches the KM dimensions for all blocks read from the grid file.
static PetscInt * g_JMs_from_file
Caches the JM dimensions for all blocks read from the grid file.
PetscErrorCode StringToBCFace(const char *str, BCFace *face_out)
Internal helper implementation: StringToBCFace().
PetscErrorCode ReadPositionsFromFile(PetscInt timeIndex, UserCtx *user, double **coordsArray, PetscInt *Ncoords)
Internal helper implementation: ReadPositionsFromFile().
static PetscErrorCode ReadOptionalField(UserCtx *user, const char *field_name, const char *field_label, Vec field_vec, PetscInt ti, const char *ext)
Internal helper implementation: ReadOptionalField().
PetscErrorCode VerifyPathExistence(const char *path, PetscBool is_dir, PetscBool is_optional, const char *description, PetscBool *exists)
Internal helper implementation: VerifyPathExistence().
PetscErrorCode GetBCParamBool(BC_Param *params, const char *key, PetscBool *value_out, PetscBool *found)
Internal helper implementation: GetBCParamBool().
void FreeBC_ParamList(BC_Param *head)
Implementation of FreeBC_ParamList().
PetscErrorCode StringToBCType(const char *str, BCType *type_out)
Internal helper implementation: StringToBCType().
PetscErrorCode DisplayBanner(SimCtx *simCtx)
Internal helper implementation: DisplayBanner().
static PetscErrorCode CheckDataFile(UserCtx *user, PetscInt ti, const char *fieldName, const char *ext, PetscBool *fileExists)
Internal helper implementation: CheckDataFile().
static PetscErrorCode ReadOptionalSwarmField(UserCtx *user, const char *field_name, const char *field_label, PetscInt ti, const char *ext)
Internal helper implementation: ReadOptionalSwarmField().
Public interface for data input/output routines.
const char * BCHandlerTypeToString(BCHandlerType handler_type)
Converts a BCHandlerType enum to its string representation.
#define LOG_ALLOW_SYNC(scope, level, fmt,...)
Synchronized logging macro that checks both the log level and whether the calling function is in the ...
#define LOCAL
Logging scope definitions for controlling message output.
#define GLOBAL
Scope for global logging across all processes.
const char * BCFaceToString(BCFace face)
Helper function to convert BCFace enum to a string representation.
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
#define LOG(scope, level, fmt,...)
Logging macro for PETSc-based applications with scope control.
const char * BCTypeToString(BCType type)
Helper function to convert BCType enum to a string representation.
const char * FlowDirectionToString(FlowDirection fd)
Convert a FlowDirection enum value to its YAML token string.
const char * InitialConditionModeToString(InitialConditionMode mode)
Convert an initial-condition mode to a string representation.
@ LOG_ERROR
Critical errors that may halt the program.
@ LOG_TRACE
Very fine-grained tracing information for in-depth debugging.
@ LOG_INFO
Informational messages about program execution.
@ LOG_WARNING
Non-critical issues that warrant attention.
@ LOG_DEBUG
Detailed debugging information.
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
const char * LESModelToString(LESModelType LESFlag)
Helper function to convert LES Flag to a string representation.
const char * MomentumSolverTypeToString(MomentumSolverType SolverFlag)
Helper function to convert Momentum Solver flag to a string representation.
const char * ParticleInitializationToString(ParticleInitializationType ParticleInitialization)
Helper function to convert ParticleInitialization to a string representation.
PetscErrorCode UpdateLocalGhosts(UserCtx *user, const char *fieldName)
Updates the local vector (including ghost points) from its corresponding global vector.
PetscReal icVelocityPhysical
char statistics_output_prefix[256]
basename for CSV output, e.g.
BCType
Defines the general mathematical/physical Category of a boundary.
PetscBool inletFaceDefined
char particle_output_prefix[256]
BoundaryFaceConfig boundary_faces[6]
BCFace identifiedInletBCFace
PetscBool walltimeGuardActive
char euler_subdir[PETSC_MAX_PATH_LEN]
InitialConditionMode initialConditionMode
SimCtx * simCtx
Back-pointer to the master simulation context.
@ PARTICLE_INIT_SURFACE_RANDOM
Random placement on the inlet face.
@ PARTICLE_INIT_SURFACE_EDGES
Deterministic placement at inlet face edges.
FlowDirection flowDirection
#define MAX_FIELD_LIST_LENGTH
PetscReal walltimeGuardMinSeconds
BCHandlerType
Defines the specific computational "strategy" for a boundary handler.
@ BC_HANDLER_PERIODIC_GEOMETRIC
@ BC_HANDLER_INLET_PARABOLIC
@ BC_HANDLER_INLET_CONSTANT_VELOCITY
@ BC_HANDLER_PERIODIC_DRIVEN_INITIAL_FLUX
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
@ BC_HANDLER_INLET_PROFILE_FROM_FILE
@ BC_HANDLER_OUTLET_CONSERVATION
char output_fields_averaged[1024]
#define MAX_PIPELINE_LENGTH
BCHandlerType handler_type
Cmpnts max_coords
Maximum x, y, z coordinates of the bounding box.
char output_dir[PETSC_MAX_PATH_LEN]
#define MAX_FILENAME_LENGTH
Cmpnts min_coords
Minimum x, y, z coordinates of the bounding box.
char * current_io_directory
char grid_file[PETSC_MAX_PATH_LEN]
char statistics_pipeline[1024]
e.g.
InterpolationMethod interpolationMethod
char output_fields_instantaneous[1024]
char particleRestartMode[16]
char particle_subdir[PETSC_MAX_PATH_LEN]
char source_dir[PETSC_MAX_PATH_LEN]
char particle_pipeline[1024]
char eulerianSource[PETSC_MAX_PATH_LEN]
PetscBool walltimeGuardEnabled
PetscInt walltimeGuardWarmupSteps
ParticleInitializationType ParticleInitialization
char process_pipeline[1024]
PetscInt particle_output_freq
char particle_fields[1024]
PetscBool outputParticles
char initialConditionDirectory[PETSC_MAX_PATH_LEN]
char AnalyticalSolutionType[PETSC_MAX_PATH_LEN]
@ IC_MODE_CONSTANT_CARTESIAN
@ IC_MODE_CONSTANT_STREAMWISE
PetscInt particleConsoleOutputFreq
Cmpnts InitialConstantContra
@ EXEC_MODE_POSTPROCESSOR
char _io_context_buffer[PETSC_MAX_PATH_LEN]
Cmpnts periodic_translation[3]
PetscReal walltimeGuardEstimatorAlpha
PetscBool periodic_translation_valid[3]
InitialConditionField initialConditionField
PetscReal walltimeGuardMultiplier
MomentumSolverType mom_solver_type
char PostprocessingControlFile[PETSC_MAX_PATH_LEN]
char restart_dir[PETSC_MAX_PATH_LEN]
PetscInt LoggingFrequency
BCFace
Identifies the six logical faces of a structured computational block.
BoundaryCondition * handler
A node in a linked list for storing key-value parameters from the bcs.dat file.
Holds the complete configuration for one of the six boundary faces.
Defines a 3D axis-aligned bounding box.
A 3D point or vector with PetscScalar components.
Holds all configuration parameters for a post-processing run.
The master context for the entire simulation.
User-defined context containing data specific to a single computational grid level.