214 UserCtx *user,
const DMDALocalInfo *info,
215 PetscInt xs_gnode_rank, PetscInt ys_gnode_rank, PetscInt zs_gnode_rank,
216 PetscInt IM_cells_global, PetscInt JM_cells_global, PetscInt KM_cells_global,
217 PetscInt64 particle_global_id,
218 PetscInt *ci_metric_lnode_out, PetscInt *cj_metric_lnode_out, PetscInt *ck_metric_lnode_out,
219 PetscReal *xi_metric_logic_out, PetscReal *eta_metric_logic_out, PetscReal *zta_metric_logic_out,
220 PetscBool *placement_successful_out)
223 PetscReal global_logic_i = 0.0, global_logic_j = 0.0, global_logic_k = 0.0;
225 PetscMPIInt rank_for_logging;
227 PetscFunctionBeginUser;
228 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank_for_logging); CHKERRQ(ierr);
230 *placement_successful_out = PETSC_FALSE;
235 const PetscInt grid_layers = 2;
238 "[Rank %d] Placing particle %lld on face %s with grid_layers=%d in global domain (%d,%d,%d) cells.\n",
240 IM_cells_global, JM_cells_global, KM_cells_global);
248 if (JM_cells_global <= 1 || KM_cells_global <= 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"Cannot place grid on face %s for a 2D/1D domain (J-cells=%d, K-cells=%d).", face_name, JM_cells_global, KM_cells_global);
249 if (2 * grid_layers >= JM_cells_global || 2 * grid_layers >= KM_cells_global) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
"Grid layers (%d) from opposing J/K faces would overlap in this domain (J-cells=%d, K-cells=%d).", grid_layers, JM_cells_global, KM_cells_global);
252 if (IM_cells_global <= 1 || KM_cells_global <= 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"Cannot place grid on face %s for a 2D/1D domain (I-cells=%d, K-cells=%d).", face_name, IM_cells_global, KM_cells_global);
253 if (2 * grid_layers >= IM_cells_global || 2 * grid_layers >= KM_cells_global) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
"Grid layers (%d) from opposing I/K faces would overlap in this domain (I-cells=%d, K-cells=%d).", grid_layers, IM_cells_global, KM_cells_global);
256 if (IM_cells_global <= 1 || JM_cells_global <= 1) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"Cannot place grid on face %s for a 2D/1D domain (I-cells=%d, J-cells=%d).", face_name, IM_cells_global, JM_cells_global);
257 if (2 * grid_layers >= IM_cells_global || 2 * grid_layers >= JM_cells_global) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
"Grid layers (%d) from opposing I/J faces would overlap in this domain (I-cells=%d, J-cells=%d).", grid_layers, IM_cells_global, JM_cells_global);
259 default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"Invalid identifiedInletBCFace specified: %d", user->
identifiedInletBCFace);
262 const PetscInt num_lines_total = 4 * grid_layers;
263 if (simCtx->
np < num_lines_total) {
264 LOG_ALLOW(
GLOBAL,
LOG_WARNING,
"Warning: Total particle count (%lld) is less than the number of grid lines requested (%d). Some lines may be empty.\n", (
long long)simCtx->
np, num_lines_total);
266 if (simCtx->
np > 0 && simCtx->
np % num_lines_total != 0) {
267 LOG_ALLOW(
GLOBAL,
LOG_WARNING,
"Warning: Total particle count (%lld) is not evenly divisible by the number of grid lines (%d). Distribution will be uneven.\n", (
long long)simCtx->
np, num_lines_total);
271 if (simCtx->
np == 0) PetscFunctionReturn(0);
274 rank_for_logging, (
long long)simCtx->
np, num_lines_total, face_name);
276 const PetscInt points_per_line = PetscMax(1, simCtx->
np / num_lines_total);
277 PetscInt line_index = particle_global_id / points_per_line;
278 PetscInt point_index_on_line = particle_global_id % points_per_line;
279 line_index = PetscMin(line_index, num_lines_total - 1);
282 const PetscInt edge_group = line_index / grid_layers;
283 const PetscInt layer_index = line_index % grid_layers;
286 const PetscReal layer_spacing_norm_i = (IM_cells_global > 0) ? 1.0 / (PetscReal)IM_cells_global : 0.0;
287 const PetscReal layer_spacing_norm_j = (JM_cells_global > 0) ? 1.0 / (PetscReal)JM_cells_global : 0.0;
288 const PetscReal layer_spacing_norm_k = (KM_cells_global > 0) ? 1.0 / (PetscReal)KM_cells_global : 0.0;
291 const PetscReal min_layer_spacing = PetscMin(layer_spacing_norm_i, PetscMin(layer_spacing_norm_j, layer_spacing_norm_k));
292 const PetscReal epsilon = 0.5 * min_layer_spacing;
294 PetscReal variable_coord;
295 if (points_per_line <= 1) {
296 variable_coord = 0.5;
298 variable_coord = ((PetscReal)point_index_on_line + 0.5)/ (PetscReal)(points_per_line);
300 variable_coord = PetscMin(1.0 - epsilon, PetscMax(epsilon, variable_coord));
305 global_logic_i = 0.5 * layer_spacing_norm_i;
306 if (edge_group == 0) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_k = variable_coord; }
307 else if (edge_group == 1) { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_k = variable_coord; }
308 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_j = variable_coord; }
309 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_j = variable_coord; }
312 global_logic_i = 1.0 - (0.5 * layer_spacing_norm_i);
313 if (edge_group == 0) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_k = variable_coord; }
314 else if (edge_group == 1) { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_k = variable_coord; }
315 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_j = variable_coord; }
316 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_j = variable_coord; }
319 global_logic_j = 0.5 * layer_spacing_norm_j;
320 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_k = variable_coord; }
321 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_k = variable_coord; }
322 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_i = variable_coord; }
323 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_i = variable_coord; }
326 global_logic_j = 1.0 - (0.5 * layer_spacing_norm_j);
327 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_k = variable_coord; }
328 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_k = variable_coord; }
329 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_i = variable_coord; }
330 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_i = variable_coord; }
333 global_logic_k = 0.5 * layer_spacing_norm_k;
334 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_j = variable_coord; }
335 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_j = variable_coord; }
336 else if (edge_group == 2) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_i = variable_coord; }
337 else { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_i = variable_coord; }
340 global_logic_k = 1.0 - (0.5 * layer_spacing_norm_k);
341 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_j = variable_coord; }
342 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_j = variable_coord; }
343 else if (edge_group == 2) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_i = variable_coord; }
344 else { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_i = variable_coord; }
349 "[Rank %d] Particle %lld assigned to line %d (edge group %d, layer %d) with variable_coord=%.4f.\n"
350 " -> Global logical coords: (i,j,k) = (%.6f, %.6f, %.6f)\n",
351 rank_for_logging, (
long long)particle_global_id, line_index, edge_group, layer_index, variable_coord,
352 global_logic_i, global_logic_j, global_logic_k);
355 PetscReal global_cell_coord_i = global_logic_i * IM_cells_global;
356 PetscInt I_g = (PetscInt)global_cell_coord_i;
357 *xi_metric_logic_out = global_cell_coord_i - I_g;
359 PetscReal global_cell_coord_j = global_logic_j * JM_cells_global;
360 PetscInt J_g = (PetscInt)global_cell_coord_j;
361 *eta_metric_logic_out = global_cell_coord_j - J_g;
363 PetscReal global_cell_coord_k = global_logic_k * KM_cells_global;
364 PetscInt K_g = (PetscInt)global_cell_coord_k;
365 *zta_metric_logic_out = global_cell_coord_k - K_g;
368 if ((I_g >= info->xs && I_g < info->xs + info->xm) &&
369 (J_g >= info->ys && J_g < info->ys + info->ym) &&
370 (K_g >= info->zs && K_g < info->zs + info->zm))
373 *ci_metric_lnode_out = (I_g - info->xs) + xs_gnode_rank;
374 *cj_metric_lnode_out = (J_g - info->ys) + ys_gnode_rank;
375 *ck_metric_lnode_out = (K_g - info->zs) + zs_gnode_rank;
376 *placement_successful_out = PETSC_TRUE;
380 "[Rank %d] Particle %lld placement %s.\n",
381 rank_for_logging, (
long long)particle_global_id,
382 (*placement_successful_out ?
"SUCCESSFUL" :
"NOT ON THIS RANK"));
384 if(*placement_successful_out){
385 LOG_ALLOW(
LOCAL,
LOG_TRACE,
"Local cell origin node: (I,J,K) = (%d,%d,%d), intra-cell logicals: (xi,eta,zta)=(%.6f,%.6f,%.6f)\n",
386 *ci_metric_lnode_out, *cj_metric_lnode_out, *ck_metric_lnode_out,
387 *xi_metric_logic_out, *eta_metric_logic_out, *zta_metric_logic_out);
390 PetscFunctionReturn(0);
401 UserCtx *user,
const DMDALocalInfo *info,
402 PetscInt xs_gnode_rank, PetscInt ys_gnode_rank, PetscInt zs_gnode_rank,
403 PetscInt IM_nodes_global, PetscInt JM_nodes_global, PetscInt KM_nodes_global,
404 PetscRandom *rand_logic_i_ptr, PetscRandom *rand_logic_j_ptr, PetscRandom *rand_logic_k_ptr,
405 PetscInt *ci_metric_lnode_out, PetscInt *cj_metric_lnode_out, PetscInt *ck_metric_lnode_out,
406 PetscReal *xi_metric_logic_out, PetscReal *eta_metric_logic_out, PetscReal *zta_metric_logic_out)
408 PetscErrorCode ierr = 0;
409 PetscReal r_val_i_sel, r_val_j_sel, r_val_k_sel;
410 PetscInt local_cell_idx_on_face_dim1 = 0;
411 PetscInt local_cell_idx_on_face_dim2 = 0;
412 PetscMPIInt rank_for_logging;
414 PetscFunctionBeginUser;
418 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank_for_logging); CHKERRQ(ierr);
421 PetscInt owned_start_cell_i, num_owned_cells_on_rank_i;
422 PetscInt owned_start_cell_j, num_owned_cells_on_rank_j;
423 PetscInt owned_start_cell_k, num_owned_cells_on_rank_k;
425 ierr =
GetOwnedCellRange(info, 0, &owned_start_cell_i, &num_owned_cells_on_rank_i); CHKERRQ(ierr);
426 ierr =
GetOwnedCellRange(info, 1, &owned_start_cell_j, &num_owned_cells_on_rank_j); CHKERRQ(ierr);
427 ierr =
GetOwnedCellRange(info, 2, &owned_start_cell_k, &num_owned_cells_on_rank_k); CHKERRQ(ierr);
430 *ci_metric_lnode_out = xs_gnode_rank; *cj_metric_lnode_out = ys_gnode_rank; *ck_metric_lnode_out = zs_gnode_rank;
432 *xi_metric_logic_out = 0.5; *eta_metric_logic_out = 0.5; *zta_metric_logic_out = 0.5;
435 PetscInt last_global_cell_idx_i = (IM_nodes_global > 1) ? (IM_nodes_global - 2) : -1;
436 PetscInt last_global_cell_idx_j = (JM_nodes_global > 1) ? (JM_nodes_global - 2) : -1;
437 PetscInt last_global_cell_idx_k = (KM_nodes_global > 1) ? (KM_nodes_global - 2) : -1;
440 " Owned cells (i,j,k): (%d,%d,%d)\n"
441 " Global nodes (I,J,K): (%d,%d,%d)\n"
442 " info->xs,ys,zs (first owned node GLOBAL): (%d,%d,%d)\n"
443 " info->xm,ym,zm (num owned nodes GLOBAL): (%d,%d,%d)\n"
444 " xs_gnode_rank,ys_gnode_rank,zs_gnode_rank (DMDAGetCorners): (%d,%d,%d)\n"
445 " owned_start_cell (i,j,k) GLOBAL: (%d,%d,%d)\n"
446 " last_global_cell_idx (i,j,k): (%d,%d,%d)\n",
448 num_owned_cells_on_rank_i,num_owned_cells_on_rank_j,num_owned_cells_on_rank_k,
449 IM_nodes_global,JM_nodes_global,KM_nodes_global,
450 info->xs, info->ys, info->zs,
451 info->xm, info->ym, info->zm,
452 xs_gnode_rank,ys_gnode_rank,zs_gnode_rank,
453 owned_start_cell_i, owned_start_cell_j, owned_start_cell_k,
454 last_global_cell_idx_i, last_global_cell_idx_j, last_global_cell_idx_k);
461 *ci_metric_lnode_out = xs_gnode_rank;
462 *xi_metric_logic_out = 1.0e-6;
466 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
467 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
468 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_j - 1);
469 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim1;
471 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
472 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
473 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
474 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
476 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
477 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
483 *ci_metric_lnode_out = xs_gnode_rank + (last_global_cell_idx_i - info->xs);
484 *xi_metric_logic_out = 1.0 - 1.0e-6;
486 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
487 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
488 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_j - 1);
489 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim1;
491 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
492 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
493 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
494 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
496 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
497 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
501 *cj_metric_lnode_out = ys_gnode_rank;
502 *eta_metric_logic_out = 1.0e-6;
503 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
504 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
505 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
506 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
507 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
508 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
509 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
510 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
511 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
512 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
515 *cj_metric_lnode_out = ys_gnode_rank + (last_global_cell_idx_j - info->ys);
516 *eta_metric_logic_out = 1.0 - 1.0e-6;
517 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
518 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
519 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
520 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
521 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
522 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
523 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
524 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
525 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
526 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
529 *ck_metric_lnode_out = zs_gnode_rank;
530 *zta_metric_logic_out = 1.0e-6;
532 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
533 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
534 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
535 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
537 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
538 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
539 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_j - 1);
540 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim2;
542 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
543 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
546 *ck_metric_lnode_out = zs_gnode_rank + (last_global_cell_idx_k - info->zs);
547 *zta_metric_logic_out = 1.0 - 1.0e-6;
548 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
549 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
550 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
551 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
552 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
553 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
554 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_j - 1);
555 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim2;
556 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
557 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
560 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"GetRandomCellAndLogicOnInletFace: Invalid user->identifiedInletBCFace %d. \n", user->
identifiedInletBCFace);
563 PetscReal eps = 1.0e-7;
565 *eta_metric_logic_out = PetscMin(PetscMax(0.0, *eta_metric_logic_out), 1.0 - eps);
566 *zta_metric_logic_out = PetscMin(PetscMax(0.0, *zta_metric_logic_out), 1.0 - eps);
568 *xi_metric_logic_out = PetscMin(PetscMax(0.0, *xi_metric_logic_out), 1.0 - eps);
569 *zta_metric_logic_out = PetscMin(PetscMax(0.0, *zta_metric_logic_out), 1.0 - eps);
571 *xi_metric_logic_out = PetscMin(PetscMax(0.0, *xi_metric_logic_out), 1.0 - eps);
572 *eta_metric_logic_out = PetscMin(PetscMax(0.0, *eta_metric_logic_out), 1.0 - eps);
576 rank_for_logging, *ci_metric_lnode_out, *cj_metric_lnode_out, *ck_metric_lnode_out,
577 *xi_metric_logic_out, *eta_metric_logic_out, *zta_metric_logic_out);
581 PetscFunctionReturn(0);
1046 PetscErrorCode ierr;
1047 PetscFunctionBeginUser;
1056 PetscReal local_inflow_pre = 0.0;
1057 PetscReal local_inflow_post = 0.0;
1058 PetscReal global_inflow_pre = 0.0;
1059 PetscReal global_inflow_post = 0.0;
1060 PetscInt num_handlers[3] = {0,0,0};
1065 for (
int i = 0; i < 6; i++) {
1068 if (!handler->
PreStep)
continue;
1074 .global_inflow_sum = NULL,
1075 .global_outflow_sum = NULL,
1081 ierr = handler->
PreStep(handler, &ctx, &local_inflow_pre, NULL); CHKERRQ(ierr);
1085 if (local_inflow_pre != 0.0) {
1086 ierr = MPI_Allreduce(&local_inflow_pre, &global_inflow_pre, 1, MPIU_REAL,
1087 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1092 for (
int i = 0; i < 6; i++) {
1095 if(!handler->
Apply)
continue;
1102 .global_inflow_sum = NULL,
1103 .global_outflow_sum = NULL,
1109 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1113 for (
int i = 0; i < 6; i++) {
1123 .global_inflow_sum = NULL,
1124 .global_outflow_sum = NULL,
1130 ierr = handler->
PostStep(handler, &ctx, &local_inflow_post, NULL); CHKERRQ(ierr);
1134 ierr = MPI_Allreduce(&local_inflow_post, &global_inflow_post, 1, MPIU_REAL,
1135 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1141 " (INLETS): %d Prestep(s), %d Application(s), %d Poststep(s), FluxInSum = %.6e\n",
1142 num_handlers[0],num_handlers[1],num_handlers[2], global_inflow_post);
1148 PetscReal local_farfield_in_pre = 0.0;
1149 PetscReal local_farfield_out_pre = 0.0;
1150 PetscReal local_farfield_in_post = 0.0;
1151 PetscReal local_farfield_out_post = 0.0;
1152 PetscReal global_farfield_in_pre = 0.0;
1153 PetscReal global_farfield_out_pre = 0.0;
1154 PetscReal global_farfield_in_post = 0.0;
1155 PetscReal global_farfield_out_post = 0.0;
1156 memset(num_handlers,0,
sizeof(num_handlers));
1161 for (
int i = 0; i < 6; i++) {
1164 if (!handler->
PreStep)
continue;
1171 .global_outflow_sum = NULL,
1177 ierr = handler->
PreStep(handler, &ctx, &local_farfield_in_pre, &local_farfield_out_pre);
1182 if (local_farfield_in_pre != 0.0 || local_farfield_out_pre != 0.0) {
1183 ierr = MPI_Allreduce(&local_farfield_in_pre, &global_farfield_in_pre, 1, MPIU_REAL,
1184 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1185 ierr = MPI_Allreduce(&local_farfield_out_pre, &global_farfield_out_pre, 1, MPIU_REAL,
1186 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1189 " Farfield pre-analysis: In=%.6e, Out=%.6e\n",
1190 global_farfield_in_pre, global_farfield_out_pre);
1194 for (
int i = 0; i < 6; i++) {
1197 if(!handler->
Apply)
continue;
1205 .global_outflow_sum = NULL,
1211 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1215 for (
int i = 0; i < 6; i++) {
1226 .global_outflow_sum = NULL,
1232 ierr = handler->
PostStep(handler, &ctx, &local_farfield_in_post, &local_farfield_out_post);
1237 if (num_handlers > 0) {
1238 ierr = MPI_Allreduce(&local_farfield_in_post, &global_farfield_in_post, 1, MPIU_REAL,
1239 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1240 ierr = MPI_Allreduce(&local_farfield_out_post, &global_farfield_out_post, 1, MPIU_REAL,
1241 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1248 " (FARFIELD): %d Prestep(s), %d Application(s), %d Poststep(s) , InFlux=%.6e, OutFlux=%.6e\n",
1249 num_handlers[0],num_handlers[1],num_handlers[2], global_farfield_in_post, global_farfield_out_post);
1261 memset(num_handlers,0,
sizeof(num_handlers));
1266 for (
int i = 0; i < 6; i++) {
1269 if (!handler->
PreStep)
continue;
1276 .global_outflow_sum = NULL,
1282 ierr = handler->
PreStep(handler, &ctx, NULL, NULL); CHKERRQ(ierr);
1288 for (
int i = 0; i < 6; i++) {
1291 if(!handler->
Apply)
continue;
1299 .global_outflow_sum = NULL,
1305 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1309 for (
int i = 0; i < 6; i++) {
1320 .global_outflow_sum = NULL,
1326 ierr = handler->
PostStep(handler, &ctx, NULL, NULL); CHKERRQ(ierr);
1332 num_handlers[0],num_handlers[1],num_handlers[2]);
1339 PetscReal local_outflow_pre = 0.0;
1340 PetscReal local_outflow_post = 0.0;
1341 PetscReal global_outflow_pre = 0.0;
1342 PetscReal global_outflow_post = 0.0;
1343 memset(num_handlers,0,
sizeof(num_handlers));
1348 for (
int i = 0; i < 6; i++) {
1351 if (!handler->
PreStep)
continue;
1358 .global_outflow_sum = NULL,
1364 ierr = handler->
PreStep(handler, &ctx, NULL, &local_outflow_pre); CHKERRQ(ierr);
1368 ierr = MPI_Allreduce(&local_outflow_pre, &global_outflow_pre, 1, MPIU_REAL,
1369 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1375 " Uncorrected outflow: %.6e, Total inflow: %.6e (Inlet: %.6e + Farfield: %.6e)\n",
1380 for (
int i = 0; i < 6; i++) {
1383 if(!handler->
Apply)
continue;
1391 .global_outflow_sum = &global_outflow_pre,
1397 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1401 for (
int i = 0; i < 6; i++) {
1412 .global_outflow_sum = &global_outflow_pre,
1418 ierr = handler->
PostStep(handler, &ctx, NULL, &local_outflow_post); CHKERRQ(ierr);
1422 ierr = MPI_Allreduce(&local_outflow_post, &global_outflow_post, 1, MPIU_REAL,
1423 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1430 PetscReal flux_error = PetscAbsReal(total_outflow - total_inflow);
1431 PetscReal relative_error = (total_inflow > 1e-16) ?
1432 flux_error / total_inflow : flux_error;
1435 " (OUTLETS): %d Prestep(s), %d Application(s), %d Poststep(s), FluxOutSum = %.6e\n",
1436 num_handlers[0],num_handlers[1],num_handlers[2], global_outflow_post);
1438 " Conservation: Total In=%.6e, Total Out=%.6e, Error=%.3e (%.2e)%%)\n",
1439 total_inflow, total_outflow, flux_error, relative_error * 100.0);
1441 if (relative_error > 1e-6) {
1443 " WARNING: Large mass conservation error (%.2e%%)!\n",
1444 relative_error * 100.0);
1451 PetscFunctionReturn(0);
2336 DMDALocalInfo info = user->
info;
2337 PetscInt xs = info.xs, xe = info.xs + info.xm;
2338 PetscInt ys = info.ys, ye = info.ys + info.ym;
2339 PetscInt zs = info.zs, ze = info.zs + info.zm;
2340 PetscInt mx = info.mx, my = info.my, mz = info.mz;
2342 PetscScalar ****f = NULL;
2345 PetscFunctionBeginUser;
2350 PetscCall(DMDAVecGetArrayDOF(view.
dm, view.
global_vec, &f));
2353#define EDGE_AVERAGE(tk, tj, ti, ak, aj, ai, bk, bj, bi) \
2354 for (PetscInt c = 0; c < dof; c++) f[tk][tj][ti][c] = 0.5 * (f[ak][aj][ai][c] + f[bk][bj][bi][c])
2361 if (xs == 0)
for (PetscInt j = ys; j < ye; j++) {
EDGE_AVERAGE(zs, j, xs, zs+1, j, xs, zs, j, xs+1); }
2362 if (xe == mx)
for (PetscInt j = ys; j < ye; j++) {
EDGE_AVERAGE(zs, j, mx-1, zs+1, j, mx-1, zs, j, mx-2); }
2363 if (ys == 0)
for (PetscInt i = xs; i < xe; i++) {
EDGE_AVERAGE(zs, ys, i, zs+1, ys, i, zs, ys+1, i); }
2364 if (ye == my)
for (PetscInt i = xs; i < xe; i++) {
EDGE_AVERAGE(zs, my-1, i, zs+1, my-1, i, zs, my-2, i); }
2368 if (xs == 0)
for (PetscInt j = ys; j < ye; j++) {
EDGE_AVERAGE(mz-1, j, xs, mz-2, j, xs, mz-1, j, xs+1); }
2369 if (xe == mx)
for (PetscInt j = ys; j < ye; j++) {
EDGE_AVERAGE(mz-1, j, mx-1, mz-2, j, mx-1, mz-1, j, mx-2); }
2370 if (ys == 0)
for (PetscInt i = xs; i < xe; i++) {
EDGE_AVERAGE(mz-1, ys, i, mz-2, ys, i, mz-1, ys+1, i); }
2371 if (ye == my)
for (PetscInt i = xs; i < xe; i++) {
EDGE_AVERAGE(mz-1, my-1, i, mz-2, my-1, i, mz-1, my-2, i); }
2375 if (xs == 0)
for (PetscInt k = zs; k < ze; k++) {
EDGE_AVERAGE(k, ys, xs, k, ys+1, xs, k, ys, xs+1); }
2376 if (xe == mx)
for (PetscInt k = zs; k < ze; k++) {
EDGE_AVERAGE(k, ys, mx-1, k, ys+1, mx-1, k, ys, mx-2); }
2379 if (xs == 0)
for (PetscInt k = zs; k < ze; k++) {
EDGE_AVERAGE(k, my-1, xs, k, my-2, xs, k, my-1, xs+1); }
2380 if (xe == mx)
for (PetscInt k = zs; k < ze; k++) {
EDGE_AVERAGE(k, my-1, mx-1, k, my-2, mx-1, k, my-1, mx-2); }
2384 PetscCall(DMDAVecRestoreArrayDOF(view.
dm, view.
global_vec, &f));
2385 PetscFunctionReturn(0);
2509 PetscErrorCode ierr;
2511 DMDALocalInfo *info = &user->
info;
2513 PetscFunctionBeginUser;
2519 PetscFunctionReturn(0);
2528 ierr = VecSet(user->
Nu_Wall, 0.0); CHKERRQ(ierr);
2533 Cmpnts ***velocity_cartesian;
2534 Cmpnts ***velocity_contravariant;
2535 Cmpnts ***velocity_boundary;
2536 Cmpnts ***csi, ***eta, ***zet;
2537 PetscReal ***node_vertex_flag;
2538 PetscReal ***cell_jacobian;
2539 PetscReal ***wall_eddy_viscosity;
2540 PetscReal ***friction_velocity;
2541 PetscReal ***wall_pressure = NULL;
2543 ierr = DMDAVecGetArray(user->
fda, user->
Ucat, &velocity_cartesian); CHKERRQ(ierr);
2544 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &velocity_contravariant); CHKERRQ(ierr);
2545 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &velocity_boundary); CHKERRQ(ierr);
2546 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2547 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2548 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2549 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&node_vertex_flag); CHKERRQ(ierr);
2550 ierr = DMDAVecGetArrayRead(user->
da, user->
lAj, (
const PetscReal***)&cell_jacobian); CHKERRQ(ierr);
2553 ierr = DMDAVecGetArray(user->
da, user->
Friction_Velocity, &friction_velocity); CHKERRQ(ierr);
2554 ierr = DMDAVecGetArray(user->
da, user->
Nu_Wall, &wall_eddy_viscosity); CHKERRQ(ierr);
2557 ierr = DMDAVecGetArrayRead(user->
da, user->
lP, (
const PetscReal ***)&wall_pressure); CHKERRQ(ierr);
2562 PetscInt grid_start_i = info->xs, grid_end_i = info->xs + info->xm;
2563 PetscInt grid_start_j = info->ys, grid_end_j = info->ys + info->ym;
2564 PetscInt grid_start_k = info->zs, grid_end_k = info->zs + info->zm;
2565 PetscInt grid_size_i = info->mx, grid_size_j = info->my, grid_size_k = info->mz;
2568 PetscInt loop_start_i = grid_start_i, loop_end_i = grid_end_i;
2569 PetscInt loop_start_j = grid_start_j, loop_end_j = grid_end_j;
2570 PetscInt loop_start_k = grid_start_k, loop_end_k = grid_end_k;
2572 if (grid_start_i == 0) loop_start_i = grid_start_i + 1;
2573 if (grid_end_i == grid_size_i) loop_end_i = grid_end_i - 1;
2574 if (grid_start_j == 0) loop_start_j = grid_start_j + 1;
2575 if (grid_end_j == grid_size_j) loop_end_j = grid_end_j - 1;
2576 if (grid_start_k == 0) loop_start_k = grid_start_k + 1;
2577 if (grid_end_k == grid_size_k) loop_end_k = grid_end_k - 1;
2585 for (
int face_index = 0; face_index < 6; face_index++) {
2595 PetscBool rank_owns_this_face;
2597 current_face_id, &rank_owns_this_face); CHKERRQ(ierr);
2599 if (!rank_owns_this_face) {
2609 switch(current_face_id) {
2615 if (grid_start_i == 0) {
2616 const PetscInt ghost_cell_index = grid_start_i;
2617 const PetscInt first_interior_cell = grid_start_i + 1;
2618 const PetscInt second_interior_cell = grid_start_i + 2;
2620 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2621 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
2624 if (node_vertex_flag[k][j][first_interior_cell] < 0.1) {
2627 PetscReal face_area = sqrt(
2628 csi[k][j][ghost_cell_index].x * csi[k][j][ghost_cell_index].x +
2629 csi[k][j][ghost_cell_index].y * csi[k][j][ghost_cell_index].y +
2630 csi[k][j][ghost_cell_index].z * csi[k][j][ghost_cell_index].z
2636 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][j][first_interior_cell] / face_area;
2637 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2638 0.5 / cell_jacobian[k][j][second_interior_cell] / face_area;
2641 PetscReal wall_normal[3];
2642 wall_normal[0] = csi[k][j][ghost_cell_index].
x / face_area;
2643 wall_normal[1] = csi[k][j][ghost_cell_index].
y / face_area;
2644 wall_normal[2] = csi[k][j][ghost_cell_index].
z / face_area;
2648 Cmpnts reference_velocity;
2650 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2651 reference_velocity = velocity_cartesian[k][j][second_interior_cell];
2654 noslip(user, distance_to_second_cell, distance_to_first_cell,
2655 wall_velocity, reference_velocity,
2656 &velocity_cartesian[k][j][first_interior_cell],
2657 wall_normal[0], wall_normal[1], wall_normal[2]);
2661 first_interior_cell, j, k,
2662 wall_roughness_height,
2663 distance_to_second_cell, distance_to_first_cell,
2664 wall_velocity, reference_velocity,
2665 &velocity_cartesian[k][j][first_interior_cell],
2666 &friction_velocity[k][j][first_interior_cell],
2667 wall_normal[0], wall_normal[1], wall_normal[2]); CHKERRQ(ierr);
2670 velocity_boundary[k][j][ghost_cell_index].
x = 0.0;
2671 velocity_boundary[k][j][ghost_cell_index].
y = 0.0;
2672 velocity_boundary[k][j][ghost_cell_index].
z = 0.0;
2673 velocity_contravariant[k][j][ghost_cell_index].
x = 0.0;
2684 if (grid_end_i == grid_size_i) {
2685 const PetscInt ghost_cell_index = grid_end_i - 1;
2686 const PetscInt first_interior_cell = grid_end_i - 2;
2687 const PetscInt second_interior_cell = grid_end_i - 3;
2689 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2690 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
2692 if (node_vertex_flag[k][j][first_interior_cell] < 0.1) {
2694 PetscReal face_area = sqrt(
2695 csi[k][j][first_interior_cell].x * csi[k][j][first_interior_cell].x +
2696 csi[k][j][first_interior_cell].y * csi[k][j][first_interior_cell].y +
2697 csi[k][j][first_interior_cell].z * csi[k][j][first_interior_cell].z
2700 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][j][first_interior_cell] / face_area;
2701 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2702 0.5 / cell_jacobian[k][j][second_interior_cell] / face_area;
2705 PetscReal wall_normal[3];
2706 wall_normal[0] = -csi[k][j][first_interior_cell].
x / face_area;
2707 wall_normal[1] = -csi[k][j][first_interior_cell].
y / face_area;
2708 wall_normal[2] = -csi[k][j][first_interior_cell].
z / face_area;
2710 Cmpnts wall_velocity, reference_velocity;
2711 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2712 reference_velocity = velocity_cartesian[k][j][second_interior_cell];
2714 noslip(user, distance_to_second_cell, distance_to_first_cell,
2715 wall_velocity, reference_velocity,
2716 &velocity_cartesian[k][j][first_interior_cell],
2717 wall_normal[0], wall_normal[1], wall_normal[2]);
2720 first_interior_cell, j, k,
2721 wall_roughness_height,
2722 distance_to_second_cell, distance_to_first_cell,
2723 wall_velocity, reference_velocity,
2724 &velocity_cartesian[k][j][first_interior_cell],
2725 &friction_velocity[k][j][first_interior_cell],
2726 wall_normal[0], wall_normal[1], wall_normal[2]); CHKERRQ(ierr);
2728 velocity_boundary[k][j][ghost_cell_index].
x = 0.0;
2729 velocity_boundary[k][j][ghost_cell_index].
y = 0.0;
2730 velocity_boundary[k][j][ghost_cell_index].
z = 0.0;
2731 velocity_contravariant[k][j][first_interior_cell].
x = 0.0;
2742 if (grid_start_j == 0) {
2743 const PetscInt ghost_cell_index = grid_start_j;
2744 const PetscInt first_interior_cell = grid_start_j + 1;
2745 const PetscInt second_interior_cell = grid_start_j + 2;
2747 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2748 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
2750 if (node_vertex_flag[k][first_interior_cell][i] < 0.1) {
2752 PetscReal face_area = sqrt(
2753 eta[k][ghost_cell_index][i].x * eta[k][ghost_cell_index][i].x +
2754 eta[k][ghost_cell_index][i].y * eta[k][ghost_cell_index][i].y +
2755 eta[k][ghost_cell_index][i].z * eta[k][ghost_cell_index][i].z
2758 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][first_interior_cell][i] / face_area;
2759 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2760 0.5 / cell_jacobian[k][second_interior_cell][i] / face_area;
2762 PetscReal wall_normal[3];
2763 wall_normal[0] = eta[k][ghost_cell_index][i].
x / face_area;
2764 wall_normal[1] = eta[k][ghost_cell_index][i].
y / face_area;
2765 wall_normal[2] = eta[k][ghost_cell_index][i].
z / face_area;
2767 Cmpnts wall_velocity, reference_velocity;
2768 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2769 reference_velocity = velocity_cartesian[k][second_interior_cell][i];
2771 noslip(user, distance_to_second_cell, distance_to_first_cell,
2772 wall_velocity, reference_velocity,
2773 &velocity_cartesian[k][first_interior_cell][i],
2774 wall_normal[0], wall_normal[1], wall_normal[2]);
2777 i, first_interior_cell, k,
2778 wall_roughness_height,
2779 distance_to_second_cell, distance_to_first_cell,
2780 wall_velocity, reference_velocity,
2781 &velocity_cartesian[k][first_interior_cell][i],
2782 &friction_velocity[k][first_interior_cell][i],
2783 wall_normal[0], wall_normal[1], wall_normal[2]); CHKERRQ(ierr);
2785 velocity_boundary[k][ghost_cell_index][i].
x = 0.0;
2786 velocity_boundary[k][ghost_cell_index][i].
y = 0.0;
2787 velocity_boundary[k][ghost_cell_index][i].
z = 0.0;
2788 velocity_contravariant[k][ghost_cell_index][i].
y = 0.0;
2799 if (grid_end_j == grid_size_j) {
2800 const PetscInt ghost_cell_index = grid_end_j - 1;
2801 const PetscInt first_interior_cell = grid_end_j - 2;
2802 const PetscInt second_interior_cell = grid_end_j - 3;
2804 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2805 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
2807 if (node_vertex_flag[k][first_interior_cell][i] < 0.1) {
2809 PetscReal face_area = sqrt(
2810 eta[k][first_interior_cell][i].x * eta[k][first_interior_cell][i].x +
2811 eta[k][first_interior_cell][i].y * eta[k][first_interior_cell][i].y +
2812 eta[k][first_interior_cell][i].z * eta[k][first_interior_cell][i].z
2815 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][first_interior_cell][i] / face_area;
2816 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2817 0.5 / cell_jacobian[k][second_interior_cell][i] / face_area;
2819 PetscReal wall_normal[3];
2820 wall_normal[0] = -eta[k][first_interior_cell][i].
x / face_area;
2821 wall_normal[1] = -eta[k][first_interior_cell][i].
y / face_area;
2822 wall_normal[2] = -eta[k][first_interior_cell][i].
z / face_area;
2824 Cmpnts wall_velocity, reference_velocity;
2825 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2826 reference_velocity = velocity_cartesian[k][second_interior_cell][i];
2828 noslip(user, distance_to_second_cell, distance_to_first_cell,
2829 wall_velocity, reference_velocity,
2830 &velocity_cartesian[k][first_interior_cell][i],
2831 wall_normal[0], wall_normal[1], wall_normal[2]);
2834 i, first_interior_cell, k,
2835 wall_roughness_height,
2836 distance_to_second_cell, distance_to_first_cell,
2837 wall_velocity, reference_velocity,
2838 &velocity_cartesian[k][first_interior_cell][i],
2839 &friction_velocity[k][first_interior_cell][i],
2840 wall_normal[0], wall_normal[1], wall_normal[2]); CHKERRQ(ierr);
2842 velocity_boundary[k][ghost_cell_index][i].
x = 0.0;
2843 velocity_boundary[k][ghost_cell_index][i].
y = 0.0;
2844 velocity_boundary[k][ghost_cell_index][i].
z = 0.0;
2845 velocity_contravariant[k][first_interior_cell][i].
y = 0.0;
2856 if (grid_start_k == 0) {
2857 const PetscInt ghost_cell_index = grid_start_k;
2858 const PetscInt first_interior_cell = grid_start_k + 1;
2859 const PetscInt second_interior_cell = grid_start_k + 2;
2861 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
2862 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
2864 if (node_vertex_flag[first_interior_cell][j][i] < 0.1) {
2866 PetscReal face_area = sqrt(
2867 zet[ghost_cell_index][j][i].x * zet[ghost_cell_index][j][i].x +
2868 zet[ghost_cell_index][j][i].y * zet[ghost_cell_index][j][i].y +
2869 zet[ghost_cell_index][j][i].z * zet[ghost_cell_index][j][i].z
2872 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[first_interior_cell][j][i] / face_area;
2873 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2874 0.5 / cell_jacobian[second_interior_cell][j][i] / face_area;
2876 PetscReal wall_normal[3];
2877 wall_normal[0] = zet[ghost_cell_index][j][i].
x / face_area;
2878 wall_normal[1] = zet[ghost_cell_index][j][i].
y / face_area;
2879 wall_normal[2] = zet[ghost_cell_index][j][i].
z / face_area;
2881 Cmpnts wall_velocity, reference_velocity;
2882 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2883 reference_velocity = velocity_cartesian[second_interior_cell][j][i];
2885 noslip(user, distance_to_second_cell, distance_to_first_cell,
2886 wall_velocity, reference_velocity,
2887 &velocity_cartesian[first_interior_cell][j][i],
2888 wall_normal[0], wall_normal[1], wall_normal[2]);
2891 i, j, first_interior_cell,
2892 wall_roughness_height,
2893 distance_to_second_cell, distance_to_first_cell,
2894 wall_velocity, reference_velocity,
2895 &velocity_cartesian[first_interior_cell][j][i],
2896 &friction_velocity[first_interior_cell][j][i],
2897 wall_normal[0], wall_normal[1], wall_normal[2]); CHKERRQ(ierr);
2899 velocity_boundary[ghost_cell_index][j][i].
x = 0.0;
2900 velocity_boundary[ghost_cell_index][j][i].
y = 0.0;
2901 velocity_boundary[ghost_cell_index][j][i].
z = 0.0;
2902 velocity_contravariant[ghost_cell_index][j][i].
z = 0.0;
2913 if (grid_end_k == grid_size_k) {
2914 const PetscInt ghost_cell_index = grid_end_k - 1;
2915 const PetscInt first_interior_cell = grid_end_k - 2;
2916 const PetscInt second_interior_cell = grid_end_k - 3;
2918 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
2919 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
2921 if (node_vertex_flag[first_interior_cell][j][i] < 0.1) {
2923 PetscReal face_area = sqrt(
2924 zet[first_interior_cell][j][i].x * zet[first_interior_cell][j][i].x +
2925 zet[first_interior_cell][j][i].y * zet[first_interior_cell][j][i].y +
2926 zet[first_interior_cell][j][i].z * zet[first_interior_cell][j][i].z
2929 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[first_interior_cell][j][i] / face_area;
2930 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2931 0.5 / cell_jacobian[second_interior_cell][j][i] / face_area;
2933 PetscReal wall_normal[3];
2934 wall_normal[0] = -zet[first_interior_cell][j][i].
x / face_area;
2935 wall_normal[1] = -zet[first_interior_cell][j][i].
y / face_area;
2936 wall_normal[2] = -zet[first_interior_cell][j][i].
z / face_area;
2938 Cmpnts wall_velocity, reference_velocity;
2939 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2940 reference_velocity = velocity_cartesian[second_interior_cell][j][i];
2942 noslip(user, distance_to_second_cell, distance_to_first_cell,
2943 wall_velocity, reference_velocity,
2944 &velocity_cartesian[first_interior_cell][j][i],
2945 wall_normal[0], wall_normal[1], wall_normal[2]);
2948 i, j, first_interior_cell,
2949 wall_roughness_height,
2950 distance_to_second_cell, distance_to_first_cell,
2951 wall_velocity, reference_velocity,
2952 &velocity_cartesian[first_interior_cell][j][i],
2953 &friction_velocity[first_interior_cell][j][i],
2954 wall_normal[0], wall_normal[1], wall_normal[2]); CHKERRQ(ierr);
2956 velocity_boundary[ghost_cell_index][j][i].
x = 0.0;
2957 velocity_boundary[ghost_cell_index][j][i].
y = 0.0;
2958 velocity_boundary[ghost_cell_index][j][i].
z = 0.0;
2959 velocity_contravariant[first_interior_cell][j][i].
z = 0.0;
2971 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucat, &velocity_cartesian); CHKERRQ(ierr);
2972 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &velocity_contravariant); CHKERRQ(ierr);
2973 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &velocity_boundary); CHKERRQ(ierr);
2974 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2975 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2976 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2977 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&node_vertex_flag); CHKERRQ(ierr);
2978 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lAj, (
const PetscReal***)&cell_jacobian); CHKERRQ(ierr);
2979 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lP, (
const PetscReal ***)&wall_pressure); CHKERRQ(ierr);
2980 ierr = DMDAVecRestoreArray(user->
da, user->
Nu_Wall, &wall_eddy_viscosity); CHKERRQ(ierr);
2981 ierr = DMDAVecRestoreArray(user->
da, user->
Friction_Velocity, &friction_velocity); CHKERRQ(ierr);
2990 PetscFunctionReturn(0);