10#define __FUNCT__ "Validate_DrivenFlowConfiguration"
29 PetscFunctionBeginUser;
32 PetscBool is_driven_flow_active = PETSC_FALSE;
33 char driven_direction =
' ';
34 const char* first_driven_face_name =
"";
36 for (
int i = 0; i < 6; i++) {
41 is_driven_flow_active = PETSC_TRUE;
44 if (i <= 1) driven_direction =
'X';
45 else if (i <= 3) driven_direction =
'Y';
46 else driven_direction =
'Z';
53 if (!is_driven_flow_active) {
54 PetscFunctionReturn(0);
57 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
" - Driven Flow Handler detected on face %s. Applying driven flow validation rules...\n", first_driven_face_name);
61 for (
int i = 0; i < 6; i++) {
64 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
65 "Configuration Error: A DRIVEN flow handler is active, which is incompatible with the %s boundary condition found on face %s.",
72 LOG_ALLOW(
GLOBAL,
LOG_DEBUG,
" - Validating symmetry and mathematical types for the '%c' direction...\n", driven_direction);
74 PetscInt neg_face_idx = 0, pos_face_idx = 0;
75 if (driven_direction ==
'X') {
77 }
else if (driven_direction ==
'Y') {
88 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
89 "Configuration Error: For a driven flow in the '%c' direction, both the %s and %s faces must be of mathematical_type PERIODIC.",
95 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
96 "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).",
102 PetscFunctionReturn(0);
119#define __FUNCT__ "Create_WallNoSlip"
134 PetscFunctionBeginUser;
136 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
137 "Input BoundaryCondition object is NULL in Create_WallNoSlip");
153 PetscFunctionReturn(0);
157#define __FUNCT__ "Apply_WallNoSlip"
177 PetscBool can_service;
181 PetscFunctionBeginUser;
182 DMDALocalInfo *info = &user->
info;
184 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
186 IM_nodes_global = user->
IM;
187 JM_nodes_global = user->
JM;
188 KM_nodes_global = user->
KM;
190 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
192 if (!can_service) PetscFunctionReturn(0);
199 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
200 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
202 PetscInt xs = info->xs, xe = info->xs + info->xm;
203 PetscInt ys = info->ys, ye = info->ys + info->ym;
204 PetscInt zs = info->zs, ze = info->zs + info->zm;
205 PetscInt mx = info->mx, my = info->my, mz = info->mz;
208 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
209 if (xs == 0) lxs = xs + 1;
210 if (xe == mx) lxe = xe - 1;
211 if (ys == 0) lys = ys + 1;
212 if (ye == my) lye = ye - 1;
213 if (zs == 0) lzs = zs + 1;
214 if (ze == mz) lze = ze - 1;
220 for (PetscInt k = lzs; k < lze; k++) {
221 for (PetscInt j = lys; j < lye; j++) {
223 ucont[k][j][i].
x = 0.0;
226 ubcs[k][j][i].
x = 0.0;
227 ubcs[k][j][i].
y = 0.0;
228 ubcs[k][j][i].
z = 0.0;
238 for (PetscInt k = lzs; k < lze; k++) {
239 for (PetscInt j = lys; j < lye; j++) {
240 ucont[k][j][i-1].
x = 0.0;
242 ubcs[k][j][i].
x = 0.0;
243 ubcs[k][j][i].
y = 0.0;
244 ubcs[k][j][i].
z = 0.0;
253 for (PetscInt k = lzs; k < lze; k++) {
254 for (PetscInt i = lxs; i < lxe; i++) {
255 ucont[k][j][i].
y = 0.0;
257 ubcs[k][j][i].
x = 0.0;
258 ubcs[k][j][i].
y = 0.0;
259 ubcs[k][j][i].
z = 0.0;
268 for (PetscInt k = lzs; k < lze; k++) {
269 for (PetscInt i = lxs; i < lxe; i++) {
270 ucont[k][j-1][i].
y = 0.0;
272 ubcs[k][j][i].
x = 0.0;
273 ubcs[k][j][i].
y = 0.0;
274 ubcs[k][j][i].
z = 0.0;
283 for (PetscInt j = lys; j < lye; j++) {
284 for (PetscInt i = lxs; i < lxe; i++) {
285 ucont[k][j][i].
z = 0.0;
287 ubcs[k][j][i].
x = 0.0;
288 ubcs[k][j][i].
y = 0.0;
289 ubcs[k][j][i].
z = 0.0;
298 for (PetscInt j = lys; j < lye; j++) {
299 for (PetscInt i = lxs; i < lxe; i++) {
300 ucont[k-1][j][i].
z = 0.0;
302 ubcs[k][j][i].
x = 0.0;
303 ubcs[k][j][i].
y = 0.0;
304 ubcs[k][j][i].
z = 0.0;
312 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
313 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
315 PetscFunctionReturn(0);
330 PetscReal *in, PetscReal *out);
333 PetscReal *in, PetscReal *out);
344#define __FUNCT__ "Create_InletConstantVelocity"
351 PetscFunctionBeginUser;
353 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
356 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
357 bc->
data = (
void*)data;
367 PetscFunctionReturn(0);
372#define __FUNCT__ "Initialize_InletConstantVelocity"
388 PetscFunctionBeginUser;
389 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Initialize_InletConstantVelocity: Initializing handler for Face %d. \n", face_id);
421 PetscFunctionReturn(0);
425#define __FUNCT__ "PreStep_InletConstantVelocity"
437 PetscReal *local_inflow_contribution,
438 PetscReal *local_outflow_contribution)
446 (void)local_inflow_contribution;
447 (void)local_outflow_contribution;
449 PetscFunctionBeginUser;
450 PetscFunctionReturn(0);
454#define __FUNCT__ "Apply_InletConstantVelocity"
471 PetscBool can_service;
473 PetscFunctionBeginUser;
475 DMDALocalInfo *info = &user->
info;
476 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
478 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
480 IM_nodes_global = user->
IM;
481 JM_nodes_global = user->
JM;
482 KM_nodes_global = user->
KM;
484 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
486 if (!can_service) PetscFunctionReturn(0);
490 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
491 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
492 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
493 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
494 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
495 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
500 PetscInt xs = info->xs, xe = info->xs + info->xm;
501 PetscInt ys = info->ys, ye = info->ys + info->ym;
502 PetscInt zs = info->zs, ze = info->zs + info->zm;
503 PetscInt mx = info->mx, my = info->my, mz = info->mz;
505 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
506 if (xs == 0) lxs = xs + 1;
507 if (xe == mx) lxe = xe - 1;
508 if (ys == 0) lys = ys + 1;
509 if (ye == my) lye = ye - 1;
510 if (zs == 0) lzs = zs + 1;
511 if (ze == mz) lze = ze - 1;
519 for (PetscInt k = lzs; k < lze; k++) {
520 for (PetscInt j = lys; j < lye; j++) {
521 if ((
sign > 0 && nvert[k][j][i+1] > 0.1) ||
522 (
sign < 0 && nvert[k][j][i] > 0.1))
continue;
524 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
525 csi[k][j][i].y * csi[k][j][i].y +
526 csi[k][j][i].z * csi[k][j][i].z);
528 ucont[k][j][i].
x =
sign * uin_this_point * CellArea;
530 ubcs[k][j][i + (
sign < 0)].x =
sign * uin_this_point * csi[k][j][i].x / CellArea;
531 ubcs[k][j][i + (
sign < 0)].y =
sign * uin_this_point * csi[k][j][i].y / CellArea;
532 ubcs[k][j][i + (
sign < 0)].z =
sign * uin_this_point * csi[k][j][i].z / CellArea;
542 for (PetscInt k = lzs; k < lze; k++) {
543 for (PetscInt i = lxs; i < lxe; i++) {
544 if ((
sign > 0 && nvert[k][j+1][i] > 0.1) ||
545 (
sign < 0 && nvert[k][j][i] > 0.1))
continue;
547 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
548 eta[k][j][i].y * eta[k][j][i].y +
549 eta[k][j][i].z * eta[k][j][i].z);
551 ucont[k][j][i].
y =
sign * uin_this_point * CellArea;
553 ubcs[k][j + (
sign < 0)][i].x =
sign * uin_this_point * eta[k][j][i].x / CellArea;
554 ubcs[k][j + (
sign < 0)][i].y =
sign * uin_this_point * eta[k][j][i].y / CellArea;
555 ubcs[k][j + (
sign < 0)][i].z =
sign * uin_this_point * eta[k][j][i].z / CellArea;
565 for (PetscInt j = lys; j < lye; j++) {
566 for (PetscInt i = lxs; i < lxe; i++) {
567 if ((
sign > 0 && nvert[k+1][j][i] > 0.1) ||
568 (
sign < 0 && nvert[k][j][i] > 0.1))
continue;
570 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
571 zet[k][j][i].y * zet[k][j][i].y +
572 zet[k][j][i].z * zet[k][j][i].z);
574 ucont[k][j][i].
z =
sign * uin_this_point * CellArea;
576 ubcs[k + (
sign < 0)][j][i].x =
sign * uin_this_point * zet[k][j][i].x / CellArea;
577 ubcs[k + (
sign < 0)][j][i].y =
sign * uin_this_point * zet[k][j][i].y / CellArea;
578 ubcs[k + (
sign < 0)][j][i].z =
sign * uin_this_point * zet[k][j][i].z / CellArea;
585 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
586 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
587 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
588 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
589 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
590 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
592 PetscFunctionReturn(0);
596#define __FUNCT__ "PostStep_InletConstantVelocity"
601 PetscReal *local_inflow_contribution,
602 PetscReal *local_outflow_contribution)
607 PetscBool can_service;
610 (void)local_outflow_contribution;
612 PetscFunctionBeginUser;
614 DMDALocalInfo *info = &user->
info;
617 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
619 IM_nodes_global = user->
IM;
620 JM_nodes_global = user->
JM;
621 KM_nodes_global = user->
KM;
623 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
626 if (!can_service) PetscFunctionReturn(0);
628 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
630 PetscReal local_flux = 0.0;
632 PetscInt xs = info->xs, xe = info->xs + info->xm;
633 PetscInt ys = info->ys, ye = info->ys + info->ym;
634 PetscInt zs = info->zs, ze = info->zs + info->zm;
635 PetscInt mx = info->mx, my = info->my, mz = info->mz;
637 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
638 if (xs == 0) lxs = xs + 1;
639 if (xe == mx) lxe = xe - 1;
640 if (ys == 0) lys = ys + 1;
641 if (ye == my) lye = ye - 1;
642 if (zs == 0) lzs = zs + 1;
643 if (ze == mz) lze = ze - 1;
650 for (PetscInt k = lzs; k < lze; k++) {
651 for (PetscInt j = lys; j < lye; j++) {
652 local_flux += ucont[k][j][i].
x;
660 for (PetscInt k = lzs; k < lze; k++) {
661 for (PetscInt i = lxs; i < lxe; i++) {
662 local_flux += ucont[k][j][i].
y;
670 for (PetscInt j = lys; j < lye; j++) {
671 for (PetscInt i = lxs; i < lxe; i++) {
672 local_flux += ucont[k][j][i].
z;
678 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
680 *local_inflow_contribution += local_flux;
683 face_id, local_flux);
685 PetscFunctionReturn(0);
690#define __FUNCT__ "Destroy_InletConstantVelocity"
696 PetscFunctionBeginUser;
697 if (self && self->
data) {
698 PetscFree(self->
data);
701 PetscFunctionReturn(0);
731 PetscReal *in, PetscReal *out);
734 PetscReal *in, PetscReal *out);
752#define __FUNCT__ "Create_InletParabolicProfile"
765 PetscFunctionBeginUser;
767 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
770 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
771 bc->
data = (
void*)data;
781 PetscFunctionReturn(0);
786#define __FUNCT__ "Initialize_InletParabolicProfile"
811 PetscFunctionBeginUser;
817 &data->
v_max, &found); CHKERRQ(ierr);
819 LOG_ALLOW(
GLOBAL,
LOG_WARNING,
"Initialize_InletParabolicProfile: 'v_max' not found in params for face %d. Defaulting to 0.0.\n", face_id);
823 PetscReal cs1_dim, cs2_dim;
827 cs1_dim = (PetscReal)user->
JM;
828 cs2_dim = (PetscReal)user->
KM;
832 cs1_dim = (PetscReal)user->
IM;
833 cs2_dim = (PetscReal)user->
KM;
838 cs1_dim = (PetscReal)user->
IM;
839 cs2_dim = (PetscReal)user->
JM;
844 PetscReal cs1_width = cs1_dim - 2.0;
845 PetscReal cs2_width = cs2_dim - 2.0;
859 PetscFunctionReturn(0);
864#define __FUNCT__ "PreStep_InletParabolicProfile"
872 PetscReal *local_inflow_contribution,
873 PetscReal *local_outflow_contribution)
877 (void)local_inflow_contribution;
878 (void)local_outflow_contribution;
880 PetscFunctionBeginUser;
881 PetscFunctionReturn(0);
886#define __FUNCT__ "Apply_InletParabolicProfile"
908 PetscBool can_service;
910 PetscFunctionBeginUser;
912 DMDALocalInfo *info = &user->
info;
913 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
915 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
917 IM_nodes_global = user->
IM;
918 JM_nodes_global = user->
JM;
919 KM_nodes_global = user->
KM;
922 face_id, &can_service); CHKERRQ(ierr);
924 if (!can_service) PetscFunctionReturn(0);
927 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
928 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
929 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
930 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
931 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
932 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
934 PetscInt xs = info->xs, xe = info->xs + info->xm;
935 PetscInt ys = info->ys, ye = info->ys + info->ym;
936 PetscInt zs = info->zs, ze = info->zs + info->zm;
937 PetscInt mx = info->mx, my = info->my, mz = info->mz;
939 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
940 if (xs == 0) lxs = xs + 1;
941 if (xe == mx) lxe = xe - 1;
942 if (ys == 0) lys = ys + 1;
943 if (ye == my) lye = ye - 1;
944 if (zs == 0) lzs = zs + 1;
945 if (ze == mz) lze = ze - 1;
954 for (PetscInt k = lzs; k < lze; k++) {
955 for (PetscInt j = lys; j < lye; j++) {
956 if ((
sign > 0 && nvert[k][j][i+1] > 0.1) ||
957 (
sign < 0 && nvert[k][j][i] > 0.1))
continue;
962 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
963 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
964 PetscReal uin_local = data->
v_max * profile;
966 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
967 csi[k][j][i].y * csi[k][j][i].y +
968 csi[k][j][i].z * csi[k][j][i].z);
970 ucont[k][j][i].
x =
sign * uin_local * CellArea;
972 ubcs[k][j][i + (
sign < 0)].x =
sign * uin_local * csi[k][j][i].x / CellArea;
973 ubcs[k][j][i + (
sign < 0)].y =
sign * uin_local * csi[k][j][i].y / CellArea;
974 ubcs[k][j][i + (
sign < 0)].z =
sign * uin_local * csi[k][j][i].z / CellArea;
985 for (PetscInt k = lzs; k < lze; k++) {
986 for (PetscInt i = lxs; i < lxe; i++) {
987 if ((
sign > 0 && nvert[k][j+1][i] > 0.1) ||
988 (
sign < 0 && nvert[k][j][i] > 0.1))
continue;
993 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
994 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
995 PetscReal uin_local = data->
v_max * profile;
997 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
998 eta[k][j][i].y * eta[k][j][i].y +
999 eta[k][j][i].z * eta[k][j][i].z);
1001 ucont[k][j][i].
y =
sign * uin_local * CellArea;
1003 ubcs[k][j + (
sign < 0)][i].x =
sign * uin_local * eta[k][j][i].x / CellArea;
1004 ubcs[k][j + (
sign < 0)][i].y =
sign * uin_local * eta[k][j][i].y / CellArea;
1005 ubcs[k][j + (
sign < 0)][i].z =
sign * uin_local * eta[k][j][i].z / CellArea;
1016 for (PetscInt j = lys; j < lye; j++) {
1017 for (PetscInt i = lxs; i < lxe; i++) {
1018 if ((
sign > 0 && nvert[k+1][j][i] > 0.1) ||
1019 (
sign < 0 && nvert[k][j][i] > 0.1))
continue;
1024 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
1025 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
1026 PetscReal uin_local = data->
v_max * profile;
1028 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
1029 zet[k][j][i].y * zet[k][j][i].y +
1030 zet[k][j][i].z * zet[k][j][i].z);
1032 ucont[k][j][i].
z =
sign * uin_local * CellArea;
1034 ubcs[k + (
sign < 0)][j][i].x =
sign * uin_local * zet[k][j][i].x / CellArea;
1035 ubcs[k + (
sign < 0)][j][i].y =
sign * uin_local * zet[k][j][i].y / CellArea;
1036 ubcs[k + (
sign < 0)][j][i].z =
sign * uin_local * zet[k][j][i].z / CellArea;
1043 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1044 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1045 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1046 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1047 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1048 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1050 PetscFunctionReturn(0);
1055#define __FUNCT__ "PostStep_InletParabolicProfile"
1065 PetscReal *local_inflow_contribution,
1066 PetscReal *local_outflow_contribution)
1068 PetscErrorCode ierr;
1071 PetscBool can_service;
1074 (void)local_outflow_contribution;
1076 PetscFunctionBeginUser;
1078 DMDALocalInfo *info = &user->
info;
1081 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
1083 IM_nodes_global = user->
IM;
1084 JM_nodes_global = user->
JM;
1085 KM_nodes_global = user->
KM;
1088 face_id, &can_service); CHKERRQ(ierr);
1090 if (!can_service) PetscFunctionReturn(0);
1092 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1094 PetscReal local_flux = 0.0;
1096 PetscInt xs = info->xs, xe = info->xs + info->xm;
1097 PetscInt ys = info->ys, ye = info->ys + info->ym;
1098 PetscInt zs = info->zs, ze = info->zs + info->zm;
1099 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1101 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1102 if (xs == 0) lxs = xs + 1;
1103 if (xe == mx) lxe = xe - 1;
1104 if (ys == 0) lys = ys + 1;
1105 if (ye == my) lye = ye - 1;
1106 if (zs == 0) lzs = zs + 1;
1107 if (ze == mz) lze = ze - 1;
1113 for (PetscInt k = lzs; k < lze; k++) {
1114 for (PetscInt j = lys; j < lye; j++) {
1115 local_flux += ucont[k][j][i].
x;
1123 for (PetscInt k = lzs; k < lze; k++) {
1124 for (PetscInt i = lxs; i < lxe; i++) {
1125 local_flux += ucont[k][j][i].
y;
1133 for (PetscInt j = lys; j < lye; j++) {
1134 for (PetscInt i = lxs; i < lxe; i++) {
1135 local_flux += ucont[k][j][i].
z;
1141 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1143 *local_inflow_contribution += local_flux;
1146 face_id, local_flux);
1148 PetscFunctionReturn(0);
1153#define __FUNCT__ "Destroy_InletParabolicProfile"
1159 PetscFunctionBeginUser;
1160 if (self && self->
data) {
1161 PetscFree(self->
data);
1164 PetscFunctionReturn(0);
1185 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution);
1188 PetscReal *in, PetscReal *out);
1191#define __FUNCT__ "Create_OutletConservation"
1197 PetscFunctionBeginUser;
1199 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
1215 PetscFunctionReturn(0);
1219#define __FUNCT__ "PreStep_OutletConservation"
1249 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution)
1251 PetscErrorCode ierr;
1254 DMDALocalInfo* info = &user->
info;
1255 PetscBool can_service;
1259 (void)local_inflow_contribution;
1261 PetscFunctionBeginUser;
1265 const PetscInt IM_nodes_global = user->
IM;
1266 const PetscInt JM_nodes_global = user->
JM;
1267 const PetscInt KM_nodes_global = user->
KM;
1268 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1271 PetscFunctionReturn(0);
1277 Cmpnts ***ucat, ***csi, ***eta, ***zet;
1279 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1280 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1281 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1282 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1283 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1285 PetscReal local_flux_out = 0.0;
1286 const PetscInt xs=info->xs, xe=info->xs+info->xm;
1287 const PetscInt ys=info->ys, ye=info->ys+info->ym;
1288 const PetscInt zs=info->zs, ze=info->zs+info->zm;
1289 const PetscInt mx=info->mx, my=info->my, mz=info->mz;
1292 PetscInt lxs = xs;
if (xs == 0) lxs = xs + 1;
1293 PetscInt lxe = xe;
if (xe == mx) lxe = xe - 1;
1294 PetscInt lys = ys;
if (ys == 0) lys = ys + 1;
1295 PetscInt lye = ye;
if (ye == my) lye = ye - 1;
1296 PetscInt lzs = zs;
if (zs == 0) lzs = zs + 1;
1297 PetscInt lze = ze;
if (ze == mz) lze = ze - 1;
1302 const PetscInt i_cell = xs + 1;
1303 const PetscInt i_face = xs;
1304 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1305 if (nvert[k][j][i_cell] < 0.1) {
1306 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);
1312 const PetscInt i_cell = xe - 2;
1313 const PetscInt i_face = xe - 2;
1314 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1315 if (nvert[k][j][i_cell] < 0.1) {
1316 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);
1322 const PetscInt j_cell = ys + 1;
1323 const PetscInt j_face = ys;
1324 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1325 if (nvert[k][j_cell][i] < 0.1) {
1326 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);
1332 const PetscInt j_cell = ye - 2;
1333 const PetscInt j_face = ye - 2;
1334 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1335 if (nvert[k][j_cell][i] < 0.1) {
1336 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);
1342 const PetscInt k_cell = zs + 1;
1343 const PetscInt k_face = zs;
1344 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1345 if (nvert[k_cell][j][i] < 0.1) {
1346 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);
1352 const PetscInt k_cell = ze - 2;
1353 const PetscInt k_face = ze - 2;
1354 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1355 if (nvert[k_cell][j][i] < 0.1) {
1356 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);
1364 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1365 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1366 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1367 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1368 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1371 *local_outflow_contribution += local_flux_out;
1373 PetscFunctionReturn(0);
1377#define __FUNCT__ "Apply_OutletConservation"
1383static PetscErrorCode Apply_OutletConservation(BoundaryCondition *self, BCContext *ctx)
1385 PetscErrorCode ierr;
1387 BCFace face_id = ctx->face_id;
1388 DMDALocalInfo* info = &user->
info;
1389 PetscBool can_service;
1391 PetscFunctionBeginUser;
1394 const PetscInt IM_nodes_global = user->
IM;
1395 const PetscInt JM_nodes_global = user->
JM;
1396 const PetscInt KM_nodes_global = user->
KM;
1397 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1401 PetscFunctionReturn(0);
1405 PetscReal total_inflow = *ctx->global_inflow_sum + *ctx->global_farfield_inflow_sum;
1406 PetscReal flux_imbalance = total_inflow - *ctx->global_outflow_sum;
1409 PetscReal velocity_correction = (PetscAbsReal(user->
simCtx->
AreaOutSum) > 1e-12)
1420 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet, ***ucat;
1422 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1423 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1424 ierr = DMDAVecGetArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1425 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1426 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1427 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1428 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1431 PetscInt xs = info->xs, xe = info->xs + info->xm;
1432 PetscInt ys = info->ys, ye = info->ys + info->ym;
1433 PetscInt zs = info->zs, ze = info->zs + info->zm;
1434 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1435 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1437 if (xs == 0) lxs = xs + 1;
1438 if (xe == mx) lxe = xe - 1;
1439 if (ys == 0) lys = ys + 1;
1440 if (ye == my) lye = ye - 1;
1441 if (zs == 0) lzs = zs + 1;
1442 if (ze == mz) lze = ze - 1;
1447 const PetscInt i_cell = xs + 1;
1448 const PetscInt i_face = xs;
1449 const PetscInt i_dummy = xs;
1450 for (PetscInt k = lzs; k < lze; k++) {
1451 for (PetscInt j = lys; j < lye; j++) {
1452 if (nvert[k][j][i_cell] < 0.1) {
1454 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1457 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);
1459 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));
1461 PetscReal Correction_flux = velocity_correction*Cell_Area;
1463 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1470 const PetscInt i_cell = xe - 2;
1471 const PetscInt i_face = xe - 2;
1472 const PetscInt i_dummy = xe - 1;
1473 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++){
1474 if(nvert[k][j][i_cell]<0.1){
1476 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1479 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);
1481 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));
1483 PetscReal Correction_flux = velocity_correction*Cell_Area;
1485 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1491 const PetscInt j_cell = ys + 1;
1492 const PetscInt j_face = ys;
1493 const PetscInt j_dummy = ys;
1494 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1495 if(nvert[k][j_cell][i]<0.1){
1497 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1500 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);
1502 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));
1504 PetscReal Correction_flux = velocity_correction*Cell_Area;
1506 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1512 const PetscInt j_cell = ye - 2;
1513 const PetscInt j_face = ye - 2;
1514 const PetscInt j_dummy = ye - 1;
1515 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1516 if(nvert[k][j_cell][i]<0.1){
1518 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1521 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);
1523 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));
1525 PetscReal Correction_flux = velocity_correction*Cell_Area;
1527 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1533 const PetscInt k_cell = zs + 1;
1534 const PetscInt k_face = zs;
1535 const PetscInt k_dummy = zs;
1536 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1537 if(nvert[k_cell][j][i]<0.1){
1539 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
1542 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));
1544 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));
1546 PetscReal Correction_flux = velocity_correction*Cell_Area;
1548 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
1554 const PetscInt k_cell = ze - 2;
1555 const PetscInt k_face = ze - 2;
1556 const PetscInt k_dummy = ze - 1;
1557 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1558 if(nvert[k_cell][j][i]<0.1){
1560 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
1563 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));
1565 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));
1567 PetscReal Correction_flux = velocity_correction*Cell_Area;
1569 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
1577 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1578 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1579 ierr = DMDAVecRestoreArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1580 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1581 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1582 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1583 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1586 PetscFunctionReturn(0);
1590#define __FUNCT__ "PostStep_OutletConservation"
1599 PetscReal *local_inflow_contribution,
1600 PetscReal *local_outflow_contribution)
1602 PetscErrorCode ierr;
1605 DMDALocalInfo* info = &user->
info;
1606 PetscBool can_service;
1609 (void)local_inflow_contribution;
1611 PetscFunctionBeginUser;
1612 const PetscInt IM_nodes_global = user->
IM;
1613 const PetscInt JM_nodes_global = user->
JM;
1614 const PetscInt KM_nodes_global = user->
KM;
1615 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1617 if (!can_service) PetscFunctionReturn(0);
1623 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1624 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1626 PetscReal local_flux = 0.0;
1628 PetscInt xs = info->xs, xe = info->xs + info->xm;
1629 PetscInt ys = info->ys, ye = info->ys + info->ym;
1630 PetscInt zs = info->zs, ze = info->zs + info->zm;
1631 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1633 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1634 if (xs == 0) lxs = xs + 1;
1635 if (xe == mx) lxe = xe - 1;
1636 if (ys == 0) lys = ys + 1;
1637 if (ye == my) lye = ye - 1;
1638 if (zs == 0) lzs = zs + 1;
1639 if (ze == mz) lze = ze - 1;
1644 const PetscInt i_cell = xs + 1;
1645 const PetscInt i_face = xs;
1646 for (PetscInt k = lzs; k < lze; k++) {
1647 for (PetscInt j = lys; j < lye; j++) {
1648 if (nvert[k][j][i_cell] < 0.1) {
1649 local_flux += ucont[k][j][i_face].
x;
1656 const PetscInt i_cell = xe - 2;
1657 const PetscInt i_face = xe - 2;
1658 for (PetscInt k = lzs; k < lze; k++) {
1659 for (PetscInt j = lys; j < lye; j++) {
1660 if (nvert[k][j][i_cell] < 0.1) {
1661 local_flux += ucont[k][j][i_face].
x;
1668 const PetscInt j_cell = ys + 1;
1669 const PetscInt j_face = ys;
1670 for (PetscInt k = lzs; k < lze; k++) {
1671 for (PetscInt i = lxs; i < lxe; i++) {
1672 if (nvert[k][j_cell][i] < 0.1) {
1673 local_flux += ucont[k][j_face][i].
y;
1680 const PetscInt j_cell = ye - 2;
1681 const PetscInt j_face = ye - 2;
1682 for (PetscInt k = lzs; k < lze; k++) {
1683 for (PetscInt i = lxs; i < lxe; i++) {
1684 if (nvert[k][j_cell][i] < 0.1) {
1685 local_flux += ucont[k][j_face][i].
y;
1692 const PetscInt k_cell = zs + 1;
1693 const PetscInt k_face = zs;
1694 for (PetscInt j = lys; j < lye; j++) {
1695 for (PetscInt i = lxs; i < lxe; i++) {
1696 if (nvert[k_cell][j][i] < 0.1) {
1697 local_flux += ucont[k_face][j][i].
z;
1704 const PetscInt k_cell = ze - 2;
1705 const PetscInt k_face = ze - 2;
1706 for (PetscInt j = lys; j < lye; j++) {
1707 for (PetscInt i = lxs; i < lxe; i++) {
1708 if (nvert[k_cell][j][i] < 0.1) {
1709 local_flux += ucont[k_face][j][i].
z;
1717 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1718 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1721 *local_outflow_contribution += local_flux;
1724 face_id, local_flux);
1726 PetscFunctionReturn(0);
1734 PetscFunctionBeginUser;
1736 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
1749 PetscFunctionReturn(0);
1781#define __FUNCT__ "Create_PeriodicDrivenConstant"
1801 PetscErrorCode ierr;
1802 PetscFunctionBeginUser;
1804 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition object is NULL in Create_PeriodicDrivenConstantFlux");
1808 ierr = PetscNew(&data); CHKERRQ(ierr);
1817 bc->
data = (
void*)data;
1834 PetscFunctionReturn(0);
1838#define __FUNCT__ "Initialize_PeriodicDrivenConstant"
1865 PetscErrorCode ierr;
1870 PetscFunctionBeginUser;
1876 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
1877 "Configuration Error: Handler PERIODIC_DRIVEN_CONSTANT_FLUX on Face %s must be applied to a face with mathematical_type PERIODIC.",
1902 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
1903 "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).",
1915 PetscBool trimfound;
1922 PetscFunctionReturn(0);
1926#define __FUNCT__ "PreStep_PeriodicDrivenConstant"
1955 PetscReal *local_inflow_contribution,
1956 PetscReal *local_outflow_contribution)
1958 PetscErrorCode ierr;
1963 PetscFunctionBeginUser;
1967 PetscFunctionReturn(0);
1972 DMDALocalInfo info = user->
info;
1978 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1979 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1982 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
1983 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
1984 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
1985 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
1986 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
1987 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2043 PetscReal localCurrentBoundaryFlux = 0.0;
2044 PetscReal localAveragePlanarVolumetricFluxTerm = 0.0;
2047 switch (direction) {
2051 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2052 if (nvert[k][j][i + 1] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
x;
2055 for (i = info.xs; i < lxe; i++) {
2056 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2057 if (nvert[k][j][i + 1] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
x / (PetscReal)(info.mx - 1);
2064 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2065 if (nvert[k][j + 1][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
y;
2068 for (j = info.ys; j < lye; j++) {
2069 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2070 if (nvert[k][j + 1][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
y / (PetscReal)(info.my - 1);
2077 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2078 if (nvert[k + 1][j][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
z;
2081 for (k = info.zs; k < lze; k++) {
2082 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2083 if (nvert[k + 1][j][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
z / (PetscReal)(info.mz - 1);
2090 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2091 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2095 PetscReal globalBoundaryArea;
2100 PetscReal globalCurrentBoundaryFlux, globalAveragePlanarVolumetricFlux;
2101 ierr = MPI_Allreduce(&localCurrentBoundaryFlux, &globalCurrentBoundaryFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2102 ierr = MPI_Allreduce(&localAveragePlanarVolumetricFluxTerm, &globalAveragePlanarVolumetricFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2105 if (globalBoundaryArea > 1.0e-12) {
2118 LOG_ALLOW(
GLOBAL,
LOG_INFO,
" - Avg Planar Volumetric Flux (Stable): %.6e\n", globalAveragePlanarVolumetricFlux);
2124 (void)local_inflow_contribution;
2125 (void)local_outflow_contribution;
2127 PetscFunctionReturn(0);
2131#define __FUNCT__ "Apply_PeriodicDrivenConstant"
2153 PetscErrorCode ierr;
2157 PetscBool can_service;
2159 PetscFunctionBeginUser;
2164 PetscFunctionReturn(0);
2169 PetscFunctionReturn(0);
2175 DMDALocalInfo info = user->
info;
2176 Cmpnts ***ucont, ***uch, ***csi, ***eta, ***zet;
2179 ierr = DMDAVecGetArray(user->
fda, user->
lUcont, &ucont); CHKERRQ(ierr);
2180 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2181 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2182 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2183 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2184 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2186 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
2187 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
2188 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
2189 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
2190 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
2191 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2196 PetscInt i_face = (face_id ==
BC_FACE_NEG_X) ? info.xs : info.mx - 2;
2197 PetscInt i_nvert = (face_id ==
BC_FACE_NEG_X) ? info.xs + 1 : info.mx - 2;
2199 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++) {
2200 if (nvert[k][j][i_nvert] < 0.1) {
2201 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);
2204 uch[k][j][i_face].
x = fluxTrim;
2210 PetscInt j_face = (face_id ==
BC_FACE_NEG_Y) ? info.ys : info.my - 2;
2211 PetscInt j_nvert = (face_id ==
BC_FACE_NEG_Y) ? info.ys + 1 : info.my - 2;
2213 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++) {
2214 if (nvert[k][j_nvert][i] < 0.1) {
2215 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);
2218 uch[k][j_face][i].
y = fluxTrim;
2224 PetscInt k_face = (face_id ==
BC_FACE_NEG_Z) ? info.zs : info.mz - 2;
2225 PetscInt k_nvert = (face_id ==
BC_FACE_NEG_Z) ? info.zs + 1 : info.mz - 2;
2227 for (PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++) {
2228 if (nvert[k_nvert][j][i] < 0.1) {
2229 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);
2232 uch[k_face][j][i].
z = fluxTrim;
2239 ierr = DMDAVecRestoreArray(user->
fda, user->
lUcont, &ucont); CHKERRQ(ierr);
2240 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2241 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2242 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2243 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2244 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2246 PetscFunctionReturn(0);
2250#define __FUNCT__ "Destroy_PeriodicDrivenConstant"
2265 PetscFunctionBeginUser;
2268 if (self && self->
data) {
2270 PetscFree(self->
data);
2279 PetscFunctionReturn(0);
PetscReal cs2_half
Half-width (in index space) in cross-stream direction 2.
PetscErrorCode Create_InletConstantVelocity(BoundaryCondition *bc)
Configures a BoundaryCondition object to behave as a constant velocity inlet.
static PetscErrorCode Apply_WallNoSlip(BoundaryCondition *self, BCContext *ctx)
(Handler Action) Applies the no-slip wall condition to a specified face.
PetscBool applyBoundaryTrim
static PetscErrorCode Initialize_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx)
(Handler Action) Initializes the parabolic inlet handler.
static PetscErrorCode PreStep_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
(Handler PreStep) No preparation needed for constant velocity inlet.
static PetscErrorCode Apply_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx)
(Handler Action) Applies the constant velocity inlet condition.
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)
(Handler Action) Applies the parabolic velocity inlet condition.
static PetscErrorCode PostStep_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
(Handler PostStep) Measures actual inflow flux through the parabolic inlet face.
PetscReal targetVolumetricFlux
PetscBool isMasterController
static PetscErrorCode Apply_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx)
(Handler Apply) Applies the immediate "Boundary Trim" velocity correction to the periodic face.
static PetscErrorCode Initialize_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx)
(Handler Initialize) Initializes the handler by validating its configuration and parsing parameters.
PetscErrorCode Create_PeriodicGeometric(BoundaryCondition *bc)
PetscReal v_max
Peak centerline velocity (from user params).
PetscErrorCode Validate_DrivenFlowConfiguration(UserCtx *user)
(Private) Validates all consistency rules for a driven flow (channel/pipe) setup.
PetscErrorCode Create_InletParabolicProfile(BoundaryCondition *bc)
(Handler Constructor) Populates a BoundaryCondition object with Parabolic Inlet behavior.
static PetscErrorCode Destroy_InletConstantVelocity(BoundaryCondition *self)
(Handler Destructor) Frees memory for the Constant Velocity Inlet.
static PetscErrorCode Destroy_PeriodicDrivenConstant(BoundaryCondition *self)
(Handler Destructor) Frees the memory allocated for the handler's private data.
PetscErrorCode Create_PeriodicDrivenConstant(BoundaryCondition *bc)
(Handler Constructor) Creates and configures a BoundaryCondition object for a driven periodic flow wi...
static PetscErrorCode PreStep_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
(Handler PreStep) No preparation needed for parabolic inlet.
static PetscErrorCode PostStep_OutletConservation(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
(Handler PostStep) Measures corrected outflow flux for verification.
PetscReal normal_velocity
static PetscErrorCode Destroy_InletParabolicProfile(BoundaryCondition *self)
(Handler Destructor) Frees memory for the Parabolic Velocity Inlet.
static PetscErrorCode Initialize_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx)
(Handler Action) Initializes the constant velocity inlet handler.
PetscErrorCode Create_WallNoSlip(BoundaryCondition *bc)
(Handler Constructor) Populates a BoundaryCondition object with No-Slip Wall behavior.
static PetscErrorCode PreStep_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
(Handler PreStep) Measures current fluxes and calculates the correction terms for the timestep.
static PetscErrorCode PostStep_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
(Handler PostStep) Measures actual inflow flux through the constant velocity inlet face.
static PetscErrorCode PreStep_OutletConservation(BoundaryCondition *self, BCContext *ctx, PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution)
(Handler Action) Measures the current, uncorrected flux passing through a SINGLE outlet face.
PetscReal boundaryVelocityCorrection
PetscErrorCode Create_OutletConservation(BoundaryCondition *bc)
(Handler Constructor) Populates a BoundaryCondition object with Outlet Conservation behavior.
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(* PreStep)(BoundaryCondition *self, BCContext *ctx, PetscReal *local_inflow, PetscReal *local_outflow)
PetscErrorCode(* Destroy)(BoundaryCondition *self)
PetscErrorCode(* PostStep)(BoundaryCondition *self, BCContext *ctx,...)
PetscErrorCode(* Initialize)(BoundaryCondition *self, BCContext *ctx)
PetscErrorCode(* UpdateUbcs)(BoundaryCondition *self, BCContext *ctx)
PetscErrorCode(* Apply)(BoundaryCondition *self, BCContext *ctx)
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
Boundary condition velocity values. (Comment: "An ugly hack, waste of memory")
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.
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.
static double sign(double value)
Returns the sign of a number.