10#define __FUNCT__ "Validate_DrivenFlowConfiguration"
17 PetscFunctionBeginUser;
20 PetscBool is_driven_flow_active = PETSC_FALSE;
21 char driven_direction =
' ';
22 const char* first_driven_face_name =
"";
24 for (
int i = 0; i < 6; i++) {
29 is_driven_flow_active = PETSC_TRUE;
32 if (i <= 1) driven_direction =
'X';
33 else if (i <= 3) driven_direction =
'Y';
34 else driven_direction =
'Z';
41 if (!is_driven_flow_active) {
42 PetscFunctionReturn(0);
45 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
" - Driven Flow Handler detected on face %s. Applying driven flow validation rules...\n", first_driven_face_name);
49 for (
int i = 0; i < 6; i++) {
52 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
53 "Configuration Error: A DRIVEN flow handler is active, which is incompatible with the %s boundary condition found on face %s.",
60 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
" - Validating symmetry and mathematical types for the '%c' direction...\n", driven_direction);
62 PetscInt neg_face_idx = 0, pos_face_idx = 0;
63 if (driven_direction ==
'X') {
65 }
else if (driven_direction ==
'Y') {
76 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
77 "Configuration Error: For a driven flow in the '%c' direction, both the %s and %s faces must be of mathematical_type PERIODIC.",
83 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
84 "Configuration Error: The DRIVEN handlers on the %s and %s faces of the '%c' direction do not match. Both must be the same type (e.g., both CONSTANT_FLUX).",
90 PetscFunctionReturn(0);
107#define __FUNCT__ "Create_WallNoSlip"
116 PetscFunctionBeginUser;
118 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
119 "Input BoundaryCondition object is NULL in Create_WallNoSlip");
135 PetscFunctionReturn(0);
139#define __FUNCT__ "Apply_WallNoSlip"
149 PetscBool can_service;
153 PetscFunctionBeginUser;
154 DMDALocalInfo *info = &user->
info;
156 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
158 IM_nodes_global = user->
IM;
159 JM_nodes_global = user->
JM;
160 KM_nodes_global = user->
KM;
162 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
164 if (!can_service) PetscFunctionReturn(0);
171 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
172 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
174 PetscInt xs = info->xs, xe = info->xs + info->xm;
175 PetscInt ys = info->ys, ye = info->ys + info->ym;
176 PetscInt zs = info->zs, ze = info->zs + info->zm;
177 PetscInt mx = info->mx, my = info->my, mz = info->mz;
180 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
181 if (xs == 0) lxs = xs + 1;
182 if (xe == mx) lxe = xe - 1;
183 if (ys == 0) lys = ys + 1;
184 if (ye == my) lye = ye - 1;
185 if (zs == 0) lzs = zs + 1;
186 if (ze == mz) lze = ze - 1;
192 for (PetscInt k = lzs; k < lze; k++) {
193 for (PetscInt j = lys; j < lye; j++) {
195 ucont[k][j][i].
x = 0.0;
198 ubcs[k][j][i].
x = 0.0;
199 ubcs[k][j][i].
y = 0.0;
200 ubcs[k][j][i].
z = 0.0;
210 for (PetscInt k = lzs; k < lze; k++) {
211 for (PetscInt j = lys; j < lye; j++) {
212 ucont[k][j][i-1].
x = 0.0;
214 ubcs[k][j][i].
x = 0.0;
215 ubcs[k][j][i].
y = 0.0;
216 ubcs[k][j][i].
z = 0.0;
225 for (PetscInt k = lzs; k < lze; k++) {
226 for (PetscInt i = lxs; i < lxe; i++) {
227 ucont[k][j][i].
y = 0.0;
229 ubcs[k][j][i].
x = 0.0;
230 ubcs[k][j][i].
y = 0.0;
231 ubcs[k][j][i].
z = 0.0;
240 for (PetscInt k = lzs; k < lze; k++) {
241 for (PetscInt i = lxs; i < lxe; i++) {
242 ucont[k][j-1][i].
y = 0.0;
244 ubcs[k][j][i].
x = 0.0;
245 ubcs[k][j][i].
y = 0.0;
246 ubcs[k][j][i].
z = 0.0;
255 for (PetscInt j = lys; j < lye; j++) {
256 for (PetscInt i = lxs; i < lxe; i++) {
257 ucont[k][j][i].
z = 0.0;
259 ubcs[k][j][i].
x = 0.0;
260 ubcs[k][j][i].
y = 0.0;
261 ubcs[k][j][i].
z = 0.0;
270 for (PetscInt j = lys; j < lye; j++) {
271 for (PetscInt i = lxs; i < lxe; i++) {
272 ucont[k-1][j][i].
z = 0.0;
274 ubcs[k][j][i].
x = 0.0;
275 ubcs[k][j][i].
y = 0.0;
276 ubcs[k][j][i].
z = 0.0;
284 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
285 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
287 PetscFunctionReturn(0);
302 PetscReal *in, PetscReal *out);
305 PetscReal *in, PetscReal *out);
316#define __FUNCT__ "Create_InletConstantVelocity"
326 PetscFunctionBeginUser;
328 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
331 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
332 bc->
data = (
void*)data;
342 PetscFunctionReturn(0);
347#define __FUNCT__ "Initialize_InletConstantVelocity"
360 PetscFunctionBeginUser;
361 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Initialize_InletConstantVelocity: Initializing handler for Face %d. \n", face_id);
393 PetscFunctionReturn(0);
397#define __FUNCT__ "PreStep_InletConstantVelocity"
403 PetscReal *local_inflow_contribution,
404 PetscReal *local_outflow_contribution)
412 (void)local_inflow_contribution;
413 (void)local_outflow_contribution;
415 PetscFunctionBeginUser;
416 PetscFunctionReturn(0);
420#define __FUNCT__ "Apply_InletConstantVelocity"
431 PetscBool can_service;
433 PetscFunctionBeginUser;
435 DMDALocalInfo *info = &user->
info;
436 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
438 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
440 IM_nodes_global = user->
IM;
441 JM_nodes_global = user->
JM;
442 KM_nodes_global = user->
KM;
444 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
446 if (!can_service) PetscFunctionReturn(0);
450 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
451 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
452 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
453 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
454 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
455 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
460 PetscInt xs = info->xs, xe = info->xs + info->xm;
461 PetscInt ys = info->ys, ye = info->ys + info->ym;
462 PetscInt zs = info->zs, ze = info->zs + info->zm;
463 PetscInt mx = info->mx, my = info->my, mz = info->mz;
465 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
466 if (xs == 0) lxs = xs + 1;
467 if (xe == mx) lxe = xe - 1;
468 if (ys == 0) lys = ys + 1;
469 if (ye == my) lye = ye - 1;
470 if (zs == 0) lzs = zs + 1;
471 if (ze == mz) lze = ze - 1;
479 for (PetscInt k = lzs; k < lze; k++) {
480 for (PetscInt j = lys; j < lye; j++) {
481 if ((sign > 0 && nvert[k][j][i+1] > 0.1) ||
482 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
484 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
485 csi[k][j][i].y * csi[k][j][i].y +
486 csi[k][j][i].z * csi[k][j][i].z);
488 ucont[k][j][i].
x = sign * uin_this_point * CellArea;
490 ubcs[k][j][i + (sign < 0)].x = sign * uin_this_point * csi[k][j][i].x / CellArea;
491 ubcs[k][j][i + (sign < 0)].y = sign * uin_this_point * csi[k][j][i].y / CellArea;
492 ubcs[k][j][i + (sign < 0)].z = sign * uin_this_point * csi[k][j][i].z / CellArea;
502 for (PetscInt k = lzs; k < lze; k++) {
503 for (PetscInt i = lxs; i < lxe; i++) {
504 if ((sign > 0 && nvert[k][j+1][i] > 0.1) ||
505 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
507 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
508 eta[k][j][i].y * eta[k][j][i].y +
509 eta[k][j][i].z * eta[k][j][i].z);
511 ucont[k][j][i].
y = sign * uin_this_point * CellArea;
513 ubcs[k][j + (sign < 0)][i].x = sign * uin_this_point * eta[k][j][i].x / CellArea;
514 ubcs[k][j + (sign < 0)][i].y = sign * uin_this_point * eta[k][j][i].y / CellArea;
515 ubcs[k][j + (sign < 0)][i].z = sign * uin_this_point * eta[k][j][i].z / CellArea;
525 for (PetscInt j = lys; j < lye; j++) {
526 for (PetscInt i = lxs; i < lxe; i++) {
527 if ((sign > 0 && nvert[k+1][j][i] > 0.1) ||
528 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
530 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
531 zet[k][j][i].y * zet[k][j][i].y +
532 zet[k][j][i].z * zet[k][j][i].z);
534 ucont[k][j][i].
z = sign * uin_this_point * CellArea;
536 ubcs[k + (sign < 0)][j][i].x = sign * uin_this_point * zet[k][j][i].x / CellArea;
537 ubcs[k + (sign < 0)][j][i].y = sign * uin_this_point * zet[k][j][i].y / CellArea;
538 ubcs[k + (sign < 0)][j][i].z = sign * uin_this_point * zet[k][j][i].z / CellArea;
545 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
546 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
547 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
548 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
549 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
550 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
552 PetscFunctionReturn(0);
556#define __FUNCT__ "PostStep_InletConstantVelocity"
562 PetscReal *local_inflow_contribution,
563 PetscReal *local_outflow_contribution)
568 PetscBool can_service;
571 (void)local_outflow_contribution;
573 PetscFunctionBeginUser;
575 DMDALocalInfo *info = &user->
info;
578 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
580 IM_nodes_global = user->
IM;
581 JM_nodes_global = user->
JM;
582 KM_nodes_global = user->
KM;
584 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
587 if (!can_service) PetscFunctionReturn(0);
589 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
591 PetscReal local_flux = 0.0;
593 PetscInt xs = info->xs, xe = info->xs + info->xm;
594 PetscInt ys = info->ys, ye = info->ys + info->ym;
595 PetscInt zs = info->zs, ze = info->zs + info->zm;
596 PetscInt mx = info->mx, my = info->my, mz = info->mz;
598 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
599 if (xs == 0) lxs = xs + 1;
600 if (xe == mx) lxe = xe - 1;
601 if (ys == 0) lys = ys + 1;
602 if (ye == my) lye = ye - 1;
603 if (zs == 0) lzs = zs + 1;
604 if (ze == mz) lze = ze - 1;
611 for (PetscInt k = lzs; k < lze; k++) {
612 for (PetscInt j = lys; j < lye; j++) {
613 local_flux += ucont[k][j][i].
x;
621 for (PetscInt k = lzs; k < lze; k++) {
622 for (PetscInt i = lxs; i < lxe; i++) {
623 local_flux += ucont[k][j][i].
y;
631 for (PetscInt j = lys; j < lye; j++) {
632 for (PetscInt i = lxs; i < lxe; i++) {
633 local_flux += ucont[k][j][i].
z;
639 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
641 *local_inflow_contribution += local_flux;
644 face_id, local_flux);
646 PetscFunctionReturn(0);
651#define __FUNCT__ "Destroy_InletConstantVelocity"
658 PetscFunctionBeginUser;
659 if (self && self->
data) {
660 PetscFree(self->
data);
663 PetscFunctionReturn(0);
693 PetscReal *in, PetscReal *out);
696 PetscReal *in, PetscReal *out);
714#define __FUNCT__ "Create_InletParabolicProfile"
724 PetscFunctionBeginUser;
726 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
729 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
730 bc->
data = (
void*)data;
740 PetscFunctionReturn(0);
745#define __FUNCT__ "Initialize_InletParabolicProfile"
758 PetscFunctionBeginUser;
764 &data->
v_max, &found); CHKERRQ(ierr);
766 LOG_ALLOW(
GLOBAL,
LOG_WARNING,
"Initialize_InletParabolicProfile: 'v_max' not found in params for face %d. Defaulting to 0.0.\n", face_id);
770 PetscReal cs1_dim, cs2_dim;
774 cs1_dim = (PetscReal)user->
JM;
775 cs2_dim = (PetscReal)user->
KM;
779 cs1_dim = (PetscReal)user->
IM;
780 cs2_dim = (PetscReal)user->
KM;
785 cs1_dim = (PetscReal)user->
IM;
786 cs2_dim = (PetscReal)user->
JM;
791 PetscReal cs1_width = cs1_dim - 2.0;
792 PetscReal cs2_width = cs2_dim - 2.0;
806 PetscFunctionReturn(0);
811#define __FUNCT__ "PreStep_InletParabolicProfile"
817 PetscReal *local_inflow_contribution,
818 PetscReal *local_outflow_contribution)
822 (void)local_inflow_contribution;
823 (void)local_outflow_contribution;
825 PetscFunctionBeginUser;
826 PetscFunctionReturn(0);
831#define __FUNCT__ "Apply_InletParabolicProfile"
842 PetscBool can_service;
844 PetscFunctionBeginUser;
846 DMDALocalInfo *info = &user->
info;
847 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
849 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
851 IM_nodes_global = user->
IM;
852 JM_nodes_global = user->
JM;
853 KM_nodes_global = user->
KM;
856 face_id, &can_service); CHKERRQ(ierr);
858 if (!can_service) PetscFunctionReturn(0);
861 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
862 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
863 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
864 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
865 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
866 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
868 PetscInt xs = info->xs, xe = info->xs + info->xm;
869 PetscInt ys = info->ys, ye = info->ys + info->ym;
870 PetscInt zs = info->zs, ze = info->zs + info->zm;
871 PetscInt mx = info->mx, my = info->my, mz = info->mz;
873 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
874 if (xs == 0) lxs = xs + 1;
875 if (xe == mx) lxe = xe - 1;
876 if (ys == 0) lys = ys + 1;
877 if (ye == my) lye = ye - 1;
878 if (zs == 0) lzs = zs + 1;
879 if (ze == mz) lze = ze - 1;
888 for (PetscInt k = lzs; k < lze; k++) {
889 for (PetscInt j = lys; j < lye; j++) {
890 if ((sign > 0 && nvert[k][j][i+1] > 0.1) ||
891 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
896 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
897 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
898 PetscReal uin_local = data->
v_max * profile;
900 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
901 csi[k][j][i].y * csi[k][j][i].y +
902 csi[k][j][i].z * csi[k][j][i].z);
904 ucont[k][j][i].
x = sign * uin_local * CellArea;
906 ubcs[k][j][i + (sign < 0)].x = sign * uin_local * csi[k][j][i].x / CellArea;
907 ubcs[k][j][i + (sign < 0)].y = sign * uin_local * csi[k][j][i].y / CellArea;
908 ubcs[k][j][i + (sign < 0)].z = sign * uin_local * csi[k][j][i].z / CellArea;
919 for (PetscInt k = lzs; k < lze; k++) {
920 for (PetscInt i = lxs; i < lxe; i++) {
921 if ((sign > 0 && nvert[k][j+1][i] > 0.1) ||
922 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
927 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
928 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
929 PetscReal uin_local = data->
v_max * profile;
931 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
932 eta[k][j][i].y * eta[k][j][i].y +
933 eta[k][j][i].z * eta[k][j][i].z);
935 ucont[k][j][i].
y = sign * uin_local * CellArea;
937 ubcs[k][j + (sign < 0)][i].x = sign * uin_local * eta[k][j][i].x / CellArea;
938 ubcs[k][j + (sign < 0)][i].y = sign * uin_local * eta[k][j][i].y / CellArea;
939 ubcs[k][j + (sign < 0)][i].z = sign * uin_local * eta[k][j][i].z / CellArea;
950 for (PetscInt j = lys; j < lye; j++) {
951 for (PetscInt i = lxs; i < lxe; i++) {
952 if ((sign > 0 && nvert[k+1][j][i] > 0.1) ||
953 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
958 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
959 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
960 PetscReal uin_local = data->
v_max * profile;
962 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
963 zet[k][j][i].y * zet[k][j][i].y +
964 zet[k][j][i].z * zet[k][j][i].z);
966 ucont[k][j][i].
z = sign * uin_local * CellArea;
968 ubcs[k + (sign < 0)][j][i].x = sign * uin_local * zet[k][j][i].x / CellArea;
969 ubcs[k + (sign < 0)][j][i].y = sign * uin_local * zet[k][j][i].y / CellArea;
970 ubcs[k + (sign < 0)][j][i].z = sign * uin_local * zet[k][j][i].z / CellArea;
977 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
978 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
979 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
980 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
981 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
982 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
984 PetscFunctionReturn(0);
989#define __FUNCT__ "PostStep_InletParabolicProfile"
995 PetscReal *local_inflow_contribution,
996 PetscReal *local_outflow_contribution)
1001 PetscBool can_service;
1004 (void)local_outflow_contribution;
1006 PetscFunctionBeginUser;
1008 DMDALocalInfo *info = &user->
info;
1011 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
1013 IM_nodes_global = user->
IM;
1014 JM_nodes_global = user->
JM;
1015 KM_nodes_global = user->
KM;
1018 face_id, &can_service); CHKERRQ(ierr);
1020 if (!can_service) PetscFunctionReturn(0);
1022 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1024 PetscReal local_flux = 0.0;
1026 PetscInt xs = info->xs, xe = info->xs + info->xm;
1027 PetscInt ys = info->ys, ye = info->ys + info->ym;
1028 PetscInt zs = info->zs, ze = info->zs + info->zm;
1029 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1031 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1032 if (xs == 0) lxs = xs + 1;
1033 if (xe == mx) lxe = xe - 1;
1034 if (ys == 0) lys = ys + 1;
1035 if (ye == my) lye = ye - 1;
1036 if (zs == 0) lzs = zs + 1;
1037 if (ze == mz) lze = ze - 1;
1043 for (PetscInt k = lzs; k < lze; k++) {
1044 for (PetscInt j = lys; j < lye; j++) {
1045 local_flux += ucont[k][j][i].
x;
1053 for (PetscInt k = lzs; k < lze; k++) {
1054 for (PetscInt i = lxs; i < lxe; i++) {
1055 local_flux += ucont[k][j][i].
y;
1063 for (PetscInt j = lys; j < lye; j++) {
1064 for (PetscInt i = lxs; i < lxe; i++) {
1065 local_flux += ucont[k][j][i].
z;
1071 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1073 *local_inflow_contribution += local_flux;
1076 face_id, local_flux);
1078 PetscFunctionReturn(0);
1083#define __FUNCT__ "Destroy_InletParabolicProfile"
1090 PetscFunctionBeginUser;
1091 if (self && self->
data) {
1092 PetscFree(self->
data);
1095 PetscFunctionReturn(0);
1111 PetscReal *in, PetscReal *out);
1114 PetscReal *in, PetscReal *out);
1136 const char **value_out, PetscBool *found)
1138 PetscFunctionBeginUser;
1139 *found = PETSC_FALSE;
1141 for (
BC_Param *param = params; param; param = param->
next) {
1142 if (strcasecmp(param->key, key) == 0) {
1143 *value_out = param->value;
1144 *found = PETSC_TRUE;
1145 PetscFunctionReturn(0);
1148 PetscFunctionReturn(0);
1161 PetscInt *n1, PetscInt *n2)
1163 PetscFunctionBeginUser;
1181 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
1182 "Unsupported face id %d for inlet profile dimensions.", face_id);
1184 if (*n1 <= 0 || *n2 <= 0) {
1185 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1186 "Invalid inlet profile dimensions (%d, %d) for grid (%d, %d, %d).",
1187 *n1, *n2, user->
IM, user->
JM, user->
KM);
1189 PetscFunctionReturn(0);
1208 PetscErrorCode ierr;
1210 char magic[32] = {0};
1211 PetscInt frame_count = 0, n1 = 0, n2 = 0;
1213 PetscFunctionBeginUser;
1214 fd = fopen(source_file,
"r");
1215 if (!fd) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
1216 "Cannot open PICSLICE inlet profile file: %s", source_file);
1218 if (fscanf(fd,
"%31s", magic) != 1 || strcmp(magic,
"PICSLICE") != 0) {
1220 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1221 "PICSLICE inlet profile file %s must begin with PICSLICE header.", source_file);
1223 if (fscanf(fd,
"%d", &frame_count) != 1) {
1225 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1226 "PICSLICE inlet profile file %s missing frame count.", source_file);
1228 if (frame_count != 1) {
1230 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1231 "PICSLICE inlet profile file %s has %d frames; static handler requires 1.",
1232 source_file, frame_count);
1234 if (fscanf(fd,
"%d %d", &n1, &n2) != 2) {
1236 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1237 "PICSLICE inlet profile file %s missing slice dimensions.", source_file);
1239 if (n1 != expected_n1 || n2 != expected_n2) {
1241 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1242 "PICSLICE inlet profile dimensions mismatch for %s: expected (%d, %d), found (%d, %d).",
1243 source_file, expected_n1, expected_n2, n1, n2);
1248 ierr = PetscMalloc1(n1 * n2, &data->
profile); CHKERRQ(ierr);
1252 for (PetscInt idx = 0; idx < n1 * n2; idx++) {
1253 PetscReal value = 0.0;
1254 if (fscanf(fd,
"%le", &value) != 1) {
1256 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1257 "PICSLICE inlet profile file %s ended early: expected %d values.",
1258 source_file, n1 * n2);
1260 if (PetscIsInfOrNanReal(value) || value < 0.0) {
1262 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1263 "PICSLICE inlet profile file %s contains invalid speed %.6e at flat index %d.",
1264 source_file, (
double)value, idx);
1272 if (fscanf(fd,
"%63s", extra) == 1) {
1274 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1275 "PICSLICE inlet profile file %s has extra token after %d values: %s",
1276 source_file, n1 * n2, extra);
1279 PetscFunctionReturn(0);
1296#define __FUNCT__ "Create_InletProfileFromFile"
1305 PetscErrorCode ierr;
1306 PetscFunctionBeginUser;
1308 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
1311 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
1318 bc->
data = (
void*)data;
1328 PetscFunctionReturn(0);
1332#define __FUNCT__ "Initialize_InletProfileFromFile"
1346 PetscErrorCode ierr;
1350 PetscBool found = PETSC_FALSE;
1351 const char *source_file = NULL;
1352 PetscInt expected_n1 = 0, expected_n2 = 0;
1354 PetscFunctionBeginUser;
1356 &source_file, &found); CHKERRQ(ierr);
1357 if (!found || !source_file || source_file[0] ==
'\0') {
1358 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1359 "InletProfileFromFile requires source_file parameter for face %d.", face_id);
1362 ierr = PetscStrallocpy(source_file, &data->
source_file); CHKERRQ(ierr);
1367 " Inlet Face %d (Prescribed Flow): source=%s dims=(%d,%d) speed[min,max]=[%.6e, %.6e]\n",
1372 PetscFunctionReturn(0);
1376#define __FUNCT__ "PreStep_InletProfileFromFile"
1390 PetscReal *local_inflow_contribution,
1391 PetscReal *local_outflow_contribution)
1395 (void)local_inflow_contribution;
1396 (void)local_outflow_contribution;
1397 PetscFunctionBeginUser;
1398 PetscFunctionReturn(0);
1402#define __FUNCT__ "Apply_InletProfileFromFile"
1417 PetscErrorCode ierr;
1421 PetscBool can_service;
1423 PetscFunctionBeginUser;
1424 DMDALocalInfo *info = &user->
info;
1425 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
1429 if (!can_service) PetscFunctionReturn(0);
1431 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1432 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1433 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1434 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1435 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1436 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1438 PetscInt xs = info->xs, xe = info->xs + info->xm;
1439 PetscInt ys = info->ys, ye = info->ys + info->ym;
1440 PetscInt zs = info->zs, ze = info->zs + info->zm;
1441 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1443 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1444 if (xs == 0) lxs = xs + 1;
1445 if (xe == mx) lxe = xe - 1;
1446 if (ys == 0) lys = ys + 1;
1447 if (ye == my) lye = ye - 1;
1448 if (zs == 0) lzs = zs + 1;
1449 if (ze == mz) lze = ze - 1;
1456 for (PetscInt k = lzs; k < lze; k++) {
1457 for (PetscInt j = lys; j < lye; j++) {
1458 if ((sign > 0 && nvert[k][j][i+1] > 0.1) ||
1459 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1461 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
1462 csi[k][j][i].y * csi[k][j][i].y +
1463 csi[k][j][i].z * csi[k][j][i].z);
1464 ucont[k][j][i].
x = sign * uin_local * CellArea;
1465 ubcs[k][j][i + (sign < 0)].x = sign * uin_local * csi[k][j][i].x / CellArea;
1466 ubcs[k][j][i + (sign < 0)].y = sign * uin_local * csi[k][j][i].y / CellArea;
1467 ubcs[k][j][i + (sign < 0)].z = sign * uin_local * csi[k][j][i].z / CellArea;
1475 for (PetscInt k = lzs; k < lze; k++) {
1476 for (PetscInt i = lxs; i < lxe; i++) {
1477 if ((sign > 0 && nvert[k][j+1][i] > 0.1) ||
1478 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1480 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
1481 eta[k][j][i].y * eta[k][j][i].y +
1482 eta[k][j][i].z * eta[k][j][i].z);
1483 ucont[k][j][i].
y = sign * uin_local * CellArea;
1484 ubcs[k][j + (sign < 0)][i].x = sign * uin_local * eta[k][j][i].x / CellArea;
1485 ubcs[k][j + (sign < 0)][i].y = sign * uin_local * eta[k][j][i].y / CellArea;
1486 ubcs[k][j + (sign < 0)][i].z = sign * uin_local * eta[k][j][i].z / CellArea;
1494 for (PetscInt j = lys; j < lye; j++) {
1495 for (PetscInt i = lxs; i < lxe; i++) {
1496 if ((sign > 0 && nvert[k+1][j][i] > 0.1) ||
1497 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1499 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
1500 zet[k][j][i].y * zet[k][j][i].y +
1501 zet[k][j][i].z * zet[k][j][i].z);
1502 ucont[k][j][i].
z = sign * uin_local * CellArea;
1503 ubcs[k + (sign < 0)][j][i].x = sign * uin_local * zet[k][j][i].x / CellArea;
1504 ubcs[k + (sign < 0)][j][i].y = sign * uin_local * zet[k][j][i].y / CellArea;
1505 ubcs[k + (sign < 0)][j][i].z = sign * uin_local * zet[k][j][i].z / CellArea;
1511 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1512 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1513 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1514 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1515 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1516 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1518 PetscFunctionReturn(0);
1522#define __FUNCT__ "PostStep_InletProfileFromFile"
1536 PetscReal *local_inflow_contribution,
1537 PetscReal *local_outflow_contribution)
1539 PetscErrorCode ierr;
1542 PetscBool can_service;
1545 (void)local_outflow_contribution;
1547 PetscFunctionBeginUser;
1548 DMDALocalInfo *info = &user->
info;
1552 if (!can_service) PetscFunctionReturn(0);
1554 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1555 PetscReal local_flux = 0.0;
1557 PetscInt xs = info->xs, xe = info->xs + info->xm;
1558 PetscInt ys = info->ys, ye = info->ys + info->ym;
1559 PetscInt zs = info->zs, ze = info->zs + info->zm;
1560 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1562 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1563 if (xs == 0) lxs = xs + 1;
1564 if (xe == mx) lxe = xe - 1;
1565 if (ys == 0) lys = ys + 1;
1566 if (ye == my) lye = ye - 1;
1567 if (zs == 0) lzs = zs + 1;
1568 if (ze == mz) lze = ze - 1;
1574 for (PetscInt k = lzs; k < lze; k++)
1575 for (PetscInt j = lys; j < lye; j++)
1576 local_flux += ucont[k][j][i].x;
1581 for (PetscInt k = lzs; k < lze; k++)
1582 for (PetscInt i = lxs; i < lxe; i++)
1583 local_flux += ucont[k][j][i].y;
1588 for (PetscInt j = lys; j < lye; j++)
1589 for (PetscInt i = lxs; i < lxe; i++)
1590 local_flux += ucont[k][j][i].z;
1594 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1595 *local_inflow_contribution += local_flux;
1598 face_id, local_flux);
1600 PetscFunctionReturn(0);
1604#define __FUNCT__ "Destroy_InletProfileFromFile"
1613 PetscFunctionBeginUser;
1614 if (self && self->
data) {
1618 PetscFree(self->
data);
1621 PetscFunctionReturn(0);
1642 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution);
1645 PetscReal *in, PetscReal *out);
1648#define __FUNCT__ "Create_OutletConservation"
1657 PetscFunctionBeginUser;
1659 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
1675 PetscFunctionReturn(0);
1679#define __FUNCT__ "PreStep_OutletConservation"
1685 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution)
1687 PetscErrorCode ierr;
1690 DMDALocalInfo* info = &user->
info;
1691 PetscBool can_service;
1695 (void)local_inflow_contribution;
1697 PetscFunctionBeginUser;
1701 const PetscInt IM_nodes_global = user->
IM;
1702 const PetscInt JM_nodes_global = user->
JM;
1703 const PetscInt KM_nodes_global = user->
KM;
1704 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1707 PetscFunctionReturn(0);
1713 Cmpnts ***ucat, ***csi, ***eta, ***zet;
1715 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1716 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1717 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1718 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1719 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1721 PetscReal local_flux_out = 0.0;
1722 const PetscInt xs=info->xs, xe=info->xs+info->xm;
1723 const PetscInt ys=info->ys, ye=info->ys+info->ym;
1724 const PetscInt zs=info->zs, ze=info->zs+info->zm;
1725 const PetscInt mx=info->mx, my=info->my, mz=info->mz;
1728 PetscInt lxs = xs;
if (xs == 0) lxs = xs + 1;
1729 PetscInt lxe = xe;
if (xe == mx) lxe = xe - 1;
1730 PetscInt lys = ys;
if (ys == 0) lys = ys + 1;
1731 PetscInt lye = ye;
if (ye == my) lye = ye - 1;
1732 PetscInt lzs = zs;
if (zs == 0) lzs = zs + 1;
1733 PetscInt lze = ze;
if (ze == mz) lze = ze - 1;
1738 const PetscInt i_cell = xs + 1;
1739 const PetscInt i_face = xs;
1740 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1741 if (nvert[k][j][i_cell] < 0.1) {
1742 local_flux_out += (ucat[k][j][i_cell].
x * csi[k][j][i_face].
x + ucat[k][j][i_cell].
y * csi[k][j][i_face].
y + ucat[k][j][i_cell].
z * csi[k][j][i_face].
z);
1748 const PetscInt i_cell = xe - 2;
1749 const PetscInt i_face = xe - 2;
1750 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1751 if (nvert[k][j][i_cell] < 0.1) {
1752 local_flux_out += (ucat[k][j][i_cell].
x * csi[k][j][i_face].
x + ucat[k][j][i_cell].
y * csi[k][j][i_face].
y + ucat[k][j][i_cell].
z * csi[k][j][i_face].
z);
1758 const PetscInt j_cell = ys + 1;
1759 const PetscInt j_face = ys;
1760 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1761 if (nvert[k][j_cell][i] < 0.1) {
1762 local_flux_out += (ucat[k][j_cell][i].
x * eta[k][j_face][i].
x + ucat[k][j_cell][i].
y * eta[k][j_face][i].
y + ucat[k][j_cell][i].
z * eta[k][j_face][i].
z);
1768 const PetscInt j_cell = ye - 2;
1769 const PetscInt j_face = ye - 2;
1770 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1771 if (nvert[k][j_cell][i] < 0.1) {
1772 local_flux_out += (ucat[k][j_cell][i].
x * eta[k][j_face][i].
x + ucat[k][j_cell][i].
y * eta[k][j_face][i].
y + ucat[k][j_cell][i].
z * eta[k][j_face][i].
z);
1778 const PetscInt k_cell = zs + 1;
1779 const PetscInt k_face = zs;
1780 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1781 if (nvert[k_cell][j][i] < 0.1) {
1782 local_flux_out += (ucat[k_cell][j][i].
x * zet[k_face][j][i].
x + ucat[k_cell][j][i].
y * zet[k_face][j][i].
y + ucat[k_cell][j][i].
z * zet[k_face][j][i].
z);
1788 const PetscInt k_cell = ze - 2;
1789 const PetscInt k_face = ze - 2;
1790 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1791 if (nvert[k_cell][j][i] < 0.1) {
1792 local_flux_out += (ucat[k_cell][j][i].
x * zet[k_face][j][i].
x + ucat[k_cell][j][i].
y * zet[k_face][j][i].
y + ucat[k_cell][j][i].
z * zet[k_face][j][i].
z);
1800 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1801 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1802 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1803 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1804 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1807 *local_outflow_contribution += local_flux_out;
1809 PetscFunctionReturn(0);
1813#define __FUNCT__ "Apply_OutletConservation"
1822 PetscErrorCode ierr;
1826 DMDALocalInfo* info = &user->
info;
1827 PetscBool can_service;
1829 PetscFunctionBeginUser;
1832 const PetscInt IM_nodes_global = user->
IM;
1833 const PetscInt JM_nodes_global = user->
JM;
1834 const PetscInt KM_nodes_global = user->
KM;
1835 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1839 PetscFunctionReturn(0);
1847 PetscReal velocity_correction = (PetscAbsReal(user->
simCtx->
AreaOutSum) > 1e-12)
1858 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet, ***ucat;
1860 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1861 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1862 ierr = DMDAVecGetArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1863 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1864 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1865 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1866 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1869 PetscInt xs = info->xs, xe = info->xs + info->xm;
1870 PetscInt ys = info->ys, ye = info->ys + info->ym;
1871 PetscInt zs = info->zs, ze = info->zs + info->zm;
1872 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1873 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1875 if (xs == 0) lxs = xs + 1;
1876 if (xe == mx) lxe = xe - 1;
1877 if (ys == 0) lys = ys + 1;
1878 if (ye == my) lye = ye - 1;
1879 if (zs == 0) lzs = zs + 1;
1880 if (ze == mz) lze = ze - 1;
1885 const PetscInt i_cell = xs + 1;
1886 const PetscInt i_face = xs;
1887 const PetscInt i_dummy = xs;
1888 for (PetscInt k = lzs; k < lze; k++) {
1889 for (PetscInt j = lys; j < lye; j++) {
1890 if (nvert[k][j][i_cell] < 0.1) {
1892 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1895 PetscReal Uncorrected_local_flux = (ubcs[k][j][i_dummy].
x * csi[k][j][i_face].
x) + (ubcs[k][j][i_dummy].y * csi[k][j][i_face].y) + (ubcs[k][j][i_dummy].
z * csi[k][j][i_face].
z);
1897 PetscReal Cell_Area = sqrt((csi[k][j][i_face].x*csi[k][j][i_face].x) + (csi[k][j][i_face].y*csi[k][j][i_face].y) + (csi[k][j][i_face].z*csi[k][j][i_face].z));
1899 PetscReal Correction_flux = velocity_correction*Cell_Area;
1901 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1908 const PetscInt i_cell = xe - 2;
1909 const PetscInt i_face = xe - 2;
1910 const PetscInt i_dummy = xe - 1;
1911 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++){
1912 if(nvert[k][j][i_cell]<0.1){
1914 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1917 PetscReal Uncorrected_local_flux = (ubcs[k][j][i_dummy].
x * csi[k][j][i_face].
x) + (ubcs[k][j][i_dummy].y * csi[k][j][i_face].y) + (ubcs[k][j][i_dummy].
z * csi[k][j][i_face].
z);
1919 PetscReal Cell_Area = sqrt((csi[k][j][i_face].x*csi[k][j][i_face].x) + (csi[k][j][i_face].y*csi[k][j][i_face].y) + (csi[k][j][i_face].z*csi[k][j][i_face].z));
1921 PetscReal Correction_flux = velocity_correction*Cell_Area;
1923 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1929 const PetscInt j_cell = ys + 1;
1930 const PetscInt j_face = ys;
1931 const PetscInt j_dummy = ys;
1932 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1933 if(nvert[k][j_cell][i]<0.1){
1935 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1938 PetscReal Uncorrected_local_flux = (ubcs[k][j_dummy][i].
x*eta[k][j_face][i].
x) + (ubcs[k][j_dummy][i].y*eta[k][j_face][i].y) + (ubcs[k][j_dummy][i].
z*eta[k][j_face][i].
z);
1940 PetscReal Cell_Area = sqrt((eta[k][j_face][i].x*eta[k][j_face][i].x)+(eta[k][j_face][i].y*eta[k][j_face][i].y)+(eta[k][j_face][i].z*eta[k][j_face][i].z));
1942 PetscReal Correction_flux = velocity_correction*Cell_Area;
1944 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1950 const PetscInt j_cell = ye - 2;
1951 const PetscInt j_face = ye - 2;
1952 const PetscInt j_dummy = ye - 1;
1953 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1954 if(nvert[k][j_cell][i]<0.1){
1956 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1959 PetscReal Uncorrected_local_flux = (ubcs[k][j_dummy][i].
x*eta[k][j_face][i].
x) + (ubcs[k][j_dummy][i].y*eta[k][j_face][i].y) + (ubcs[k][j_dummy][i].
z*eta[k][j_face][i].
z);
1961 PetscReal Cell_Area = sqrt((eta[k][j_face][i].x*eta[k][j_face][i].x)+(eta[k][j_face][i].y*eta[k][j_face][i].y)+(eta[k][j_face][i].z*eta[k][j_face][i].z));
1963 PetscReal Correction_flux = velocity_correction*Cell_Area;
1965 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1971 const PetscInt k_cell = zs + 1;
1972 const PetscInt k_face = zs;
1973 const PetscInt k_dummy = zs;
1974 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1975 if(nvert[k_cell][j][i]<0.1){
1977 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
1980 PetscReal Uncorrected_local_flux = ((ubcs[k_dummy][j][i].
x*zet[k_face][j][i].
x) + (ubcs[k_dummy][j][i].y*zet[k_face][j][i].y) + (ubcs[k_dummy][j][i].
z*zet[k_face][j][i].
z));
1982 PetscReal Cell_Area = sqrt((zet[k_face][j][i].x*zet[k_face][j][i].x)+(zet[k_face][j][i].y*zet[k_face][j][i].y)+(zet[k_face][j][i].z*zet[k_face][j][i].z));
1984 PetscReal Correction_flux = velocity_correction*Cell_Area;
1986 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
1992 const PetscInt k_cell = ze - 2;
1993 const PetscInt k_face = ze - 2;
1994 const PetscInt k_dummy = ze - 1;
1995 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1996 if(nvert[k_cell][j][i]<0.1){
1998 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
2001 PetscReal Uncorrected_local_flux = ((ubcs[k_dummy][j][i].
x*zet[k_face][j][i].
x) + (ubcs[k_dummy][j][i].y*zet[k_face][j][i].y) + (ubcs[k_dummy][j][i].
z*zet[k_face][j][i].
z));
2003 PetscReal Cell_Area = sqrt((zet[k_face][j][i].x*zet[k_face][j][i].x)+(zet[k_face][j][i].y*zet[k_face][j][i].y)+(zet[k_face][j][i].z*zet[k_face][j][i].z));
2005 PetscReal Correction_flux = velocity_correction*Cell_Area;
2007 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
2015 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
2016 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
2017 ierr = DMDAVecRestoreArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
2018 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2019 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2020 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2021 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2024 PetscFunctionReturn(0);
2028#define __FUNCT__ "PostStep_OutletConservation"
2034 PetscReal *local_inflow_contribution,
2035 PetscReal *local_outflow_contribution)
2037 PetscErrorCode ierr;
2040 DMDALocalInfo* info = &user->
info;
2041 PetscBool can_service;
2044 (void)local_inflow_contribution;
2046 PetscFunctionBeginUser;
2047 const PetscInt IM_nodes_global = user->
IM;
2048 const PetscInt JM_nodes_global = user->
JM;
2049 const PetscInt KM_nodes_global = user->
KM;
2050 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
2052 if (!can_service) PetscFunctionReturn(0);
2058 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2059 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2061 PetscReal local_flux = 0.0;
2063 PetscInt xs = info->xs, xe = info->xs + info->xm;
2064 PetscInt ys = info->ys, ye = info->ys + info->ym;
2065 PetscInt zs = info->zs, ze = info->zs + info->zm;
2066 PetscInt mx = info->mx, my = info->my, mz = info->mz;
2068 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
2069 if (xs == 0) lxs = xs + 1;
2070 if (xe == mx) lxe = xe - 1;
2071 if (ys == 0) lys = ys + 1;
2072 if (ye == my) lye = ye - 1;
2073 if (zs == 0) lzs = zs + 1;
2074 if (ze == mz) lze = ze - 1;
2079 const PetscInt i_cell = xs + 1;
2080 const PetscInt i_face = xs;
2081 for (PetscInt k = lzs; k < lze; k++) {
2082 for (PetscInt j = lys; j < lye; j++) {
2083 if (nvert[k][j][i_cell] < 0.1) {
2084 local_flux += ucont[k][j][i_face].
x;
2091 const PetscInt i_cell = xe - 2;
2092 const PetscInt i_face = xe - 2;
2093 for (PetscInt k = lzs; k < lze; k++) {
2094 for (PetscInt j = lys; j < lye; j++) {
2095 if (nvert[k][j][i_cell] < 0.1) {
2096 local_flux += ucont[k][j][i_face].
x;
2103 const PetscInt j_cell = ys + 1;
2104 const PetscInt j_face = ys;
2105 for (PetscInt k = lzs; k < lze; k++) {
2106 for (PetscInt i = lxs; i < lxe; i++) {
2107 if (nvert[k][j_cell][i] < 0.1) {
2108 local_flux += ucont[k][j_face][i].
y;
2115 const PetscInt j_cell = ye - 2;
2116 const PetscInt j_face = ye - 2;
2117 for (PetscInt k = lzs; k < lze; k++) {
2118 for (PetscInt i = lxs; i < lxe; i++) {
2119 if (nvert[k][j_cell][i] < 0.1) {
2120 local_flux += ucont[k][j_face][i].
y;
2127 const PetscInt k_cell = zs + 1;
2128 const PetscInt k_face = zs;
2129 for (PetscInt j = lys; j < lye; j++) {
2130 for (PetscInt i = lxs; i < lxe; i++) {
2131 if (nvert[k_cell][j][i] < 0.1) {
2132 local_flux += ucont[k_face][j][i].
z;
2139 const PetscInt k_cell = ze - 2;
2140 const PetscInt k_face = ze - 2;
2141 for (PetscInt j = lys; j < lye; j++) {
2142 for (PetscInt i = lxs; i < lxe; i++) {
2143 if (nvert[k_cell][j][i] < 0.1) {
2144 local_flux += ucont[k_face][j][i].
z;
2152 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2153 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2156 *local_outflow_contribution += local_flux;
2159 face_id, local_flux);
2161 PetscFunctionReturn(0);
2173 PetscFunctionBeginUser;
2175 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
2188 PetscFunctionReturn(0);
2220#define __FUNCT__ "Create_PeriodicDrivenConstant"
2227 PetscErrorCode ierr;
2228 PetscFunctionBeginUser;
2230 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition object is NULL in Create_PeriodicDrivenConstantFlux");
2234 ierr = PetscNew(&data); CHKERRQ(ierr);
2243 bc->
data = (
void*)data;
2260 PetscFunctionReturn(0);
2264#define __FUNCT__ "Initialize_PeriodicDrivenConstant"
2271 PetscErrorCode ierr;
2276 PetscFunctionBeginUser;
2282 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2283 "Configuration Error: Handler PERIODIC_DRIVEN_CONSTANT_FLUX on Face %s must be applied to a face with mathematical_type PERIODIC.",
2308 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2309 "Configuration Error: Handler PERIODIC_DRIVEN_CONSTANT_FLUX on Face %s requires a 'target_flux' parameter in the bcs file (e.g., target_flux=10.0).",
2321 PetscBool trimfound;
2328 PetscFunctionReturn(0);
2332#define __FUNCT__ "PreStep_PeriodicDrivenConstant"
2338 PetscReal *local_inflow_contribution,
2339 PetscReal *local_outflow_contribution)
2341 PetscErrorCode ierr;
2346 PetscFunctionBeginUser;
2350 PetscFunctionReturn(0);
2355 DMDALocalInfo info = user->
info;
2361 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2362 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2365 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
2366 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
2367 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
2368 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
2369 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
2370 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2426 PetscReal localCurrentBoundaryFlux = 0.0;
2427 PetscReal localAveragePlanarVolumetricFluxTerm = 0.0;
2430 switch (direction) {
2434 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2435 if (nvert[k][j][i + 1] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
x;
2438 for (i = info.xs; i < lxe; i++) {
2439 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2440 if (nvert[k][j][i + 1] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
x / (PetscReal)(info.mx - 1);
2447 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2448 if (nvert[k][j + 1][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
y;
2451 for (j = info.ys; j < lye; j++) {
2452 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2453 if (nvert[k][j + 1][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
y / (PetscReal)(info.my - 1);
2460 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2461 if (nvert[k + 1][j][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
z;
2464 for (k = info.zs; k < lze; k++) {
2465 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2466 if (nvert[k + 1][j][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
z / (PetscReal)(info.mz - 1);
2473 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2474 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2478 PetscReal globalBoundaryArea;
2483 PetscReal globalCurrentBoundaryFlux, globalAveragePlanarVolumetricFlux;
2484 ierr = MPI_Allreduce(&localCurrentBoundaryFlux, &globalCurrentBoundaryFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2485 ierr = MPI_Allreduce(&localAveragePlanarVolumetricFluxTerm, &globalAveragePlanarVolumetricFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2488 if (globalBoundaryArea > 1.0e-12) {
2501 LOG_ALLOW(
GLOBAL,
LOG_INFO,
" - Avg Planar Volumetric Flux (Stable): %.6e\n", globalAveragePlanarVolumetricFlux);
2507 (void)local_inflow_contribution;
2508 (void)local_outflow_contribution;
2510 PetscFunctionReturn(0);
2514#define __FUNCT__ "Apply_PeriodicDrivenConstant"
2521 PetscErrorCode ierr;
2525 PetscBool can_service;
2527 PetscFunctionBeginUser;
2532 PetscFunctionReturn(0);
2537 PetscFunctionReturn(0);
2543 DMDALocalInfo info = user->
info;
2544 Cmpnts ***ucont, ***uch, ***csi, ***eta, ***zet;
2547 ierr = DMDAVecGetArray(user->
fda, user->
lUcont, &ucont); CHKERRQ(ierr);
2548 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2549 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2550 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2551 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2552 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2554 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
2555 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
2556 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
2557 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
2558 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
2559 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2564 PetscInt i_face = (face_id ==
BC_FACE_NEG_X) ? info.xs : info.mx - 2;
2565 PetscInt i_nvert = (face_id ==
BC_FACE_NEG_X) ? info.xs + 1 : info.mx - 2;
2567 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++) {
2568 if (nvert[k][j][i_nvert] < 0.1) {
2569 PetscReal faceArea = sqrt(csi[k][j][i_face].x*csi[k][j][i_nvert].x + csi[k][j][i_nvert].y*csi[k][j][i_nvert].y + csi[k][j][i_face].z*csi[k][j][i_face].z);
2572 uch[k][j][i_face].
x = fluxTrim;
2578 PetscInt j_face = (face_id ==
BC_FACE_NEG_Y) ? info.ys : info.my - 2;
2579 PetscInt j_nvert = (face_id ==
BC_FACE_NEG_Y) ? info.ys + 1 : info.my - 2;
2581 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++) {
2582 if (nvert[k][j_nvert][i] < 0.1) {
2583 PetscReal faceArea = sqrt(eta[k][j_face][i].x*eta[k][j_face][i].x + eta[k][j_face][i].y*eta[k][j_face][i].y + eta[k][j_face][i].z*eta[k][j_face][i].z);
2586 uch[k][j_face][i].
y = fluxTrim;
2592 PetscInt k_face = (face_id ==
BC_FACE_NEG_Z) ? info.zs : info.mz - 2;
2593 PetscInt k_nvert = (face_id ==
BC_FACE_NEG_Z) ? info.zs + 1 : info.mz - 2;
2595 for (PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++) {
2596 if (nvert[k_nvert][j][i] < 0.1) {
2597 PetscReal faceArea = sqrt(zet[k_nvert][j][i].x*zet[k_nvert][j][i].x + zet[k_nvert][j][i].y*zet[k_nvert][j][i].y + zet[k_nvert][j][i].z*zet[k_nvert][j][i].z);
2600 uch[k_face][j][i].
z = fluxTrim;
2607 ierr = DMDAVecRestoreArray(user->
fda, user->
lUcont, &ucont); CHKERRQ(ierr);
2608 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2609 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2610 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2611 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2612 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2614 PetscFunctionReturn(0);
2618#define __FUNCT__ "Destroy_PeriodicDrivenConstant"
2625 PetscFunctionBeginUser;
2628 if (self && self->
data) {
2630 PetscFree(self->
data);
2639 PetscFunctionReturn(0);
PetscReal cs2_half
Half-width (in index space) in cross-stream direction 2.
static PetscErrorCode Initialize_InletProfileFromFile(BoundaryCondition *self, BCContext *ctx)
Initializes a file-prescribed inlet profile handler for one boundary face.
static PetscErrorCode Destroy_InletProfileFromFile(BoundaryCondition *self)
Releases private storage owned by a file-prescribed inlet profile handler.
PetscErrorCode Create_InletConstantVelocity(BoundaryCondition *bc)
Implementation of Create_InletConstantVelocity().
static PetscErrorCode Apply_WallNoSlip(BoundaryCondition *self, BCContext *ctx)
Internal helper implementation: Apply_WallNoSlip().
PetscBool applyBoundaryTrim
PetscErrorCode Create_InletProfileFromFile(BoundaryCondition *bc)
Implementation of Create_InletProfileFromFile().
static PetscErrorCode Initialize_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx)
Internal helper implementation: Initialize_InletParabolicProfile().
static PetscErrorCode GetProfileFileExpectedDims(UserCtx *user, BCFace face_id, PetscInt *n1, PetscInt *n2)
Computes the expected PICSLICE dimensions for an inlet face.
static PetscErrorCode PreStep_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Internal helper implementation: PreStep_InletConstantVelocity().
static PetscErrorCode PreStep_InletProfileFromFile(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Pre-step hook for the static file-prescribed inlet profile handler.
static PetscErrorCode Apply_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx)
Internal helper implementation: Apply_InletConstantVelocity().
PetscReal cs2_center
Center index in cross-stream direction 2.
static PetscErrorCode Apply_OutletConservation(BoundaryCondition *self, BCContext *ctx)
(Handler Action) Applies mass conservation correction to the outlet face.
static PetscErrorCode Apply_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx)
Internal helper implementation: Apply_InletParabolicProfile().
static PetscErrorCode PostStep_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Internal helper implementation: PostStep_InletParabolicProfile().
PetscReal targetVolumetricFlux
static PetscErrorCode ReadPicSliceProfile(const char *source_file, PetscInt expected_n1, PetscInt expected_n2, InletProfileFileData *data)
Reads and validates a static scalar inlet profile from a canonical PICSLICE file.
PetscBool isMasterController
static PetscErrorCode Apply_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx)
Internal helper implementation: Apply_PeriodicDrivenConstant().
static PetscErrorCode Initialize_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx)
Internal helper implementation: Initialize_PeriodicDrivenConstant().
PetscErrorCode Create_PeriodicGeometric(BoundaryCondition *bc)
Implementation of Create_PeriodicGeometric().
PetscReal v_max
Peak centerline velocity (from user params).
PetscErrorCode Validate_DrivenFlowConfiguration(UserCtx *user)
Internal helper implementation: Validate_DrivenFlowConfiguration().
PetscErrorCode Create_InletParabolicProfile(BoundaryCondition *bc)
Implementation of Create_InletParabolicProfile().
static PetscErrorCode Destroy_InletConstantVelocity(BoundaryCondition *self)
Internal helper implementation: Destroy_InletConstantVelocity().
static PetscErrorCode Destroy_PeriodicDrivenConstant(BoundaryCondition *self)
Internal helper implementation: Destroy_PeriodicDrivenConstant().
static PetscErrorCode PostStep_InletProfileFromFile(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Accumulates the applied inlet flux for a file-prescribed profile.
PetscErrorCode Create_PeriodicDrivenConstant(BoundaryCondition *bc)
Internal helper implementation: Create_PeriodicDrivenConstant().
static PetscErrorCode PreStep_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Internal helper implementation: PreStep_InletParabolicProfile().
static PetscErrorCode PostStep_OutletConservation(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Internal helper implementation: PostStep_OutletConservation().
PetscReal normal_velocity
static PetscReal ProfileSpeedAt(const InletProfileFileData *data, PetscInt a, PetscInt b)
Returns one scalar speed from the flattened PICSLICE profile.
static PetscErrorCode Destroy_InletParabolicProfile(BoundaryCondition *self)
Internal helper implementation: Destroy_InletParabolicProfile().
static PetscErrorCode Initialize_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx)
Internal helper implementation: Initialize_InletConstantVelocity().
PetscErrorCode Create_WallNoSlip(BoundaryCondition *bc)
Implementation of Create_WallNoSlip().
static PetscErrorCode Apply_InletProfileFromFile(BoundaryCondition *self, BCContext *ctx)
Applies the loaded PICSLICE scalar profile to Ucont and Ubcs on an inlet face.
static PetscErrorCode PreStep_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Internal helper implementation: PreStep_PeriodicDrivenConstant().
static PetscErrorCode PostStep_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Internal helper implementation: PostStep_InletConstantVelocity().
static PetscErrorCode PreStep_OutletConservation(BoundaryCondition *self, BCContext *ctx, PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution)
Internal helper implementation: PreStep_OutletConservation().
PetscReal boundaryVelocityCorrection
PetscErrorCode Create_OutletConservation(BoundaryCondition *bc)
Implementation of Create_OutletConservation().
static PetscErrorCode GetBCParamStringLocal(BC_Param *params, const char *key, const char **value_out, PetscBool *found)
Looks up a string-valued boundary-condition parameter in a BC_Param list.
PetscReal cs1_half
Half-width (in index space) in cross-stream direction 1.
PetscReal cs1_center
Center index in cross-stream direction 1.
Private data structure for the handler.
Private data structure for the Constant Velocity Inlet handler.
Private data structure for the Parabolic Velocity Inlet handler.
PetscErrorCode CanRankServiceFace(const DMDALocalInfo *info, PetscInt IM_nodes_global, PetscInt JM_nodes_global, PetscInt KM_nodes_global, BCFace face_id, PetscBool *can_service_out)
Determines if the current MPI rank owns any part of a specified global face.
PetscErrorCode CalculateFaceCenterAndArea(UserCtx *user, BCFace face_id, Cmpnts *face_center, PetscReal *face_area)
Calculates the geometric center and total area of a specified boundary face.
PetscErrorCode GetBCParamReal(BC_Param *params, const char *key, PetscReal *value_out, PetscBool *found)
Searches a BC_Param linked list for a key and returns its value as a double.
PetscErrorCode GetBCParamBool(BC_Param *params, const char *key, PetscBool *value_out, PetscBool *found)
Searches a BC_Param linked list for a key and returns its value as a bool.
#define LOCAL
Logging scope definitions for controlling message output.
#define GLOBAL
Scope for global logging across all processes.
const char * BCFaceToString(BCFace face)
Helper function to convert BCFace enum to a string representation.
#define LOG_ALLOW(scope, level, fmt,...)
Logging macro that checks both the log level and whether the calling function is in the allowed-funct...
#define PROFILE_FUNCTION_END
Marks the end of a profiled code block.
const char * BCTypeToString(BCType type)
Helper function to convert BCType enum to a string representation.
@ LOG_TRACE
Very fine-grained tracing information for in-depth debugging.
@ LOG_INFO
Informational messages about program execution.
@ LOG_WARNING
Non-critical issues that warrant attention.
@ LOG_DEBUG
Detailed debugging information.
#define PROFILE_FUNCTION_BEGIN
Marks the beginning of a profiled code block (typically a function).
The "virtual table" struct for a boundary condition handler object.
PetscErrorCode(* PostStep)(BoundaryCondition *self, BCContext *ctx, PetscReal *local_inflow, PetscReal *local_outflow)
PetscErrorCode(* PreStep)(BoundaryCondition *self, BCContext *ctx, PetscReal *local_inflow, PetscReal *local_outflow)
PetscErrorCode(* Destroy)(BoundaryCondition *self)
PetscErrorCode(* Initialize)(BoundaryCondition *self, BCContext *ctx)
PetscErrorCode(* UpdateUbcs)(BoundaryCondition *self, BCContext *ctx)
PetscErrorCode(* Apply)(BoundaryCondition *self, BCContext *ctx)
const PetscReal * global_outflow_sum
BCType
Defines the general mathematical/physical Category of a boundary.
BoundaryFaceConfig boundary_faces[6]
PetscReal targetVolumetricFlux
SimCtx * simCtx
Back-pointer to the master simulation context.
BCHandlerType
Defines the specific computational "strategy" for a boundary handler.
@ BC_HANDLER_PERIODIC_DRIVEN_INITIAL_FLUX
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
BCHandlerType handler_type
PetscReal bulkVelocityCorrection
Vec Ubcs
Physical Cartesian velocity at boundary faces. Full 3D array but only boundary-face entries are meani...
const PetscReal * global_inflow_sum
const PetscReal * global_farfield_inflow_sum
Vec Uch
Characteristic velocity for boundary conditions.
BCFace
Identifies the six logical faces of a structured computational block.
Provides execution context for a boundary condition handler.
A node in a linked list for storing key-value parameters from the bcs.dat file.
Holds the complete configuration for one of the six boundary faces.
A 3D point or vector with PetscScalar components.
The master context for the entire simulation.
User-defined context containing data specific to a single computational grid level.