269 UserCtx *user,
const DMDALocalInfo *info,
270 PetscInt xs_gnode_rank, PetscInt ys_gnode_rank, PetscInt zs_gnode_rank,
271 PetscInt IM_cells_global, PetscInt JM_cells_global, PetscInt KM_cells_global,
272 PetscInt64 particle_global_id,
273 PetscInt *ci_metric_lnode_out, PetscInt *cj_metric_lnode_out, PetscInt *ck_metric_lnode_out,
274 PetscReal *xi_metric_logic_out, PetscReal *eta_metric_logic_out, PetscReal *zta_metric_logic_out,
275 PetscBool *placement_successful_out)
278 PetscReal global_logic_i, global_logic_j, global_logic_k;
280 PetscMPIInt rank_for_logging;
282 PetscFunctionBeginUser;
283 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank_for_logging); CHKERRQ(ierr);
285 *placement_successful_out = PETSC_FALSE;
290 const PetscInt grid_layers = 2;
293 "[Rank %d] Placing particle %lld on face %s with grid_layers=%d in global domain (%d,%d,%d) cells.\n",
295 IM_cells_global, JM_cells_global, KM_cells_global);
303 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);
304 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);
307 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);
308 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);
311 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);
312 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);
314 default: SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"Invalid identifiedInletBCFace specified: %d", user->
identifiedInletBCFace);
317 const PetscInt num_lines_total = 4 * grid_layers;
318 if (simCtx->
np < num_lines_total) {
319 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);
321 if (simCtx->
np > 0 && simCtx->
np % num_lines_total != 0) {
322 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);
326 if (simCtx->
np == 0) PetscFunctionReturn(0);
329 rank_for_logging, (
long long)simCtx->
np, num_lines_total, face_name);
331 const PetscInt points_per_line = PetscMax(1, simCtx->
np / num_lines_total);
332 PetscInt line_index = particle_global_id / points_per_line;
333 PetscInt point_index_on_line = particle_global_id % points_per_line;
334 line_index = PetscMin(line_index, num_lines_total - 1);
337 const PetscInt edge_group = line_index / grid_layers;
338 const PetscInt layer_index = line_index % grid_layers;
341 const PetscReal layer_spacing_norm_i = (IM_cells_global > 0) ? 1.0 / (PetscReal)IM_cells_global : 0.0;
342 const PetscReal layer_spacing_norm_j = (JM_cells_global > 0) ? 1.0 / (PetscReal)JM_cells_global : 0.0;
343 const PetscReal layer_spacing_norm_k = (KM_cells_global > 0) ? 1.0 / (PetscReal)KM_cells_global : 0.0;
346 const PetscReal min_layer_spacing = PetscMin(layer_spacing_norm_i, PetscMin(layer_spacing_norm_j, layer_spacing_norm_k));
347 const PetscReal epsilon = 0.5 * min_layer_spacing;
349 PetscReal variable_coord;
350 if (points_per_line <= 1) {
351 variable_coord = 0.5;
353 variable_coord = ((PetscReal)point_index_on_line + 0.5)/ (PetscReal)(points_per_line);
355 variable_coord = PetscMin(1.0 - epsilon, PetscMax(epsilon, variable_coord));
360 global_logic_i = 0.5 * layer_spacing_norm_i;
361 if (edge_group == 0) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_k = variable_coord; }
362 else if (edge_group == 1) { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_k = variable_coord; }
363 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_j = variable_coord; }
364 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_j = variable_coord; }
367 global_logic_i = 1.0 - (0.5 * layer_spacing_norm_i);
368 if (edge_group == 0) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_k = variable_coord; }
369 else if (edge_group == 1) { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_k = variable_coord; }
370 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_j = variable_coord; }
371 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_j = variable_coord; }
374 global_logic_j = 0.5 * layer_spacing_norm_j;
375 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_k = variable_coord; }
376 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_k = variable_coord; }
377 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_i = variable_coord; }
378 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_i = variable_coord; }
381 global_logic_j = 1.0 - (0.5 * layer_spacing_norm_j);
382 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_k = variable_coord; }
383 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_k = variable_coord; }
384 else if (edge_group == 2) { global_logic_k = (PetscReal)layer_index * layer_spacing_norm_k + epsilon; global_logic_i = variable_coord; }
385 else { global_logic_k = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_k) - epsilon; global_logic_i = variable_coord; }
388 global_logic_k = 0.5 * layer_spacing_norm_k;
389 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_j = variable_coord; }
390 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_j = variable_coord; }
391 else if (edge_group == 2) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_i = variable_coord; }
392 else { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_i = variable_coord; }
395 global_logic_k = 1.0 - (0.5 * layer_spacing_norm_k);
396 if (edge_group == 0) { global_logic_i = (PetscReal)layer_index * layer_spacing_norm_i + epsilon; global_logic_j = variable_coord; }
397 else if (edge_group == 1) { global_logic_i = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_i) - epsilon; global_logic_j = variable_coord; }
398 else if (edge_group == 2) { global_logic_j = (PetscReal)layer_index * layer_spacing_norm_j + epsilon; global_logic_i = variable_coord; }
399 else { global_logic_j = 1.0 - ((PetscReal)layer_index * layer_spacing_norm_j) - epsilon; global_logic_i = variable_coord; }
404 "[Rank %d] Particle %lld assigned to line %d (edge group %d, layer %d) with variable_coord=%.4f.\n"
405 " -> Global logical coords: (i,j,k) = (%.6f, %.6f, %.6f)\n",
406 rank_for_logging, (
long long)particle_global_id, line_index, edge_group, layer_index, variable_coord,
407 global_logic_i, global_logic_j, global_logic_k);
410 PetscReal global_cell_coord_i = global_logic_i * IM_cells_global;
411 PetscInt I_g = (PetscInt)global_cell_coord_i;
412 *xi_metric_logic_out = global_cell_coord_i - I_g;
414 PetscReal global_cell_coord_j = global_logic_j * JM_cells_global;
415 PetscInt J_g = (PetscInt)global_cell_coord_j;
416 *eta_metric_logic_out = global_cell_coord_j - J_g;
418 PetscReal global_cell_coord_k = global_logic_k * KM_cells_global;
419 PetscInt K_g = (PetscInt)global_cell_coord_k;
420 *zta_metric_logic_out = global_cell_coord_k - K_g;
423 if ((I_g >= info->xs && I_g < info->xs + info->xm) &&
424 (J_g >= info->ys && J_g < info->ys + info->ym) &&
425 (K_g >= info->zs && K_g < info->zs + info->zm))
428 *ci_metric_lnode_out = (I_g - info->xs) + xs_gnode_rank;
429 *cj_metric_lnode_out = (J_g - info->ys) + ys_gnode_rank;
430 *ck_metric_lnode_out = (K_g - info->zs) + zs_gnode_rank;
431 *placement_successful_out = PETSC_TRUE;
435 "[Rank %d] Particle %lld placement %s.\n",
436 rank_for_logging, (
long long)particle_global_id,
437 (*placement_successful_out ?
"SUCCESSFUL" :
"NOT ON THIS RANK"));
439 if(*placement_successful_out){
440 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",
441 *ci_metric_lnode_out, *cj_metric_lnode_out, *ck_metric_lnode_out,
442 *xi_metric_logic_out, *eta_metric_logic_out, *zta_metric_logic_out);
445 PetscFunctionReturn(0);
468 UserCtx *user,
const DMDALocalInfo *info,
469 PetscInt xs_gnode_rank, PetscInt ys_gnode_rank, PetscInt zs_gnode_rank,
470 PetscInt IM_nodes_global, PetscInt JM_nodes_global, PetscInt KM_nodes_global,
471 PetscRandom *rand_logic_i_ptr, PetscRandom *rand_logic_j_ptr, PetscRandom *rand_logic_k_ptr,
472 PetscInt *ci_metric_lnode_out, PetscInt *cj_metric_lnode_out, PetscInt *ck_metric_lnode_out,
473 PetscReal *xi_metric_logic_out, PetscReal *eta_metric_logic_out, PetscReal *zta_metric_logic_out)
475 PetscErrorCode ierr = 0;
476 PetscReal r_val_i_sel, r_val_j_sel, r_val_k_sel;
477 PetscInt local_cell_idx_on_face_dim1 = 0;
478 PetscInt local_cell_idx_on_face_dim2 = 0;
479 PetscMPIInt rank_for_logging;
481 PetscFunctionBeginUser;
485 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank_for_logging); CHKERRQ(ierr);
488 PetscInt owned_start_cell_i, num_owned_cells_on_rank_i;
489 PetscInt owned_start_cell_j, num_owned_cells_on_rank_j;
490 PetscInt owned_start_cell_k, num_owned_cells_on_rank_k;
492 ierr =
GetOwnedCellRange(info, 0, &owned_start_cell_i, &num_owned_cells_on_rank_i); CHKERRQ(ierr);
493 ierr =
GetOwnedCellRange(info, 1, &owned_start_cell_j, &num_owned_cells_on_rank_j); CHKERRQ(ierr);
494 ierr =
GetOwnedCellRange(info, 2, &owned_start_cell_k, &num_owned_cells_on_rank_k); CHKERRQ(ierr);
497 *ci_metric_lnode_out = xs_gnode_rank; *cj_metric_lnode_out = ys_gnode_rank; *ck_metric_lnode_out = zs_gnode_rank;
499 *xi_metric_logic_out = 0.5; *eta_metric_logic_out = 0.5; *zta_metric_logic_out = 0.5;
502 PetscInt last_global_cell_idx_i = (IM_nodes_global > 1) ? (IM_nodes_global - 2) : -1;
503 PetscInt last_global_cell_idx_j = (JM_nodes_global > 1) ? (JM_nodes_global - 2) : -1;
504 PetscInt last_global_cell_idx_k = (KM_nodes_global > 1) ? (KM_nodes_global - 2) : -1;
507 " Owned cells (i,j,k): (%d,%d,%d)\n"
508 " Global nodes (I,J,K): (%d,%d,%d)\n"
509 " info->xs,ys,zs (first owned node GLOBAL): (%d,%d,%d)\n"
510 " info->xm,ym,zm (num owned nodes GLOBAL): (%d,%d,%d)\n"
511 " xs_gnode_rank,ys_gnode_rank,zs_gnode_rank (DMDAGetCorners): (%d,%d,%d)\n"
512 " owned_start_cell (i,j,k) GLOBAL: (%d,%d,%d)\n"
513 " last_global_cell_idx (i,j,k): (%d,%d,%d)\n",
515 num_owned_cells_on_rank_i,num_owned_cells_on_rank_j,num_owned_cells_on_rank_k,
516 IM_nodes_global,JM_nodes_global,KM_nodes_global,
517 info->xs, info->ys, info->zs,
518 info->xm, info->ym, info->zm,
519 xs_gnode_rank,ys_gnode_rank,zs_gnode_rank,
520 owned_start_cell_i, owned_start_cell_j, owned_start_cell_k,
521 last_global_cell_idx_i, last_global_cell_idx_j, last_global_cell_idx_k);
528 *ci_metric_lnode_out = xs_gnode_rank;
529 *xi_metric_logic_out = 1.0e-6;
533 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
534 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
535 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_j - 1);
536 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim1;
538 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
539 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
540 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
541 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
543 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
544 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
550 *ci_metric_lnode_out = xs_gnode_rank + (last_global_cell_idx_i - info->xs);
551 *xi_metric_logic_out = 1.0 - 1.0e-6;
553 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
554 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
555 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_j - 1);
556 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim1;
558 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
559 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
560 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
561 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
563 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
564 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
568 *cj_metric_lnode_out = ys_gnode_rank;
569 *eta_metric_logic_out = 1.0e-6;
570 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
571 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
572 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
573 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
574 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
575 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
576 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
577 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
578 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
579 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
582 *cj_metric_lnode_out = ys_gnode_rank + (last_global_cell_idx_j - info->ys);
583 *eta_metric_logic_out = 1.0 - 1.0e-6;
584 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
585 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
586 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
587 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
588 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, &r_val_k_sel); CHKERRQ(ierr);
589 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_k_sel * num_owned_cells_on_rank_k);
590 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_k - 1);
591 *ck_metric_lnode_out = zs_gnode_rank + local_cell_idx_on_face_dim2;
592 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
593 ierr = PetscRandomGetValueReal(*rand_logic_k_ptr, zta_metric_logic_out); CHKERRQ(ierr);
596 *ck_metric_lnode_out = zs_gnode_rank;
597 *zta_metric_logic_out = 1.0e-6;
599 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
600 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
601 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
602 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
604 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
605 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
606 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_j - 1);
607 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim2;
609 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
610 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
613 *ck_metric_lnode_out = zs_gnode_rank + (last_global_cell_idx_k - info->zs);
614 *zta_metric_logic_out = 1.0 - 1.0e-6;
615 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, &r_val_i_sel); CHKERRQ(ierr);
616 local_cell_idx_on_face_dim1 = (PetscInt)(r_val_i_sel * num_owned_cells_on_rank_i);
617 local_cell_idx_on_face_dim1 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim1), num_owned_cells_on_rank_i - 1);
618 *ci_metric_lnode_out = xs_gnode_rank + local_cell_idx_on_face_dim1;
619 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, &r_val_j_sel); CHKERRQ(ierr);
620 local_cell_idx_on_face_dim2 = (PetscInt)(r_val_j_sel * num_owned_cells_on_rank_j);
621 local_cell_idx_on_face_dim2 = PetscMin(PetscMax(0, local_cell_idx_on_face_dim2), num_owned_cells_on_rank_j - 1);
622 *cj_metric_lnode_out = ys_gnode_rank + local_cell_idx_on_face_dim2;
623 ierr = PetscRandomGetValueReal(*rand_logic_i_ptr, xi_metric_logic_out); CHKERRQ(ierr);
624 ierr = PetscRandomGetValueReal(*rand_logic_j_ptr, eta_metric_logic_out); CHKERRQ(ierr);
627 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
"GetRandomCellAndLogicOnInletFace: Invalid user->identifiedInletBCFace %d. \n", user->
identifiedInletBCFace);
630 PetscReal eps = 1.0e-7;
632 *eta_metric_logic_out = PetscMin(PetscMax(0.0, *eta_metric_logic_out), 1.0 - eps);
633 *zta_metric_logic_out = PetscMin(PetscMax(0.0, *zta_metric_logic_out), 1.0 - eps);
635 *xi_metric_logic_out = PetscMin(PetscMax(0.0, *xi_metric_logic_out), 1.0 - eps);
636 *zta_metric_logic_out = PetscMin(PetscMax(0.0, *zta_metric_logic_out), 1.0 - eps);
638 *xi_metric_logic_out = PetscMin(PetscMax(0.0, *xi_metric_logic_out), 1.0 - eps);
639 *eta_metric_logic_out = PetscMin(PetscMax(0.0, *eta_metric_logic_out), 1.0 - eps);
643 rank_for_logging, *ci_metric_lnode_out, *cj_metric_lnode_out, *ck_metric_lnode_out,
644 *xi_metric_logic_out, *eta_metric_logic_out, *zta_metric_logic_out);
648 PetscFunctionReturn(0);
1209 PetscErrorCode ierr;
1210 PetscFunctionBeginUser;
1219 PetscReal local_inflow_pre = 0.0;
1220 PetscReal local_inflow_post = 0.0;
1221 PetscReal global_inflow_pre = 0.0;
1222 PetscReal global_inflow_post = 0.0;
1223 PetscInt num_handlers[3] = {0,0,0};
1228 for (
int i = 0; i < 6; i++) {
1231 if (!handler->
PreStep)
continue;
1237 .global_inflow_sum = NULL,
1238 .global_outflow_sum = NULL,
1244 ierr = handler->
PreStep(handler, &ctx, &local_inflow_pre, NULL); CHKERRQ(ierr);
1248 if (local_inflow_pre != 0.0) {
1249 ierr = MPI_Allreduce(&local_inflow_pre, &global_inflow_pre, 1, MPIU_REAL,
1250 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1255 for (
int i = 0; i < 6; i++) {
1258 if(!handler->
Apply)
continue;
1265 .global_inflow_sum = NULL,
1266 .global_outflow_sum = NULL,
1272 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1276 for (
int i = 0; i < 6; i++) {
1286 .global_inflow_sum = NULL,
1287 .global_outflow_sum = NULL,
1293 ierr = handler->
PostStep(handler, &ctx, &local_inflow_post, NULL); CHKERRQ(ierr);
1297 ierr = MPI_Allreduce(&local_inflow_post, &global_inflow_post, 1, MPIU_REAL,
1298 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1304 " (INLETS): %d Prestep(s), %d Application(s), %d Poststep(s), FluxInSum = %.6e\n",
1305 num_handlers[0],num_handlers[1],num_handlers[2], global_inflow_post);
1311 PetscReal local_farfield_in_pre = 0.0;
1312 PetscReal local_farfield_out_pre = 0.0;
1313 PetscReal local_farfield_in_post = 0.0;
1314 PetscReal local_farfield_out_post = 0.0;
1315 PetscReal global_farfield_in_pre = 0.0;
1316 PetscReal global_farfield_out_pre = 0.0;
1317 PetscReal global_farfield_in_post = 0.0;
1318 PetscReal global_farfield_out_post = 0.0;
1319 memset(num_handlers,0,
sizeof(num_handlers));
1324 for (
int i = 0; i < 6; i++) {
1327 if (!handler->
PreStep)
continue;
1334 .global_outflow_sum = NULL,
1340 ierr = handler->
PreStep(handler, &ctx, &local_farfield_in_pre, &local_farfield_out_pre);
1345 if (local_farfield_in_pre != 0.0 || local_farfield_out_pre != 0.0) {
1346 ierr = MPI_Allreduce(&local_farfield_in_pre, &global_farfield_in_pre, 1, MPIU_REAL,
1347 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1348 ierr = MPI_Allreduce(&local_farfield_out_pre, &global_farfield_out_pre, 1, MPIU_REAL,
1349 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1352 " Farfield pre-analysis: In=%.6e, Out=%.6e\n",
1353 global_farfield_in_pre, global_farfield_out_pre);
1357 for (
int i = 0; i < 6; i++) {
1360 if(!handler->
Apply)
continue;
1368 .global_outflow_sum = NULL,
1374 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1378 for (
int i = 0; i < 6; i++) {
1389 .global_outflow_sum = NULL,
1395 ierr = handler->
PostStep(handler, &ctx, &local_farfield_in_post, &local_farfield_out_post);
1400 if (num_handlers > 0) {
1401 ierr = MPI_Allreduce(&local_farfield_in_post, &global_farfield_in_post, 1, MPIU_REAL,
1402 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1403 ierr = MPI_Allreduce(&local_farfield_out_post, &global_farfield_out_post, 1, MPIU_REAL,
1404 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1411 " (FARFIELD): %d Prestep(s), %d Application(s), %d Poststep(s) , InFlux=%.6e, OutFlux=%.6e\n",
1412 num_handlers[0],num_handlers[1],num_handlers[2], global_farfield_in_post, global_farfield_out_post);
1424 memset(num_handlers,0,
sizeof(num_handlers));
1429 for (
int i = 0; i < 6; i++) {
1432 if (!handler->
PreStep)
continue;
1439 .global_outflow_sum = NULL,
1445 ierr = handler->
PreStep(handler, &ctx, NULL, NULL); CHKERRQ(ierr);
1451 for (
int i = 0; i < 6; i++) {
1454 if(!handler->
Apply)
continue;
1462 .global_outflow_sum = NULL,
1468 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1472 for (
int i = 0; i < 6; i++) {
1483 .global_outflow_sum = NULL,
1489 ierr = handler->
PostStep(handler, &ctx, NULL, NULL); CHKERRQ(ierr);
1495 num_handlers[0],num_handlers[1],num_handlers[2]);
1502 PetscReal local_outflow_pre = 0.0;
1503 PetscReal local_outflow_post = 0.0;
1504 PetscReal global_outflow_pre = 0.0;
1505 PetscReal global_outflow_post = 0.0;
1506 memset(num_handlers,0,
sizeof(num_handlers));
1511 for (
int i = 0; i < 6; i++) {
1514 if (!handler->
PreStep)
continue;
1521 .global_outflow_sum = NULL,
1527 ierr = handler->
PreStep(handler, &ctx, NULL, &local_outflow_pre); CHKERRQ(ierr);
1531 ierr = MPI_Allreduce(&local_outflow_pre, &global_outflow_pre, 1, MPIU_REAL,
1532 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1538 " Uncorrected outflow: %.6e, Total inflow: %.6e (Inlet: %.6e + Farfield: %.6e)\n",
1543 for (
int i = 0; i < 6; i++) {
1546 if(!handler->
Apply)
continue;
1554 .global_outflow_sum = &global_outflow_pre,
1560 ierr = handler->
Apply(handler, &ctx); CHKERRQ(ierr);
1564 for (
int i = 0; i < 6; i++) {
1575 .global_outflow_sum = &global_outflow_pre,
1581 ierr = handler->
PostStep(handler, &ctx, NULL, &local_outflow_post); CHKERRQ(ierr);
1585 ierr = MPI_Allreduce(&local_outflow_post, &global_outflow_post, 1, MPIU_REAL,
1586 MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
1593 PetscReal flux_error = PetscAbsReal(total_outflow - total_inflow);
1594 PetscReal relative_error = (total_inflow > 1e-16) ?
1595 flux_error / total_inflow : flux_error;
1598 " (OUTLETS): %d Prestep(s), %d Application(s), %d Poststep(s), FluxOutSum = %.6e\n",
1599 num_handlers[0],num_handlers[1],num_handlers[2], global_outflow_post);
1601 " Conservation: Total In=%.6e, Total Out=%.6e, Error=%.3e (%.2e)%%)\n",
1602 total_inflow, total_outflow, flux_error, relative_error * 100.0);
1604 if (relative_error > 1e-6) {
1606 " WARNING: Large mass conservation error (%.2e%%)!\n",
1607 relative_error * 100.0);
1614 PetscFunctionReturn(0);
2388 PetscErrorCode ierr;
2389 DM da = user->
da, fda = user->
fda;
2390 DMDALocalInfo info = user->
info;
2391 PetscInt xs = info.xs, xe = info.xs + info.xm;
2392 PetscInt ys = info.ys, ye = info.ys + info.ym;
2393 PetscInt zs = info.zs, ze = info.zs + info.zm;
2394 PetscInt mx = info.mx, my = info.my, mz = info.mz;
2399 PetscFunctionBeginUser;
2401 ierr = DMDAVecGetArray(fda, user->
Ucat, &ucat); CHKERRQ(ierr);
2402 ierr = DMDAVecGetArray(da, user->
P, &p); CHKERRQ(ierr);
2410 for (PetscInt j = ys; j < ye; j++) {
2411 p[zs][j][xs] = 0.5 * (p[zs+1][j][xs] + p[zs][j][xs+1]);
2412 ucat[zs][j][xs].
x = 0.5 * (ucat[zs+1][j][xs].
x + ucat[zs][j][xs+1].
x);
2413 ucat[zs][j][xs].
y = 0.5 * (ucat[zs+1][j][xs].
y + ucat[zs][j][xs+1].
y);
2414 ucat[zs][j][xs].
z = 0.5 * (ucat[zs+1][j][xs].
z + ucat[zs][j][xs+1].
z);
2418 for (PetscInt j = ys; j < ye; j++) {
2419 p[zs][j][mx-1] = 0.5 * (p[zs+1][j][mx-1] + p[zs][j][mx-2]);
2420 ucat[zs][j][mx-1].
x = 0.5 * (ucat[zs+1][j][mx-1].
x + ucat[zs][j][mx-2].
x);
2421 ucat[zs][j][mx-1].
y = 0.5 * (ucat[zs+1][j][mx-1].
y + ucat[zs][j][mx-2].
y);
2422 ucat[zs][j][mx-1].
z = 0.5 * (ucat[zs+1][j][mx-1].
z + ucat[zs][j][mx-2].
z);
2426 for (PetscInt i = xs; i < xe; i++) {
2427 p[zs][ys][i] = 0.5 * (p[zs+1][ys][i] + p[zs][ys+1][i]);
2428 ucat[zs][ys][i].
x = 0.5 * (ucat[zs+1][ys][i].
x + ucat[zs][ys+1][i].
x);
2429 ucat[zs][ys][i].
y = 0.5 * (ucat[zs+1][ys][i].
y + ucat[zs][ys+1][i].
y);
2430 ucat[zs][ys][i].
z = 0.5 * (ucat[zs+1][ys][i].
z + ucat[zs][ys+1][i].
z);
2434 for (PetscInt i = xs; i < xe; i++) {
2435 p[zs][my-1][i] = 0.5 * (p[zs+1][my-1][i] + p[zs][my-2][i]);
2436 ucat[zs][my-1][i].
x = 0.5 * (ucat[zs+1][my-1][i].
x + ucat[zs][my-2][i].
x);
2437 ucat[zs][my-1][i].
y = 0.5 * (ucat[zs+1][my-1][i].
y + ucat[zs][my-2][i].
y);
2438 ucat[zs][my-1][i].
z = 0.5 * (ucat[zs+1][my-1][i].
z + ucat[zs][my-2][i].
z);
2446 for (PetscInt j = ys; j < ye; j++) {
2447 p[mz-1][j][xs] = 0.5 * (p[mz-2][j][xs] + p[mz-1][j][xs+1]);
2448 ucat[mz-1][j][xs].
x = 0.5 * (ucat[mz-2][j][xs].
x + ucat[mz-1][j][xs+1].
x);
2449 ucat[mz-1][j][xs].
y = 0.5 * (ucat[mz-2][j][xs].
y + ucat[mz-1][j][xs+1].
y);
2450 ucat[mz-1][j][xs].
z = 0.5 * (ucat[mz-2][j][xs].
z + ucat[mz-1][j][xs+1].
z);
2454 for (PetscInt j = ys; j < ye; j++) {
2455 p[mz-1][j][mx-1] = 0.5 * (p[mz-2][j][mx-1] + p[mz-1][j][mx-2]);
2456 ucat[mz-1][j][mx-1].
x = 0.5 * (ucat[mz-2][j][mx-1].
x + ucat[mz-1][j][mx-2].
x);
2457 ucat[mz-1][j][mx-1].
y = 0.5 * (ucat[mz-2][j][mx-1].
y + ucat[mz-1][j][mx-2].
y);
2458 ucat[mz-1][j][mx-1].
z = 0.5 * (ucat[mz-2][j][mx-1].
z + ucat[mz-1][j][mx-2].
z);
2462 for (PetscInt i = xs; i < xe; i++) {
2463 p[mz-1][ys][i] = 0.5 * (p[mz-2][ys][i] + p[mz-1][ys+1][i]);
2464 ucat[mz-1][ys][i].
x = 0.5 * (ucat[mz-2][ys][i].
x + ucat[mz-1][ys+1][i].
x);
2465 ucat[mz-1][ys][i].
y = 0.5 * (ucat[mz-2][ys][i].
y + ucat[mz-1][ys+1][i].
y);
2466 ucat[mz-1][ys][i].
z = 0.5 * (ucat[mz-2][ys][i].
z + ucat[mz-1][ys+1][i].
z);
2470 for (PetscInt i = xs; i < xe; i++) {
2471 p[mz-1][my-1][i] = 0.5 * (p[mz-2][my-1][i] + p[mz-1][my-2][i]);
2472 ucat[mz-1][my-1][i].
x = 0.5 * (ucat[mz-2][my-1][i].
x + ucat[mz-1][my-2][i].
x);
2473 ucat[mz-1][my-1][i].
y = 0.5 * (ucat[mz-2][my-1][i].
y + ucat[mz-1][my-2][i].
y);
2474 ucat[mz-1][my-1][i].
z = 0.5 * (ucat[mz-2][my-1][i].
z + ucat[mz-1][my-2][i].
z);
2482 for (PetscInt k = zs; k < ze; k++) {
2483 p[k][ys][xs] = 0.5 * (p[k][ys+1][xs] + p[k][ys][xs+1]);
2484 ucat[k][ys][xs].
x = 0.5 * (ucat[k][ys+1][xs].
x + ucat[k][ys][xs+1].
x);
2485 ucat[k][ys][xs].
y = 0.5 * (ucat[k][ys+1][xs].
y + ucat[k][ys][xs+1].
y);
2486 ucat[k][ys][xs].
z = 0.5 * (ucat[k][ys+1][xs].
z + ucat[k][ys][xs+1].
z);
2490 for (PetscInt k = zs; k < ze; k++) {
2491 p[k][ys][mx-1] = 0.5 * (p[k][ys+1][mx-1] + p[k][ys][mx-2]);
2492 ucat[k][ys][mx-1].
x = 0.5 * (ucat[k][ys+1][mx-1].
x + ucat[k][ys][mx-2].
x);
2493 ucat[k][ys][mx-1].
y = 0.5 * (ucat[k][ys+1][mx-1].
y + ucat[k][ys][mx-2].
y);
2494 ucat[k][ys][mx-1].
z = 0.5 * (ucat[k][ys+1][mx-1].
z + ucat[k][ys][mx-2].
z);
2501 for (PetscInt k = zs; k < ze; k++) {
2502 p[k][my-1][xs] = 0.5 * (p[k][my-2][xs] + p[k][my-1][xs+1]);
2503 ucat[k][my-1][xs].
x = 0.5 * (ucat[k][my-2][xs].
x + ucat[k][my-1][xs+1].
x);
2504 ucat[k][my-1][xs].
y = 0.5 * (ucat[k][my-2][xs].
y + ucat[k][my-1][xs+1].
y);
2505 ucat[k][my-1][xs].
z = 0.5 * (ucat[k][my-2][xs].
z + ucat[k][my-1][xs+1].
z);
2509 for (PetscInt k = zs; k < ze; k++) {
2510 p[k][my-1][mx-1] = 0.5 * (p[k][my-2][mx-1] + p[k][my-1][mx-2]);
2511 ucat[k][my-1][mx-1].
x = 0.5 * (ucat[k][my-2][mx-1].
x + ucat[k][my-1][mx-2].
x);
2512 ucat[k][my-1][mx-1].
y = 0.5 * (ucat[k][my-2][mx-1].
y + ucat[k][my-1][mx-2].
y);
2513 ucat[k][my-1][mx-1].
z = 0.5 * (ucat[k][my-2][mx-1].
z + ucat[k][my-1][mx-2].
z);
2518 ierr = DMDAVecRestoreArray(fda, user->
Ucat, &ucat); CHKERRQ(ierr);
2519 ierr = DMDAVecRestoreArray(da, user->
P, &p); CHKERRQ(ierr);
2521 PetscFunctionReturn(0);
2626 PetscErrorCode ierr;
2628 DMDALocalInfo *info = &user->
info;
2630 PetscFunctionBeginUser;
2636 PetscFunctionReturn(0);
2644 Cmpnts ***velocity_cartesian;
2645 Cmpnts ***velocity_contravariant;
2646 Cmpnts ***velocity_boundary;
2647 Cmpnts ***csi, ***eta, ***zet;
2648 PetscReal ***node_vertex_flag;
2649 PetscReal ***cell_jacobian;
2650 PetscReal ***friction_velocity;
2652 ierr = DMDAVecGetArray(user->
fda, user->
Ucat, &velocity_cartesian); CHKERRQ(ierr);
2653 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &velocity_contravariant); CHKERRQ(ierr);
2654 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &velocity_boundary); CHKERRQ(ierr);
2655 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2656 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2657 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2658 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&node_vertex_flag); CHKERRQ(ierr);
2659 ierr = DMDAVecGetArrayRead(user->
da, user->
lAj, (
const PetscReal***)&cell_jacobian); CHKERRQ(ierr);
2665 PetscInt grid_start_i = info->xs, grid_end_i = info->xs + info->xm;
2666 PetscInt grid_start_j = info->ys, grid_end_j = info->ys + info->ym;
2667 PetscInt grid_start_k = info->zs, grid_end_k = info->zs + info->zm;
2668 PetscInt grid_size_i = info->mx, grid_size_j = info->my, grid_size_k = info->mz;
2671 PetscInt loop_start_i = grid_start_i, loop_end_i = grid_end_i;
2672 PetscInt loop_start_j = grid_start_j, loop_end_j = grid_end_j;
2673 PetscInt loop_start_k = grid_start_k, loop_end_k = grid_end_k;
2675 if (grid_start_i == 0) loop_start_i = grid_start_i + 1;
2676 if (grid_end_i == grid_size_i) loop_end_i = grid_end_i - 1;
2677 if (grid_start_j == 0) loop_start_j = grid_start_j + 1;
2678 if (grid_end_j == grid_size_j) loop_end_j = grid_end_j - 1;
2679 if (grid_start_k == 0) loop_start_k = grid_start_k + 1;
2680 if (grid_end_k == grid_size_k) loop_end_k = grid_end_k - 1;
2683 const PetscReal wall_roughness_height = 1.e-16;
2688 for (
int face_index = 0; face_index < 6; face_index++) {
2698 PetscBool rank_owns_this_face;
2700 current_face_id, &rank_owns_this_face); CHKERRQ(ierr);
2702 if (!rank_owns_this_face) {
2712 switch(current_face_id) {
2718 if (grid_start_i == 0) {
2719 const PetscInt ghost_cell_index = grid_start_i;
2720 const PetscInt first_interior_cell = grid_start_i + 1;
2721 const PetscInt second_interior_cell = grid_start_i + 2;
2723 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2724 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
2727 if (node_vertex_flag[k][j][first_interior_cell] < 0.1) {
2730 PetscReal face_area = sqrt(
2731 csi[k][j][ghost_cell_index].x * csi[k][j][ghost_cell_index].x +
2732 csi[k][j][ghost_cell_index].y * csi[k][j][ghost_cell_index].y +
2733 csi[k][j][ghost_cell_index].z * csi[k][j][ghost_cell_index].z
2739 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][j][first_interior_cell] / face_area;
2740 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2741 0.5 / cell_jacobian[k][j][second_interior_cell] / face_area;
2744 PetscReal wall_normal[3];
2745 wall_normal[0] = csi[k][j][ghost_cell_index].
x / face_area;
2746 wall_normal[1] = csi[k][j][ghost_cell_index].
y / face_area;
2747 wall_normal[2] = csi[k][j][ghost_cell_index].
z / face_area;
2751 Cmpnts reference_velocity;
2753 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2754 reference_velocity = velocity_cartesian[k][j][second_interior_cell];
2757 noslip(user, distance_to_second_cell, distance_to_first_cell,
2758 wall_velocity, reference_velocity,
2759 &velocity_cartesian[k][j][first_interior_cell],
2760 wall_normal[0], wall_normal[1], wall_normal[2]);
2764 distance_to_second_cell, distance_to_first_cell,
2765 wall_velocity, reference_velocity,
2766 &velocity_cartesian[k][j][first_interior_cell],
2767 &friction_velocity[k][j][first_interior_cell],
2768 wall_normal[0], wall_normal[1], wall_normal[2]);
2771 velocity_boundary[k][j][ghost_cell_index].
x = 0.0;
2772 velocity_boundary[k][j][ghost_cell_index].
y = 0.0;
2773 velocity_boundary[k][j][ghost_cell_index].
z = 0.0;
2774 velocity_contravariant[k][j][ghost_cell_index].
x = 0.0;
2785 if (grid_end_i == grid_size_i) {
2786 const PetscInt ghost_cell_index = grid_end_i - 1;
2787 const PetscInt first_interior_cell = grid_end_i - 2;
2788 const PetscInt second_interior_cell = grid_end_i - 3;
2790 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2791 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
2793 if (node_vertex_flag[k][j][first_interior_cell] < 0.1) {
2795 PetscReal face_area = sqrt(
2796 csi[k][j][first_interior_cell].x * csi[k][j][first_interior_cell].x +
2797 csi[k][j][first_interior_cell].y * csi[k][j][first_interior_cell].y +
2798 csi[k][j][first_interior_cell].z * csi[k][j][first_interior_cell].z
2801 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][j][first_interior_cell] / face_area;
2802 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2803 0.5 / cell_jacobian[k][j][second_interior_cell] / face_area;
2806 PetscReal wall_normal[3];
2807 wall_normal[0] = -csi[k][j][first_interior_cell].
x / face_area;
2808 wall_normal[1] = -csi[k][j][first_interior_cell].
y / face_area;
2809 wall_normal[2] = -csi[k][j][first_interior_cell].
z / face_area;
2811 Cmpnts wall_velocity, reference_velocity;
2812 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2813 reference_velocity = velocity_cartesian[k][j][second_interior_cell];
2815 noslip(user, distance_to_second_cell, distance_to_first_cell,
2816 wall_velocity, reference_velocity,
2817 &velocity_cartesian[k][j][first_interior_cell],
2818 wall_normal[0], wall_normal[1], wall_normal[2]);
2821 distance_to_second_cell, distance_to_first_cell,
2822 wall_velocity, reference_velocity,
2823 &velocity_cartesian[k][j][first_interior_cell],
2824 &friction_velocity[k][j][first_interior_cell],
2825 wall_normal[0], wall_normal[1], wall_normal[2]);
2827 velocity_boundary[k][j][ghost_cell_index].
x = 0.0;
2828 velocity_boundary[k][j][ghost_cell_index].
y = 0.0;
2829 velocity_boundary[k][j][ghost_cell_index].
z = 0.0;
2830 velocity_contravariant[k][j][first_interior_cell].
x = 0.0;
2841 if (grid_start_j == 0) {
2842 const PetscInt ghost_cell_index = grid_start_j;
2843 const PetscInt first_interior_cell = grid_start_j + 1;
2844 const PetscInt second_interior_cell = grid_start_j + 2;
2846 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2847 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
2849 if (node_vertex_flag[k][first_interior_cell][i] < 0.1) {
2851 PetscReal face_area = sqrt(
2852 eta[k][ghost_cell_index][i].x * eta[k][ghost_cell_index][i].x +
2853 eta[k][ghost_cell_index][i].y * eta[k][ghost_cell_index][i].y +
2854 eta[k][ghost_cell_index][i].z * eta[k][ghost_cell_index][i].z
2857 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][first_interior_cell][i] / face_area;
2858 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2859 0.5 / cell_jacobian[k][second_interior_cell][i] / face_area;
2861 PetscReal wall_normal[3];
2862 wall_normal[0] = eta[k][ghost_cell_index][i].
x / face_area;
2863 wall_normal[1] = eta[k][ghost_cell_index][i].
y / face_area;
2864 wall_normal[2] = eta[k][ghost_cell_index][i].
z / face_area;
2866 Cmpnts wall_velocity, reference_velocity;
2867 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2868 reference_velocity = velocity_cartesian[k][second_interior_cell][i];
2870 noslip(user, distance_to_second_cell, distance_to_first_cell,
2871 wall_velocity, reference_velocity,
2872 &velocity_cartesian[k][first_interior_cell][i],
2873 wall_normal[0], wall_normal[1], wall_normal[2]);
2876 distance_to_second_cell, distance_to_first_cell,
2877 wall_velocity, reference_velocity,
2878 &velocity_cartesian[k][first_interior_cell][i],
2879 &friction_velocity[k][first_interior_cell][i],
2880 wall_normal[0], wall_normal[1], wall_normal[2]);
2882 velocity_boundary[k][ghost_cell_index][i].
x = 0.0;
2883 velocity_boundary[k][ghost_cell_index][i].
y = 0.0;
2884 velocity_boundary[k][ghost_cell_index][i].
z = 0.0;
2885 velocity_contravariant[k][ghost_cell_index][i].
y = 0.0;
2896 if (grid_end_j == grid_size_j) {
2897 const PetscInt ghost_cell_index = grid_end_j - 1;
2898 const PetscInt first_interior_cell = grid_end_j - 2;
2899 const PetscInt second_interior_cell = grid_end_j - 3;
2901 for (PetscInt k = loop_start_k; k < loop_end_k; k++) {
2902 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
2904 if (node_vertex_flag[k][first_interior_cell][i] < 0.1) {
2906 PetscReal face_area = sqrt(
2907 eta[k][first_interior_cell][i].x * eta[k][first_interior_cell][i].x +
2908 eta[k][first_interior_cell][i].y * eta[k][first_interior_cell][i].y +
2909 eta[k][first_interior_cell][i].z * eta[k][first_interior_cell][i].z
2912 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[k][first_interior_cell][i] / face_area;
2913 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2914 0.5 / cell_jacobian[k][second_interior_cell][i] / face_area;
2916 PetscReal wall_normal[3];
2917 wall_normal[0] = -eta[k][first_interior_cell][i].
x / face_area;
2918 wall_normal[1] = -eta[k][first_interior_cell][i].
y / face_area;
2919 wall_normal[2] = -eta[k][first_interior_cell][i].
z / face_area;
2921 Cmpnts wall_velocity, reference_velocity;
2922 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2923 reference_velocity = velocity_cartesian[k][second_interior_cell][i];
2925 noslip(user, distance_to_second_cell, distance_to_first_cell,
2926 wall_velocity, reference_velocity,
2927 &velocity_cartesian[k][first_interior_cell][i],
2928 wall_normal[0], wall_normal[1], wall_normal[2]);
2931 distance_to_second_cell, distance_to_first_cell,
2932 wall_velocity, reference_velocity,
2933 &velocity_cartesian[k][first_interior_cell][i],
2934 &friction_velocity[k][first_interior_cell][i],
2935 wall_normal[0], wall_normal[1], wall_normal[2]);
2937 velocity_boundary[k][ghost_cell_index][i].
x = 0.0;
2938 velocity_boundary[k][ghost_cell_index][i].
y = 0.0;
2939 velocity_boundary[k][ghost_cell_index][i].
z = 0.0;
2940 velocity_contravariant[k][first_interior_cell][i].
y = 0.0;
2951 if (grid_start_k == 0) {
2952 const PetscInt ghost_cell_index = grid_start_k;
2953 const PetscInt first_interior_cell = grid_start_k + 1;
2954 const PetscInt second_interior_cell = grid_start_k + 2;
2956 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
2957 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
2959 if (node_vertex_flag[first_interior_cell][j][i] < 0.1) {
2961 PetscReal face_area = sqrt(
2962 zet[ghost_cell_index][j][i].x * zet[ghost_cell_index][j][i].x +
2963 zet[ghost_cell_index][j][i].y * zet[ghost_cell_index][j][i].y +
2964 zet[ghost_cell_index][j][i].z * zet[ghost_cell_index][j][i].z
2967 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[first_interior_cell][j][i] / face_area;
2968 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
2969 0.5 / cell_jacobian[second_interior_cell][j][i] / face_area;
2971 PetscReal wall_normal[3];
2972 wall_normal[0] = zet[ghost_cell_index][j][i].
x / face_area;
2973 wall_normal[1] = zet[ghost_cell_index][j][i].
y / face_area;
2974 wall_normal[2] = zet[ghost_cell_index][j][i].
z / face_area;
2976 Cmpnts wall_velocity, reference_velocity;
2977 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
2978 reference_velocity = velocity_cartesian[second_interior_cell][j][i];
2980 noslip(user, distance_to_second_cell, distance_to_first_cell,
2981 wall_velocity, reference_velocity,
2982 &velocity_cartesian[first_interior_cell][j][i],
2983 wall_normal[0], wall_normal[1], wall_normal[2]);
2986 distance_to_second_cell, distance_to_first_cell,
2987 wall_velocity, reference_velocity,
2988 &velocity_cartesian[first_interior_cell][j][i],
2989 &friction_velocity[first_interior_cell][j][i],
2990 wall_normal[0], wall_normal[1], wall_normal[2]);
2992 velocity_boundary[ghost_cell_index][j][i].
x = 0.0;
2993 velocity_boundary[ghost_cell_index][j][i].
y = 0.0;
2994 velocity_boundary[ghost_cell_index][j][i].
z = 0.0;
2995 velocity_contravariant[ghost_cell_index][j][i].
z = 0.0;
3006 if (grid_end_k == grid_size_k) {
3007 const PetscInt ghost_cell_index = grid_end_k - 1;
3008 const PetscInt first_interior_cell = grid_end_k - 2;
3009 const PetscInt second_interior_cell = grid_end_k - 3;
3011 for (PetscInt j = loop_start_j; j < loop_end_j; j++) {
3012 for (PetscInt i = loop_start_i; i < loop_end_i; i++) {
3014 if (node_vertex_flag[first_interior_cell][j][i] < 0.1) {
3016 PetscReal face_area = sqrt(
3017 zet[first_interior_cell][j][i].x * zet[first_interior_cell][j][i].x +
3018 zet[first_interior_cell][j][i].y * zet[first_interior_cell][j][i].y +
3019 zet[first_interior_cell][j][i].z * zet[first_interior_cell][j][i].z
3022 PetscReal distance_to_first_cell = 0.5 / cell_jacobian[first_interior_cell][j][i] / face_area;
3023 PetscReal distance_to_second_cell = 2.0 * distance_to_first_cell +
3024 0.5 / cell_jacobian[second_interior_cell][j][i] / face_area;
3026 PetscReal wall_normal[3];
3027 wall_normal[0] = -zet[first_interior_cell][j][i].
x / face_area;
3028 wall_normal[1] = -zet[first_interior_cell][j][i].
y / face_area;
3029 wall_normal[2] = -zet[first_interior_cell][j][i].
z / face_area;
3031 Cmpnts wall_velocity, reference_velocity;
3032 wall_velocity.
x = wall_velocity.
y = wall_velocity.
z = 0.0;
3033 reference_velocity = velocity_cartesian[second_interior_cell][j][i];
3035 noslip(user, distance_to_second_cell, distance_to_first_cell,
3036 wall_velocity, reference_velocity,
3037 &velocity_cartesian[first_interior_cell][j][i],
3038 wall_normal[0], wall_normal[1], wall_normal[2]);
3041 distance_to_second_cell, distance_to_first_cell,
3042 wall_velocity, reference_velocity,
3043 &velocity_cartesian[first_interior_cell][j][i],
3044 &friction_velocity[first_interior_cell][j][i],
3045 wall_normal[0], wall_normal[1], wall_normal[2]);
3047 velocity_boundary[ghost_cell_index][j][i].
x = 0.0;
3048 velocity_boundary[ghost_cell_index][j][i].
y = 0.0;
3049 velocity_boundary[ghost_cell_index][j][i].
z = 0.0;
3050 velocity_contravariant[first_interior_cell][j][i].
z = 0.0;
3062 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucat, &velocity_cartesian); CHKERRQ(ierr);
3063 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &velocity_contravariant); CHKERRQ(ierr);
3064 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &velocity_boundary); CHKERRQ(ierr);
3065 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
3066 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
3067 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
3068 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&node_vertex_flag); CHKERRQ(ierr);
3069 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lAj, (
const PetscReal***)&cell_jacobian); CHKERRQ(ierr);
3070 ierr = DMDAVecRestoreArray(user->
da, user->
lFriction_Velocity, &friction_velocity); CHKERRQ(ierr);
3074 PetscFunctionReturn(0);