250 PetscInt N_full_coords;
251 PetscScalar *full_coords_arr = NULL;
253 PetscFunctionBeginUser;
254 ierr = DMDAGetInfo(user->
da, NULL, &IM, &JM, &KM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
260 *out_npoints = (*out_nx) * (*out_ny) * (*out_nz);
262 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
"Preparing subsampled coordinates for a %" PetscInt_FMT
"x%" PetscInt_FMT
"x%" PetscInt_FMT
" grid.\n", *out_nx, *out_ny, *out_nz);
265 ierr = DMGetCoordinates(user->
da, &coords_global); CHKERRQ(ierr);
267 ierr =
VecToArrayOnRank0(coords_global, &N_full_coords, &full_coords_arr); CHKERRQ(ierr);
272 if (N_full_coords != IM * JM * KM * 3) {
273 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
"Gathered coordinate array has wrong size. Expected %" PetscInt_FMT
", got %" PetscInt_FMT, IM * JM * KM * 3, N_full_coords);
277 ierr = PetscMalloc1(3 * (*out_npoints), out_coords); CHKERRQ(ierr);
281 for (PetscInt k = 0; k < *out_nz; k++) {
282 for (PetscInt j = 0; j < *out_ny; j++) {
283 for (PetscInt i = 0; i < *out_nx; i++) {
285 PetscInt p_in = 3 * (k * (JM * IM) + j * IM + i);
287 (*out_coords)[p_out++] = full_coords_arr[p_in + 0];
288 (*out_coords)[p_out++] = full_coords_arr[p_in + 1];
289 (*out_coords)[p_out++] = full_coords_arr[p_in + 2];
294 ierr = PetscFree(full_coords_arr); CHKERRQ(ierr);
300 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
"Subsampled coordinates prepared on rank 0 with total %" PetscInt_FMT
" points.\n", *out_npoints);
302 PetscFunctionReturn(0);
316 PetscInt IM, JM, KM, nx, ny, nz, npoints;
317 PetscInt N_full_field = 0;
318 PetscScalar *full_field_arr = NULL;
320 PetscFunctionBeginUser;
321 ierr = DMDAGetInfo(user->
da, NULL, &IM, &JM, &KM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
322 nx = IM - 1; ny = JM - 1; nz = KM - 1;
323 npoints = nx * ny * nz;
326 "Preparing subsampled field data (dof=%" PetscInt_FMT
") for a %" PetscInt_FMT
"x%" PetscInt_FMT
"x%" PetscInt_FMT
" grid.\n",
327 num_components, nx, ny, nz);
330 ierr =
VecToArrayOnRank0(field_vec, &N_full_field, &full_field_arr); CHKERRQ(ierr);
335 if (N_full_field != IM * JM * KM * num_components) {
336 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
337 "Gathered field array has wrong size. Expected %" PetscInt_FMT
", got %" PetscInt_FMT,
338 IM * JM * KM * num_components, N_full_field);
342 ierr = PetscMalloc1(num_components * npoints, out_data); CHKERRQ(ierr);
394 for (PetscInt k = 0; k < nz; k++) {
395 for (PetscInt j = 0; j < ny; j++) {
396 for (PetscInt i = 0; i < nx; i++) {
397 const PetscInt p_in_start = num_components * (k * (JM * IM) + j * IM + i);
398 for (PetscInt c = 0; c < num_components; c++) {
399 (*out_data)[p_out++] = full_field_arr[p_in_start + c];
407 ierr = PetscFree(full_field_arr); CHKERRQ(ierr);
413 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
"Subsampled field data prepared on rank 0 with total %" PetscInt_FMT
" points.\n", npoints);
415 PetscFunctionReturn(0);
425 PetscInt n_total_particles, n_components;
427 PetscFunctionBeginUser;
436 PetscScalar *full_coords_arr = NULL;
443 *p_n_total = n_total_particles;
445 if (n_total_particles == 0) {
446 if (full_coords_arr) {
447 ierr = PetscFree(full_coords_arr); CHKERRQ(ierr);
449 PetscFunctionReturn(0);
451 if (n_components != 3) {
452 SETERRQ(PETSC_COMM_SELF, 1,
"Coordinate field position must have 3 components, but has %" PetscInt_FMT, n_components);
457 meta->
npoints = (n_total_particles > 0) ? (n_total_particles - 1) / stride + 1 : 0;
459 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Subsampling %" PetscInt_FMT
" total particles with stride %" PetscInt_FMT
" -> %" PetscInt_FMT
" output particles.\n",
460 n_total_particles, stride, meta->
npoints);
463 ierr = PetscMalloc1(3 * meta->
npoints, &meta->
coords); CHKERRQ(ierr);
464 for (PetscInt i = 0; i < meta->
npoints; i++) {
465 PetscInt source_idx = i * stride;
466 for (
int d = 0; d < 3; d++) meta->
coords[3 * i + d] = full_coords_arr[3 * source_idx + d];
468 ierr = PetscFree(full_coords_arr);
472 char *fields_copy, *field_name;
473 ierr = PetscStrallocpy(pps->
particle_fields, &fields_copy); CHKERRQ(ierr);
474 field_name = strtok(fields_copy,
",");
477 if (!*field_name || strcasecmp(field_name,
"position") == 0) {
478 field_name = strtok(NULL,
",");
continue;
482 DM swarm_to_use = user->
swarm;
483 const char* internal_name = field_name;
485 PetscErrorCode check_ierr;
486 ierr = PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL); CHKERRQ(ierr);
487 check_ierr = DMSwarmGetField(user->
post_swarm, field_name, NULL, NULL, NULL);
488 ierr = PetscPopErrorHandler(); CHKERRQ(ierr);
491 ierr = DMSwarmRestoreField(user->
post_swarm, field_name, NULL, NULL, NULL); CHKERRQ(ierr);
495 if (strcasecmp(field_name,
"pid") == 0) internal_name =
"DMSwarm_pid";
496 else if (strcasecmp(field_name,
"CellID") == 0) internal_name =
"DMSwarm_CellID";
497 else if (strcasecmp(field_name,
"Migration Status") == 0) internal_name =
"DMSwarm_location_status";
503 void* full_field_arr_void = NULL;
504 PetscInt field_total_particles, field_num_components;
506 ierr =
SwarmFieldToArrayOnRank0(swarm_to_use, internal_name, &field_total_particles, &field_num_components, &full_field_arr_void); CHKERRQ(ierr);
508 if (field_total_particles != n_total_particles) {
509 LOG_ALLOW(
LOCAL,
LOG_WARNING,
"Field '%s' has %" PetscInt_FMT
" particles, but expected %" PetscInt_FMT
". Skipping.\n", field_name, field_total_particles, n_total_particles);
510 ierr = PetscFree(full_field_arr_void); CHKERRQ(ierr);
511 field_name = strtok(NULL,
",");
continue;
521 PetscScalar* final_data_arr = (PetscScalar*)current_field->
data;
524 if (strcasecmp(internal_name,
"DMSwarm_pid") == 0) {
525 PetscInt64* source_arr = (PetscInt64*)full_field_arr_void;
526 for (PetscInt i = 0; i < meta->
npoints; i++) {
527 final_data_arr[i] = (PetscScalar)source_arr[i * stride];
529 }
else if (strcasecmp(internal_name,
"DMSwarm_CellID") == 0 || strcasecmp(internal_name,
"DMSwarm_location_status") == 0) {
530 PetscInt* source_arr = (PetscInt*)full_field_arr_void;
531 for (PetscInt i = 0; i < meta->
npoints; i++) {
532 PetscInt source_idx = i * stride;
538 PetscScalar* source_arr = (PetscScalar*)full_field_arr_void;
539 for (PetscInt i = 0; i < meta->
npoints; i++) {
540 PetscInt source_idx = i * stride;
547 ierr = PetscFree(full_field_arr_void);
549 field_name = strtok(NULL,
",");
551 ierr = PetscFree(fields_copy); CHKERRQ(ierr);
557 ierr = PetscMalloc1(meta->
npoints, &meta->
offsets); CHKERRQ(ierr);
558 for (PetscInt i = 0; i < meta->
npoints; i++) {
565 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
567 PetscFunctionReturn(0);
Holds all configuration parameters for a post-processing run.