228 PetscInt N_full_coords;
229 PetscScalar *full_coords_arr = NULL;
231 PetscFunctionBeginUser;
232 ierr = DMDAGetInfo(user->
da, NULL, &IM, &JM, &KM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
238 *out_npoints = (*out_nx) * (*out_ny) * (*out_nz);
240 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);
243 ierr = DMGetCoordinates(user->
da, &coords_global); CHKERRQ(ierr);
245 ierr =
VecToArrayOnRank0(coords_global, &N_full_coords, &full_coords_arr); CHKERRQ(ierr);
250 if (N_full_coords != IM * JM * KM * 3) {
251 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);
255 ierr = PetscMalloc1(3 * (*out_npoints), out_coords); CHKERRQ(ierr);
259 for (PetscInt k = 0; k < *out_nz; k++) {
260 for (PetscInt j = 0; j < *out_ny; j++) {
261 for (PetscInt i = 0; i < *out_nx; i++) {
263 PetscInt p_in = 3 * (k * (JM * IM) + j * IM + i);
265 (*out_coords)[p_out++] = full_coords_arr[p_in + 0];
266 (*out_coords)[p_out++] = full_coords_arr[p_in + 1];
267 (*out_coords)[p_out++] = full_coords_arr[p_in + 2];
272 ierr = PetscFree(full_coords_arr); CHKERRQ(ierr);
278 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
"Subsampled coordinates prepared on rank 0 with total %" PetscInt_FMT
" points.\n", *out_npoints);
280 PetscFunctionReturn(0);
290 PetscInt IM, JM, KM, nx, ny, nz, npoints;
291 PetscInt N_full_field = 0;
292 PetscScalar *full_field_arr = NULL;
294 PetscFunctionBeginUser;
295 ierr = DMDAGetInfo(user->
da, NULL, &IM, &JM, &KM, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL); CHKERRQ(ierr);
296 nx = IM - 1; ny = JM - 1; nz = KM - 1;
297 npoints = nx * ny * nz;
300 "Preparing subsampled field data (dof=%" PetscInt_FMT
") for a %" PetscInt_FMT
"x%" PetscInt_FMT
"x%" PetscInt_FMT
" grid.\n",
301 num_components, nx, ny, nz);
304 ierr =
VecToArrayOnRank0(field_vec, &N_full_field, &full_field_arr); CHKERRQ(ierr);
309 if (N_full_field != IM * JM * KM * num_components) {
310 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
311 "Gathered field array has wrong size. Expected %" PetscInt_FMT
", got %" PetscInt_FMT,
312 IM * JM * KM * num_components, N_full_field);
316 ierr = PetscMalloc1(num_components * npoints, out_data); CHKERRQ(ierr);
368 for (PetscInt k = 0; k < nz; k++) {
369 for (PetscInt j = 0; j < ny; j++) {
370 for (PetscInt i = 0; i < nx; i++) {
371 const PetscInt p_in_start = num_components * (k * (JM * IM) + j * IM + i);
372 for (PetscInt c = 0; c < num_components; c++) {
373 (*out_data)[p_out++] = full_field_arr[p_in_start + c];
381 ierr = PetscFree(full_field_arr); CHKERRQ(ierr);
387 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
"Subsampled field data prepared on rank 0 with total %" PetscInt_FMT
" points.\n", npoints);
389 PetscFunctionReturn(0);
424 PetscInt n_total_particles, n_components;
426 PetscFunctionBeginUser;
435 PetscScalar *full_coords_arr = NULL;
442 *p_n_total = n_total_particles;
444 if (n_total_particles == 0) {
445 if (full_coords_arr) {
446 ierr = PetscFree(full_coords_arr); CHKERRQ(ierr);
448 PetscFunctionReturn(0);
450 if (n_components != 3) {
451 SETERRQ(PETSC_COMM_SELF, 1,
"Coordinate field position must have 3 components, but has %" PetscInt_FMT, n_components);
456 meta->
npoints = (n_total_particles > 0) ? (n_total_particles - 1) / stride + 1 : 0;
458 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Subsampling %" PetscInt_FMT
" total particles with stride %" PetscInt_FMT
" -> %" PetscInt_FMT
" output particles.\n",
459 n_total_particles, stride, meta->
npoints);
462 ierr = PetscMalloc1(3 * meta->
npoints, &meta->
coords); CHKERRQ(ierr);
463 for (PetscInt i = 0; i < meta->
npoints; i++) {
464 PetscInt source_idx = i * stride;
465 for (
int d = 0; d < 3; d++) meta->
coords[3 * i + d] = full_coords_arr[3 * source_idx + d];
467 ierr = PetscFree(full_coords_arr);
471 char *fields_copy, *field_name;
472 ierr = PetscStrallocpy(pps->
particle_fields, &fields_copy); CHKERRQ(ierr);
473 field_name = strtok(fields_copy,
",");
476 if (!*field_name || strcasecmp(field_name,
"position") == 0) {
477 field_name = strtok(NULL,
",");
continue;
481 DM swarm_to_use = user->
swarm;
482 const char* internal_name = field_name;
484 PetscErrorCode check_ierr;
485 ierr = PetscPushErrorHandler(PetscIgnoreErrorHandler, NULL); CHKERRQ(ierr);
486 check_ierr = DMSwarmGetField(user->
post_swarm, field_name, NULL, NULL, NULL);
487 ierr = PetscPopErrorHandler(); CHKERRQ(ierr);
490 ierr = DMSwarmRestoreField(user->
post_swarm, field_name, NULL, NULL, NULL); CHKERRQ(ierr);
494 if (strcasecmp(field_name,
"pid") == 0) internal_name =
"DMSwarm_pid";
495 else if (strcasecmp(field_name,
"CellID") == 0) internal_name =
"DMSwarm_CellID";
496 else if (strcasecmp(field_name,
"Migration Status") == 0) internal_name =
"DMSwarm_location_status";
502 void* full_field_arr_void = NULL;
503 PetscInt field_total_particles, field_num_components;
505 ierr =
SwarmFieldToArrayOnRank0(swarm_to_use, internal_name, &field_total_particles, &field_num_components, &full_field_arr_void); CHKERRQ(ierr);
507 if (field_total_particles != n_total_particles) {
508 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);
509 ierr = PetscFree(full_field_arr_void); CHKERRQ(ierr);
510 field_name = strtok(NULL,
",");
continue;
520 PetscScalar* final_data_arr = (PetscScalar*)current_field->
data;
523 if (strcasecmp(internal_name,
"DMSwarm_pid") == 0) {
524 PetscInt64* source_arr = (PetscInt64*)full_field_arr_void;
525 for (PetscInt i = 0; i < meta->
npoints; i++) {
526 final_data_arr[i] = (PetscScalar)source_arr[i * stride];
528 }
else if (strcasecmp(internal_name,
"DMSwarm_CellID") == 0 || strcasecmp(internal_name,
"DMSwarm_location_status") == 0) {
529 PetscInt* source_arr = (PetscInt*)full_field_arr_void;
530 for (PetscInt i = 0; i < meta->
npoints; i++) {
531 PetscInt source_idx = i * stride;
537 PetscScalar* source_arr = (PetscScalar*)full_field_arr_void;
538 for (PetscInt i = 0; i < meta->
npoints; i++) {
539 PetscInt source_idx = i * stride;
546 ierr = PetscFree(full_field_arr_void);
548 field_name = strtok(NULL,
",");
550 ierr = PetscFree(fields_copy); CHKERRQ(ierr);
556 ierr = PetscMalloc1(meta->
npoints, &meta->
offsets); CHKERRQ(ierr);
557 for (PetscInt i = 0; i < meta->
npoints; i++) {
564 ierr = MPI_Barrier(PETSC_COMM_WORLD); CHKERRQ(ierr);
566 PetscFunctionReturn(0);
Holds all configuration parameters for a post-processing run.