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"
148 PetscBool can_service;
152 PetscFunctionBeginUser;
153 DMDALocalInfo *info = &user->
info;
155 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
157 IM_nodes_global = user->
IM;
158 JM_nodes_global = user->
JM;
159 KM_nodes_global = user->
KM;
161 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
163 if (!can_service) PetscFunctionReturn(0);
170 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
171 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
173 PetscInt xs = info->xs, xe = info->xs + info->xm;
174 PetscInt ys = info->ys, ye = info->ys + info->ym;
175 PetscInt zs = info->zs, ze = info->zs + info->zm;
176 PetscInt mx = info->mx, my = info->my, mz = info->mz;
179 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
180 if (xs == 0) lxs = xs + 1;
181 if (xe == mx) lxe = xe - 1;
182 if (ys == 0) lys = ys + 1;
183 if (ye == my) lye = ye - 1;
184 if (zs == 0) lzs = zs + 1;
185 if (ze == mz) lze = ze - 1;
191 for (PetscInt k = lzs; k < lze; k++) {
192 for (PetscInt j = lys; j < lye; j++) {
194 ucont[k][j][i].
x = 0.0;
197 ubcs[k][j][i].
x = 0.0;
198 ubcs[k][j][i].
y = 0.0;
199 ubcs[k][j][i].
z = 0.0;
209 for (PetscInt k = lzs; k < lze; k++) {
210 for (PetscInt j = lys; j < lye; j++) {
211 ucont[k][j][i-1].
x = 0.0;
213 ubcs[k][j][i].
x = 0.0;
214 ubcs[k][j][i].
y = 0.0;
215 ubcs[k][j][i].
z = 0.0;
224 for (PetscInt k = lzs; k < lze; k++) {
225 for (PetscInt i = lxs; i < lxe; i++) {
226 ucont[k][j][i].
y = 0.0;
228 ubcs[k][j][i].
x = 0.0;
229 ubcs[k][j][i].
y = 0.0;
230 ubcs[k][j][i].
z = 0.0;
239 for (PetscInt k = lzs; k < lze; k++) {
240 for (PetscInt i = lxs; i < lxe; i++) {
241 ucont[k][j-1][i].
y = 0.0;
243 ubcs[k][j][i].
x = 0.0;
244 ubcs[k][j][i].
y = 0.0;
245 ubcs[k][j][i].
z = 0.0;
254 for (PetscInt j = lys; j < lye; j++) {
255 for (PetscInt i = lxs; i < lxe; i++) {
256 ucont[k][j][i].
z = 0.0;
258 ubcs[k][j][i].
x = 0.0;
259 ubcs[k][j][i].
y = 0.0;
260 ubcs[k][j][i].
z = 0.0;
269 for (PetscInt j = lys; j < lye; j++) {
270 for (PetscInt i = lxs; i < lxe; i++) {
271 ucont[k-1][j][i].
z = 0.0;
273 ubcs[k][j][i].
x = 0.0;
274 ubcs[k][j][i].
y = 0.0;
275 ubcs[k][j][i].
z = 0.0;
283 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
284 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
286 PetscFunctionReturn(0);
301 PetscReal *in, PetscReal *out);
304 PetscReal *in, PetscReal *out);
315#define __FUNCT__ "Create_InletConstantVelocity"
325 PetscFunctionBeginUser;
327 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
330 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
331 bc->
data = (
void*)data;
341 PetscFunctionReturn(0);
346#define __FUNCT__ "Initialize_InletConstantVelocity"
358 PetscFunctionBeginUser;
359 LOG_ALLOW(
LOCAL,
LOG_DEBUG,
"Initialize_InletConstantVelocity: Initializing handler for Face %d. \n", face_id);
391 PetscFunctionReturn(0);
395#define __FUNCT__ "PreStep_InletConstantVelocity"
400 PetscReal *local_inflow_contribution,
401 PetscReal *local_outflow_contribution)
409 (void)local_inflow_contribution;
410 (void)local_outflow_contribution;
412 PetscFunctionBeginUser;
413 PetscFunctionReturn(0);
417#define __FUNCT__ "Apply_InletConstantVelocity"
427 PetscBool can_service;
429 PetscFunctionBeginUser;
431 DMDALocalInfo *info = &user->
info;
432 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
434 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
436 IM_nodes_global = user->
IM;
437 JM_nodes_global = user->
JM;
438 KM_nodes_global = user->
KM;
440 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
442 if (!can_service) PetscFunctionReturn(0);
446 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
447 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
448 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
449 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
450 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
451 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
456 PetscInt xs = info->xs, xe = info->xs + info->xm;
457 PetscInt ys = info->ys, ye = info->ys + info->ym;
458 PetscInt zs = info->zs, ze = info->zs + info->zm;
459 PetscInt mx = info->mx, my = info->my, mz = info->mz;
461 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
462 if (xs == 0) lxs = xs + 1;
463 if (xe == mx) lxe = xe - 1;
464 if (ys == 0) lys = ys + 1;
465 if (ye == my) lye = ye - 1;
466 if (zs == 0) lzs = zs + 1;
467 if (ze == mz) lze = ze - 1;
475 for (PetscInt k = lzs; k < lze; k++) {
476 for (PetscInt j = lys; j < lye; j++) {
477 if ((sign > 0 && nvert[k][j][i+1] > 0.1) ||
478 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
480 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
481 csi[k][j][i].y * csi[k][j][i].y +
482 csi[k][j][i].z * csi[k][j][i].z);
484 ucont[k][j][i].
x = sign * uin_this_point * CellArea;
486 ubcs[k][j][i + (sign < 0)].x = sign * uin_this_point * csi[k][j][i].x / CellArea;
487 ubcs[k][j][i + (sign < 0)].y = sign * uin_this_point * csi[k][j][i].y / CellArea;
488 ubcs[k][j][i + (sign < 0)].z = sign * uin_this_point * csi[k][j][i].z / CellArea;
498 for (PetscInt k = lzs; k < lze; k++) {
499 for (PetscInt i = lxs; i < lxe; i++) {
500 if ((sign > 0 && nvert[k][j+1][i] > 0.1) ||
501 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
503 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
504 eta[k][j][i].y * eta[k][j][i].y +
505 eta[k][j][i].z * eta[k][j][i].z);
507 ucont[k][j][i].
y = sign * uin_this_point * CellArea;
509 ubcs[k][j + (sign < 0)][i].x = sign * uin_this_point * eta[k][j][i].x / CellArea;
510 ubcs[k][j + (sign < 0)][i].y = sign * uin_this_point * eta[k][j][i].y / CellArea;
511 ubcs[k][j + (sign < 0)][i].z = sign * uin_this_point * eta[k][j][i].z / CellArea;
521 for (PetscInt j = lys; j < lye; j++) {
522 for (PetscInt i = lxs; i < lxe; i++) {
523 if ((sign > 0 && nvert[k+1][j][i] > 0.1) ||
524 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
526 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
527 zet[k][j][i].y * zet[k][j][i].y +
528 zet[k][j][i].z * zet[k][j][i].z);
530 ucont[k][j][i].
z = sign * uin_this_point * CellArea;
532 ubcs[k + (sign < 0)][j][i].x = sign * uin_this_point * zet[k][j][i].x / CellArea;
533 ubcs[k + (sign < 0)][j][i].y = sign * uin_this_point * zet[k][j][i].y / CellArea;
534 ubcs[k + (sign < 0)][j][i].z = sign * uin_this_point * zet[k][j][i].z / CellArea;
541 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
542 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
543 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
544 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
545 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
546 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
548 PetscFunctionReturn(0);
552#define __FUNCT__ "PostStep_InletConstantVelocity"
557 PetscReal *local_inflow_contribution,
558 PetscReal *local_outflow_contribution)
563 PetscBool can_service;
566 (void)local_outflow_contribution;
568 PetscFunctionBeginUser;
570 DMDALocalInfo *info = &user->
info;
573 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
575 IM_nodes_global = user->
IM;
576 JM_nodes_global = user->
JM;
577 KM_nodes_global = user->
KM;
579 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
582 if (!can_service) PetscFunctionReturn(0);
584 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
586 PetscReal local_flux = 0.0;
588 PetscInt xs = info->xs, xe = info->xs + info->xm;
589 PetscInt ys = info->ys, ye = info->ys + info->ym;
590 PetscInt zs = info->zs, ze = info->zs + info->zm;
591 PetscInt mx = info->mx, my = info->my, mz = info->mz;
593 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
594 if (xs == 0) lxs = xs + 1;
595 if (xe == mx) lxe = xe - 1;
596 if (ys == 0) lys = ys + 1;
597 if (ye == my) lye = ye - 1;
598 if (zs == 0) lzs = zs + 1;
599 if (ze == mz) lze = ze - 1;
606 for (PetscInt k = lzs; k < lze; k++) {
607 for (PetscInt j = lys; j < lye; j++) {
608 local_flux += ucont[k][j][i].
x;
616 for (PetscInt k = lzs; k < lze; k++) {
617 for (PetscInt i = lxs; i < lxe; i++) {
618 local_flux += ucont[k][j][i].
y;
626 for (PetscInt j = lys; j < lye; j++) {
627 for (PetscInt i = lxs; i < lxe; i++) {
628 local_flux += ucont[k][j][i].
z;
634 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
636 *local_inflow_contribution += local_flux;
639 face_id, local_flux);
641 PetscFunctionReturn(0);
646#define __FUNCT__ "Destroy_InletConstantVelocity"
652 PetscFunctionBeginUser;
653 if (self && self->
data) {
654 PetscFree(self->
data);
657 PetscFunctionReturn(0);
687 PetscReal *in, PetscReal *out);
690 PetscReal *in, PetscReal *out);
708#define __FUNCT__ "Create_InletParabolicProfile"
718 PetscFunctionBeginUser;
720 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
723 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
724 bc->
data = (
void*)data;
734 PetscFunctionReturn(0);
739#define __FUNCT__ "Initialize_InletParabolicProfile"
751 PetscFunctionBeginUser;
757 &data->
v_max, &found); CHKERRQ(ierr);
759 LOG_ALLOW(
GLOBAL,
LOG_WARNING,
"Initialize_InletParabolicProfile: 'v_max' not found in params for face %d. Defaulting to 0.0.\n", face_id);
763 PetscReal cs1_dim, cs2_dim;
767 cs1_dim = (PetscReal)user->
JM;
768 cs2_dim = (PetscReal)user->
KM;
772 cs1_dim = (PetscReal)user->
IM;
773 cs2_dim = (PetscReal)user->
KM;
778 cs1_dim = (PetscReal)user->
IM;
779 cs2_dim = (PetscReal)user->
JM;
784 PetscReal cs1_width = cs1_dim - 2.0;
785 PetscReal cs2_width = cs2_dim - 2.0;
799 PetscFunctionReturn(0);
804#define __FUNCT__ "PreStep_InletParabolicProfile"
809 PetscReal *local_inflow_contribution,
810 PetscReal *local_outflow_contribution)
814 (void)local_inflow_contribution;
815 (void)local_outflow_contribution;
817 PetscFunctionBeginUser;
818 PetscFunctionReturn(0);
823#define __FUNCT__ "Apply_InletParabolicProfile"
833 PetscBool can_service;
835 PetscFunctionBeginUser;
837 DMDALocalInfo *info = &user->
info;
838 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
840 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
842 IM_nodes_global = user->
IM;
843 JM_nodes_global = user->
JM;
844 KM_nodes_global = user->
KM;
847 face_id, &can_service); CHKERRQ(ierr);
849 if (!can_service) PetscFunctionReturn(0);
852 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
853 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
854 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
855 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
856 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
857 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
859 PetscInt xs = info->xs, xe = info->xs + info->xm;
860 PetscInt ys = info->ys, ye = info->ys + info->ym;
861 PetscInt zs = info->zs, ze = info->zs + info->zm;
862 PetscInt mx = info->mx, my = info->my, mz = info->mz;
864 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
865 if (xs == 0) lxs = xs + 1;
866 if (xe == mx) lxe = xe - 1;
867 if (ys == 0) lys = ys + 1;
868 if (ye == my) lye = ye - 1;
869 if (zs == 0) lzs = zs + 1;
870 if (ze == mz) lze = ze - 1;
879 for (PetscInt k = lzs; k < lze; k++) {
880 for (PetscInt j = lys; j < lye; j++) {
881 if ((sign > 0 && nvert[k][j][i+1] > 0.1) ||
882 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
887 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
888 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
889 PetscReal uin_local = data->
v_max * profile;
891 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
892 csi[k][j][i].y * csi[k][j][i].y +
893 csi[k][j][i].z * csi[k][j][i].z);
895 ucont[k][j][i].
x = sign * uin_local * CellArea;
897 ubcs[k][j][i + (sign < 0)].x = sign * uin_local * csi[k][j][i].x / CellArea;
898 ubcs[k][j][i + (sign < 0)].y = sign * uin_local * csi[k][j][i].y / CellArea;
899 ubcs[k][j][i + (sign < 0)].z = sign * uin_local * csi[k][j][i].z / CellArea;
910 for (PetscInt k = lzs; k < lze; k++) {
911 for (PetscInt i = lxs; i < lxe; i++) {
912 if ((sign > 0 && nvert[k][j+1][i] > 0.1) ||
913 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
918 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
919 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
920 PetscReal uin_local = data->
v_max * profile;
922 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
923 eta[k][j][i].y * eta[k][j][i].y +
924 eta[k][j][i].z * eta[k][j][i].z);
926 ucont[k][j][i].
y = sign * uin_local * CellArea;
928 ubcs[k][j + (sign < 0)][i].x = sign * uin_local * eta[k][j][i].x / CellArea;
929 ubcs[k][j + (sign < 0)][i].y = sign * uin_local * eta[k][j][i].y / CellArea;
930 ubcs[k][j + (sign < 0)][i].z = sign * uin_local * eta[k][j][i].z / CellArea;
941 for (PetscInt j = lys; j < lye; j++) {
942 for (PetscInt i = lxs; i < lxe; i++) {
943 if ((sign > 0 && nvert[k+1][j][i] > 0.1) ||
944 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
949 PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
950 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
951 PetscReal uin_local = data->
v_max * profile;
953 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
954 zet[k][j][i].y * zet[k][j][i].y +
955 zet[k][j][i].z * zet[k][j][i].z);
957 ucont[k][j][i].
z = sign * uin_local * CellArea;
959 ubcs[k + (sign < 0)][j][i].x = sign * uin_local * zet[k][j][i].x / CellArea;
960 ubcs[k + (sign < 0)][j][i].y = sign * uin_local * zet[k][j][i].y / CellArea;
961 ubcs[k + (sign < 0)][j][i].z = sign * uin_local * zet[k][j][i].z / CellArea;
968 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
969 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
970 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
971 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
972 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
973 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
975 PetscFunctionReturn(0);
980#define __FUNCT__ "PostStep_InletParabolicProfile"
985 PetscReal *local_inflow_contribution,
986 PetscReal *local_outflow_contribution)
991 PetscBool can_service;
994 (void)local_outflow_contribution;
996 PetscFunctionBeginUser;
998 DMDALocalInfo *info = &user->
info;
1001 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
1003 IM_nodes_global = user->
IM;
1004 JM_nodes_global = user->
JM;
1005 KM_nodes_global = user->
KM;
1008 face_id, &can_service); CHKERRQ(ierr);
1010 if (!can_service) PetscFunctionReturn(0);
1012 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1014 PetscReal local_flux = 0.0;
1016 PetscInt xs = info->xs, xe = info->xs + info->xm;
1017 PetscInt ys = info->ys, ye = info->ys + info->ym;
1018 PetscInt zs = info->zs, ze = info->zs + info->zm;
1019 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1021 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1022 if (xs == 0) lxs = xs + 1;
1023 if (xe == mx) lxe = xe - 1;
1024 if (ys == 0) lys = ys + 1;
1025 if (ye == my) lye = ye - 1;
1026 if (zs == 0) lzs = zs + 1;
1027 if (ze == mz) lze = ze - 1;
1033 for (PetscInt k = lzs; k < lze; k++) {
1034 for (PetscInt j = lys; j < lye; j++) {
1035 local_flux += ucont[k][j][i].
x;
1043 for (PetscInt k = lzs; k < lze; k++) {
1044 for (PetscInt i = lxs; i < lxe; i++) {
1045 local_flux += ucont[k][j][i].
y;
1053 for (PetscInt j = lys; j < lye; j++) {
1054 for (PetscInt i = lxs; i < lxe; i++) {
1055 local_flux += ucont[k][j][i].
z;
1061 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1063 *local_inflow_contribution += local_flux;
1066 face_id, local_flux);
1068 PetscFunctionReturn(0);
1073#define __FUNCT__ "Destroy_InletParabolicProfile"
1079 PetscFunctionBeginUser;
1080 if (self && self->
data) {
1081 PetscFree(self->
data);
1084 PetscFunctionReturn(0);
1100 PetscReal *in, PetscReal *out);
1103 PetscReal *in, PetscReal *out);
1125 const char **value_out, PetscBool *found)
1127 PetscFunctionBeginUser;
1128 *found = PETSC_FALSE;
1130 for (
BC_Param *param = params; param; param = param->
next) {
1131 if (strcasecmp(param->key, key) == 0) {
1132 *value_out = param->value;
1133 *found = PETSC_TRUE;
1134 PetscFunctionReturn(0);
1137 PetscFunctionReturn(0);
1150 PetscInt *n1, PetscInt *n2)
1152 PetscFunctionBeginUser;
1170 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
1171 "Unsupported face id %d for inlet profile dimensions.", face_id);
1173 if (*n1 <= 0 || *n2 <= 0) {
1174 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1175 "Invalid inlet profile dimensions (%d, %d) for grid (%d, %d, %d).",
1176 *n1, *n2, user->
IM, user->
JM, user->
KM);
1178 PetscFunctionReturn(0);
1197 PetscErrorCode ierr;
1199 char magic[32] = {0};
1200 PetscInt frame_count = 0, n1 = 0, n2 = 0;
1202 PetscFunctionBeginUser;
1203 fd = fopen(source_file,
"r");
1204 if (!fd) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
1205 "Cannot open PICSLICE inlet profile file: %s", source_file);
1207 if (fscanf(fd,
"%31s", magic) != 1 || strcmp(magic,
"PICSLICE") != 0) {
1209 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1210 "PICSLICE inlet profile file %s must begin with PICSLICE header.", source_file);
1212 if (fscanf(fd,
"%d", &frame_count) != 1) {
1214 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1215 "PICSLICE inlet profile file %s missing frame count.", source_file);
1217 if (frame_count != 1) {
1219 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1220 "PICSLICE inlet profile file %s has %d frames; static handler requires 1.",
1221 source_file, frame_count);
1223 if (fscanf(fd,
"%d %d", &n1, &n2) != 2) {
1225 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1226 "PICSLICE inlet profile file %s missing slice dimensions.", source_file);
1228 if (n1 != expected_n1 || n2 != expected_n2) {
1230 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1231 "PICSLICE inlet profile dimensions mismatch for %s: expected (%d, %d), found (%d, %d).",
1232 source_file, expected_n1, expected_n2, n1, n2);
1237 ierr = PetscMalloc1(n1 * n2, &data->
profile); CHKERRQ(ierr);
1241 for (PetscInt idx = 0; idx < n1 * n2; idx++) {
1242 PetscReal value = 0.0;
1243 if (fscanf(fd,
"%le", &value) != 1) {
1245 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
1246 "PICSLICE inlet profile file %s ended early: expected %d values.",
1247 source_file, n1 * n2);
1249 if (PetscIsInfOrNanReal(value) || value < 0.0) {
1251 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1252 "PICSLICE inlet profile file %s contains invalid speed %.6e at flat index %d.",
1253 source_file, (
double)value, idx);
1261 if (fscanf(fd,
"%63s", extra) == 1) {
1263 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
1264 "PICSLICE inlet profile file %s has extra token after %d values: %s",
1265 source_file, n1 * n2, extra);
1268 PetscFunctionReturn(0);
1285#define __FUNCT__ "Create_InletProfileFromFile"
1294 PetscErrorCode ierr;
1295 PetscFunctionBeginUser;
1297 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
1300 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
1307 bc->
data = (
void*)data;
1317 PetscFunctionReturn(0);
1321#define __FUNCT__ "Initialize_InletProfileFromFile"
1335 PetscErrorCode ierr;
1339 PetscBool found = PETSC_FALSE;
1340 const char *source_file = NULL;
1341 PetscInt expected_n1 = 0, expected_n2 = 0;
1343 PetscFunctionBeginUser;
1345 &source_file, &found); CHKERRQ(ierr);
1346 if (!found || !source_file || source_file[0] ==
'\0') {
1347 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1348 "InletProfileFromFile requires source_file parameter for face %d.", face_id);
1351 ierr = PetscStrallocpy(source_file, &data->
source_file); CHKERRQ(ierr);
1356 " Inlet Face %d (Prescribed Flow): source=%s dims=(%d,%d) speed[min,max]=[%.6e, %.6e]\n",
1361 PetscFunctionReturn(0);
1365#define __FUNCT__ "PreStep_InletProfileFromFile"
1379 PetscReal *local_inflow_contribution,
1380 PetscReal *local_outflow_contribution)
1384 (void)local_inflow_contribution;
1385 (void)local_outflow_contribution;
1386 PetscFunctionBeginUser;
1387 PetscFunctionReturn(0);
1391#define __FUNCT__ "Apply_InletProfileFromFile"
1406 PetscErrorCode ierr;
1410 PetscBool can_service;
1412 PetscFunctionBeginUser;
1413 DMDALocalInfo *info = &user->
info;
1414 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
1418 if (!can_service) PetscFunctionReturn(0);
1420 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1421 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1422 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1423 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1424 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1425 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1427 PetscInt xs = info->xs, xe = info->xs + info->xm;
1428 PetscInt ys = info->ys, ye = info->ys + info->ym;
1429 PetscInt zs = info->zs, ze = info->zs + info->zm;
1430 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1432 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1433 if (xs == 0) lxs = xs + 1;
1434 if (xe == mx) lxe = xe - 1;
1435 if (ys == 0) lys = ys + 1;
1436 if (ye == my) lye = ye - 1;
1437 if (zs == 0) lzs = zs + 1;
1438 if (ze == mz) lze = ze - 1;
1445 for (PetscInt k = lzs; k < lze; k++) {
1446 for (PetscInt j = lys; j < lye; j++) {
1447 if ((sign > 0 && nvert[k][j][i+1] > 0.1) ||
1448 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1450 PetscReal CellArea = sqrt(csi[k][j][i].x * csi[k][j][i].x +
1451 csi[k][j][i].y * csi[k][j][i].y +
1452 csi[k][j][i].z * csi[k][j][i].z);
1453 ucont[k][j][i].
x = sign * uin_local * CellArea;
1454 ubcs[k][j][i + (sign < 0)].x = sign * uin_local * csi[k][j][i].x / CellArea;
1455 ubcs[k][j][i + (sign < 0)].y = sign * uin_local * csi[k][j][i].y / CellArea;
1456 ubcs[k][j][i + (sign < 0)].z = sign * uin_local * csi[k][j][i].z / CellArea;
1464 for (PetscInt k = lzs; k < lze; k++) {
1465 for (PetscInt i = lxs; i < lxe; i++) {
1466 if ((sign > 0 && nvert[k][j+1][i] > 0.1) ||
1467 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1469 PetscReal CellArea = sqrt(eta[k][j][i].x * eta[k][j][i].x +
1470 eta[k][j][i].y * eta[k][j][i].y +
1471 eta[k][j][i].z * eta[k][j][i].z);
1472 ucont[k][j][i].
y = sign * uin_local * CellArea;
1473 ubcs[k][j + (sign < 0)][i].x = sign * uin_local * eta[k][j][i].x / CellArea;
1474 ubcs[k][j + (sign < 0)][i].y = sign * uin_local * eta[k][j][i].y / CellArea;
1475 ubcs[k][j + (sign < 0)][i].z = sign * uin_local * eta[k][j][i].z / CellArea;
1483 for (PetscInt j = lys; j < lye; j++) {
1484 for (PetscInt i = lxs; i < lxe; i++) {
1485 if ((sign > 0 && nvert[k+1][j][i] > 0.1) ||
1486 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1488 PetscReal CellArea = sqrt(zet[k][j][i].x * zet[k][j][i].x +
1489 zet[k][j][i].y * zet[k][j][i].y +
1490 zet[k][j][i].z * zet[k][j][i].z);
1491 ucont[k][j][i].
z = sign * uin_local * CellArea;
1492 ubcs[k + (sign < 0)][j][i].x = sign * uin_local * zet[k][j][i].x / CellArea;
1493 ubcs[k + (sign < 0)][j][i].y = sign * uin_local * zet[k][j][i].y / CellArea;
1494 ubcs[k + (sign < 0)][j][i].z = sign * uin_local * zet[k][j][i].z / CellArea;
1500 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1501 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1502 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1503 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1504 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1505 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1507 PetscFunctionReturn(0);
1511#define __FUNCT__ "PostStep_InletProfileFromFile"
1525 PetscReal *local_inflow_contribution,
1526 PetscReal *local_outflow_contribution)
1528 PetscErrorCode ierr;
1531 PetscBool can_service;
1534 (void)local_outflow_contribution;
1536 PetscFunctionBeginUser;
1537 DMDALocalInfo *info = &user->
info;
1541 if (!can_service) PetscFunctionReturn(0);
1543 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1544 PetscReal local_flux = 0.0;
1546 PetscInt xs = info->xs, xe = info->xs + info->xm;
1547 PetscInt ys = info->ys, ye = info->ys + info->ym;
1548 PetscInt zs = info->zs, ze = info->zs + info->zm;
1549 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1551 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1552 if (xs == 0) lxs = xs + 1;
1553 if (xe == mx) lxe = xe - 1;
1554 if (ys == 0) lys = ys + 1;
1555 if (ye == my) lye = ye - 1;
1556 if (zs == 0) lzs = zs + 1;
1557 if (ze == mz) lze = ze - 1;
1563 for (PetscInt k = lzs; k < lze; k++)
1564 for (PetscInt j = lys; j < lye; j++)
1565 local_flux += ucont[k][j][i].x;
1570 for (PetscInt k = lzs; k < lze; k++)
1571 for (PetscInt i = lxs; i < lxe; i++)
1572 local_flux += ucont[k][j][i].y;
1577 for (PetscInt j = lys; j < lye; j++)
1578 for (PetscInt i = lxs; i < lxe; i++)
1579 local_flux += ucont[k][j][i].z;
1583 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1584 *local_inflow_contribution += local_flux;
1587 face_id, local_flux);
1589 PetscFunctionReturn(0);
1593#define __FUNCT__ "Destroy_InletProfileFromFile"
1602 PetscFunctionBeginUser;
1603 if (self && self->
data) {
1607 PetscFree(self->
data);
1610 PetscFunctionReturn(0);
1631 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution);
1634 PetscReal *in, PetscReal *out);
1637#define __FUNCT__ "Create_OutletConservation"
1646 PetscFunctionBeginUser;
1648 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
1664 PetscFunctionReturn(0);
1668#define __FUNCT__ "PreStep_OutletConservation"
1673 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution)
1675 PetscErrorCode ierr;
1678 DMDALocalInfo* info = &user->
info;
1679 PetscBool can_service;
1683 (void)local_inflow_contribution;
1685 PetscFunctionBeginUser;
1689 const PetscInt IM_nodes_global = user->
IM;
1690 const PetscInt JM_nodes_global = user->
JM;
1691 const PetscInt KM_nodes_global = user->
KM;
1692 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1695 PetscFunctionReturn(0);
1701 Cmpnts ***ucat, ***csi, ***eta, ***zet;
1703 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1704 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1705 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1706 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1707 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1709 PetscReal local_flux_out = 0.0;
1710 const PetscInt xs=info->xs, xe=info->xs+info->xm;
1711 const PetscInt ys=info->ys, ye=info->ys+info->ym;
1712 const PetscInt zs=info->zs, ze=info->zs+info->zm;
1713 const PetscInt mx=info->mx, my=info->my, mz=info->mz;
1716 PetscInt lxs = xs;
if (xs == 0) lxs = xs + 1;
1717 PetscInt lxe = xe;
if (xe == mx) lxe = xe - 1;
1718 PetscInt lys = ys;
if (ys == 0) lys = ys + 1;
1719 PetscInt lye = ye;
if (ye == my) lye = ye - 1;
1720 PetscInt lzs = zs;
if (zs == 0) lzs = zs + 1;
1721 PetscInt lze = ze;
if (ze == mz) lze = ze - 1;
1726 const PetscInt i_cell = xs + 1;
1727 const PetscInt i_face = xs;
1728 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1729 if (nvert[k][j][i_cell] < 0.1) {
1730 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);
1736 const PetscInt i_cell = xe - 2;
1737 const PetscInt i_face = xe - 2;
1738 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1739 if (nvert[k][j][i_cell] < 0.1) {
1740 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);
1746 const PetscInt j_cell = ys + 1;
1747 const PetscInt j_face = ys;
1748 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1749 if (nvert[k][j_cell][i] < 0.1) {
1750 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);
1756 const PetscInt j_cell = ye - 2;
1757 const PetscInt j_face = ye - 2;
1758 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1759 if (nvert[k][j_cell][i] < 0.1) {
1760 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);
1766 const PetscInt k_cell = zs + 1;
1767 const PetscInt k_face = zs;
1768 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1769 if (nvert[k_cell][j][i] < 0.1) {
1770 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);
1776 const PetscInt k_cell = ze - 2;
1777 const PetscInt k_face = ze - 2;
1778 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1779 if (nvert[k_cell][j][i] < 0.1) {
1780 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 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1789 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1790 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1791 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1792 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1795 *local_outflow_contribution += local_flux_out;
1797 PetscFunctionReturn(0);
1801#define __FUNCT__ "Apply_OutletConservation"
1810 PetscErrorCode ierr;
1814 DMDALocalInfo* info = &user->
info;
1815 PetscBool can_service;
1817 PetscFunctionBeginUser;
1820 const PetscInt IM_nodes_global = user->
IM;
1821 const PetscInt JM_nodes_global = user->
JM;
1822 const PetscInt KM_nodes_global = user->
KM;
1823 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1827 PetscFunctionReturn(0);
1835 PetscReal velocity_correction = (PetscAbsReal(user->
simCtx->
AreaOutSum) > 1e-12)
1846 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet, ***ucat;
1848 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1849 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1850 ierr = DMDAVecGetArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1851 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1852 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1853 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1854 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1857 PetscInt xs = info->xs, xe = info->xs + info->xm;
1858 PetscInt ys = info->ys, ye = info->ys + info->ym;
1859 PetscInt zs = info->zs, ze = info->zs + info->zm;
1860 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1861 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1863 if (xs == 0) lxs = xs + 1;
1864 if (xe == mx) lxe = xe - 1;
1865 if (ys == 0) lys = ys + 1;
1866 if (ye == my) lye = ye - 1;
1867 if (zs == 0) lzs = zs + 1;
1868 if (ze == mz) lze = ze - 1;
1873 const PetscInt i_cell = xs + 1;
1874 const PetscInt i_face = xs;
1875 const PetscInt i_dummy = xs;
1876 for (PetscInt k = lzs; k < lze; k++) {
1877 for (PetscInt j = lys; j < lye; j++) {
1878 if (nvert[k][j][i_cell] < 0.1) {
1880 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1883 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);
1885 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));
1887 PetscReal Correction_flux = velocity_correction*Cell_Area;
1889 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1896 const PetscInt i_cell = xe - 2;
1897 const PetscInt i_face = xe - 2;
1898 const PetscInt i_dummy = xe - 1;
1899 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++){
1900 if(nvert[k][j][i_cell]<0.1){
1902 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1905 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);
1907 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));
1909 PetscReal Correction_flux = velocity_correction*Cell_Area;
1911 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1917 const PetscInt j_cell = ys + 1;
1918 const PetscInt j_face = ys;
1919 const PetscInt j_dummy = ys;
1920 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1921 if(nvert[k][j_cell][i]<0.1){
1923 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1926 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);
1928 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));
1930 PetscReal Correction_flux = velocity_correction*Cell_Area;
1932 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1938 const PetscInt j_cell = ye - 2;
1939 const PetscInt j_face = ye - 2;
1940 const PetscInt j_dummy = ye - 1;
1941 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1942 if(nvert[k][j_cell][i]<0.1){
1944 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1947 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);
1949 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));
1951 PetscReal Correction_flux = velocity_correction*Cell_Area;
1953 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1959 const PetscInt k_cell = zs + 1;
1960 const PetscInt k_face = zs;
1961 const PetscInt k_dummy = zs;
1962 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1963 if(nvert[k_cell][j][i]<0.1){
1965 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
1968 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));
1970 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));
1972 PetscReal Correction_flux = velocity_correction*Cell_Area;
1974 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
1980 const PetscInt k_cell = ze - 2;
1981 const PetscInt k_face = ze - 2;
1982 const PetscInt k_dummy = ze - 1;
1983 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1984 if(nvert[k_cell][j][i]<0.1){
1986 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
1989 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));
1991 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));
1993 PetscReal Correction_flux = velocity_correction*Cell_Area;
1995 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
2003 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
2004 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
2005 ierr = DMDAVecRestoreArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
2006 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2007 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2008 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2009 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2012 PetscFunctionReturn(0);
2016#define __FUNCT__ "PostStep_OutletConservation"
2021 PetscReal *local_inflow_contribution,
2022 PetscReal *local_outflow_contribution)
2024 PetscErrorCode ierr;
2027 DMDALocalInfo* info = &user->
info;
2028 PetscBool can_service;
2031 (void)local_inflow_contribution;
2033 PetscFunctionBeginUser;
2034 const PetscInt IM_nodes_global = user->
IM;
2035 const PetscInt JM_nodes_global = user->
JM;
2036 const PetscInt KM_nodes_global = user->
KM;
2037 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
2039 if (!can_service) PetscFunctionReturn(0);
2045 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2046 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2048 PetscReal local_flux = 0.0;
2050 PetscInt xs = info->xs, xe = info->xs + info->xm;
2051 PetscInt ys = info->ys, ye = info->ys + info->ym;
2052 PetscInt zs = info->zs, ze = info->zs + info->zm;
2053 PetscInt mx = info->mx, my = info->my, mz = info->mz;
2055 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
2056 if (xs == 0) lxs = xs + 1;
2057 if (xe == mx) lxe = xe - 1;
2058 if (ys == 0) lys = ys + 1;
2059 if (ye == my) lye = ye - 1;
2060 if (zs == 0) lzs = zs + 1;
2061 if (ze == mz) lze = ze - 1;
2066 const PetscInt i_cell = xs + 1;
2067 const PetscInt i_face = xs;
2068 for (PetscInt k = lzs; k < lze; k++) {
2069 for (PetscInt j = lys; j < lye; j++) {
2070 if (nvert[k][j][i_cell] < 0.1) {
2071 local_flux += ucont[k][j][i_face].
x;
2078 const PetscInt i_cell = xe - 2;
2079 const PetscInt i_face = xe - 2;
2080 for (PetscInt k = lzs; k < lze; k++) {
2081 for (PetscInt j = lys; j < lye; j++) {
2082 if (nvert[k][j][i_cell] < 0.1) {
2083 local_flux += ucont[k][j][i_face].
x;
2090 const PetscInt j_cell = ys + 1;
2091 const PetscInt j_face = ys;
2092 for (PetscInt k = lzs; k < lze; k++) {
2093 for (PetscInt i = lxs; i < lxe; i++) {
2094 if (nvert[k][j_cell][i] < 0.1) {
2095 local_flux += ucont[k][j_face][i].
y;
2102 const PetscInt j_cell = ye - 2;
2103 const PetscInt j_face = ye - 2;
2104 for (PetscInt k = lzs; k < lze; k++) {
2105 for (PetscInt i = lxs; i < lxe; i++) {
2106 if (nvert[k][j_cell][i] < 0.1) {
2107 local_flux += ucont[k][j_face][i].
y;
2114 const PetscInt k_cell = zs + 1;
2115 const PetscInt k_face = zs;
2116 for (PetscInt j = lys; j < lye; j++) {
2117 for (PetscInt i = lxs; i < lxe; i++) {
2118 if (nvert[k_cell][j][i] < 0.1) {
2119 local_flux += ucont[k_face][j][i].
z;
2126 const PetscInt k_cell = ze - 2;
2127 const PetscInt k_face = ze - 2;
2128 for (PetscInt j = lys; j < lye; j++) {
2129 for (PetscInt i = lxs; i < lxe; i++) {
2130 if (nvert[k_cell][j][i] < 0.1) {
2131 local_flux += ucont[k_face][j][i].
z;
2139 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2140 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2143 *local_outflow_contribution += local_flux;
2146 face_id, local_flux);
2148 PetscFunctionReturn(0);
2160 PetscFunctionBeginUser;
2162 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
2175 PetscFunctionReturn(0);
2180#define __FUNCT__ "MeasureDrivenFluxes"
2200 PetscReal *boundaryFlux,
2201 PetscReal *planarAverageFlux)
2203 PetscErrorCode ierr;
2204 DMDALocalInfo info = user->
info;
2207 PetscFunctionBeginUser;
2212 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2213 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2216 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
2217 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
2218 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
2219 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
2220 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
2221 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2224 PetscReal localCurrentBoundaryFlux = 0.0;
2225 PetscReal localAveragePlanarVolumetricFluxTerm = 0.0;
2228 switch (direction) {
2232 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2233 if (nvert[k][j][i + 1] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
x;
2236 for (i = info.xs; i < lxe; i++) {
2237 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2238 if (nvert[k][j][i + 1] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
x / (PetscReal)(info.mx - 1);
2245 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2246 if (nvert[k][j + 1][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
y;
2249 for (j = info.ys; j < lye; j++) {
2250 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2251 if (nvert[k][j + 1][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
y / (PetscReal)(info.my - 1);
2258 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2259 if (nvert[k + 1][j][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
z;
2262 for (k = info.zs; k < lze; k++) {
2263 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2264 if (nvert[k + 1][j][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
z / (PetscReal)(info.mz - 1);
2269 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
2270 "MeasureDrivenFluxes received an unknown driven direction '%c'.", direction);
2274 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2275 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2278 ierr = MPI_Allreduce(&localCurrentBoundaryFlux, boundaryFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2279 ierr = MPI_Allreduce(&localAveragePlanarVolumetricFluxTerm, planarAverageFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2281 PetscFunctionReturn(0);
2320#define __FUNCT__ "Create_PeriodicDrivenConstant"
2327 PetscErrorCode ierr;
2328 PetscFunctionBeginUser;
2330 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition object is NULL in Create_PeriodicDrivenConstantFlux");
2334 ierr = PetscNew(&data); CHKERRQ(ierr);
2343 bc->
data = (
void*)data;
2360 PetscFunctionReturn(0);
2364#define __FUNCT__ "Initialize_PeriodicDrivenConstant"
2370 PetscErrorCode ierr;
2375 PetscFunctionBeginUser;
2381 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2382 "Configuration Error: Handler PERIODIC_DRIVEN_CONSTANT_FLUX on Face %s must be applied to a face with mathematical_type PERIODIC.",
2407 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2408 "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).",
2423 PetscBool trimfound;
2430 PetscFunctionReturn(0);
2434#define __FUNCT__ "PreStep_PeriodicDrivenConstant"
2439 PetscReal *local_inflow_contribution,
2440 PetscReal *local_outflow_contribution)
2442 PetscErrorCode ierr;
2447 PetscFunctionBeginUser;
2451 PetscFunctionReturn(0);
2457 PetscReal globalCurrentBoundaryFlux, globalAveragePlanarVolumetricFlux;
2459 &globalAveragePlanarVolumetricFlux); CHKERRQ(ierr);
2463 PetscReal globalBoundaryArea;
2489 if (globalBoundaryArea > 1.0e-12) {
2503 LOG_ALLOW(
GLOBAL,
LOG_INFO,
" - Avg Planar Volumetric Flux (Stable): %.6e\n", globalAveragePlanarVolumetricFlux);
2509 (void)local_inflow_contribution;
2510 (void)local_outflow_contribution;
2512 PetscFunctionReturn(0);
2516#define __FUNCT__ "Apply_PeriodicDrivenConstant"
2522 PetscErrorCode ierr;
2526 PetscBool can_service;
2528 PetscFunctionBeginUser;
2533 PetscFunctionReturn(0);
2538 PetscFunctionReturn(0);
2544 DMDALocalInfo info = user->
info;
2545 Cmpnts ***ucont, ***uch, ***csi, ***eta, ***zet;
2548 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
2549 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2550 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2551 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2552 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2553 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2555 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
2556 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
2557 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
2558 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
2559 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
2560 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2565 PetscInt i_face = (face_id ==
BC_FACE_NEG_X) ? info.xs : info.mx - 2;
2566 PetscInt i_nvert = (face_id ==
BC_FACE_NEG_X) ? info.xs + 1 : info.mx - 2;
2568 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++) {
2569 if (nvert[k][j][i_nvert] < 0.1) {
2570 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);
2573 uch[k][j][i_face].
x = fluxTrim;
2579 PetscInt j_face = (face_id ==
BC_FACE_NEG_Y) ? info.ys : info.my - 2;
2580 PetscInt j_nvert = (face_id ==
BC_FACE_NEG_Y) ? info.ys + 1 : info.my - 2;
2582 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++) {
2583 if (nvert[k][j_nvert][i] < 0.1) {
2584 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);
2587 uch[k][j_face][i].
y = fluxTrim;
2593 PetscInt k_face = (face_id ==
BC_FACE_NEG_Z) ? info.zs : info.mz - 2;
2594 PetscInt k_nvert = (face_id ==
BC_FACE_NEG_Z) ? info.zs + 1 : info.mz - 2;
2596 for (PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++) {
2597 if (nvert[k_nvert][j][i] < 0.1) {
2598 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);
2601 uch[k_face][j][i].
z = fluxTrim;
2608 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
2609 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2610 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2611 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2612 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2613 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2615 PetscFunctionReturn(0);
2619#define __FUNCT__ "Destroy_PeriodicDrivenConstant"
2625 PetscFunctionBeginUser;
2628 if (self && self->
data) {
2630 PetscFree(self->
data);
2639 PetscFunctionReturn(0);
2664#define __FUNCT__ "Create_PeriodicDrivenInitial"
2671 PetscErrorCode ierr;
2672 PetscFunctionBeginUser;
2674 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition object is NULL in Create_PeriodicDrivenInitial");
2678 ierr = PetscNew(&data); CHKERRQ(ierr);
2687 bc->
data = (
void*)data;
2702 PetscFunctionReturn(0);
2706#define __FUNCT__ "Initialize_PeriodicDrivenInitial"
2718 PetscErrorCode ierr;
2723 PetscFunctionBeginUser;
2729 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2730 "Configuration Error: Handler PERIODIC_DRIVEN_INITIAL_FLUX on Face %s must be applied to a face with mathematical_type PERIODIC.",
2747 PetscReal unused_flux;
2754 &unused_flux, &found); CHKERRQ(ierr);
2756 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2757 "Configuration Error: Handler PERIODIC_DRIVEN_INITIAL_FLUX on Face %s takes no 'target_flux' parameter; "
2758 "it measures the flux of the initial condition and holds that. Use handler 'constant_flux' to prescribe a target.",
2762 LOG_ALLOW(
GLOBAL,
LOG_INFO,
"Driven Flow (Dir %c): target volumetric flux will be latched from the initial state.\n",
2766 PetscBool trimfound;
2773 PetscFunctionReturn(0);
2777#define __FUNCT__ "PreStep_PeriodicDrivenInitial"
2789 PetscReal *local_inflow_contribution,
2790 PetscReal *local_outflow_contribution)
2792 PetscErrorCode ierr;
2796 PetscFunctionBeginUser;
2800 PetscReal boundaryFlux, planarAverageFlux;
2814 PetscFunctionReturn(0);
2818 &boundaryFlux, &planarAverageFlux); CHKERRQ(ierr);
2824 "Driven Flow (Dir %c): latched initial volumetric flux %.6e as the target.\n",
2833 local_inflow_contribution,
2834 local_outflow_contribution); CHKERRQ(ierr);
2836 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.
PetscBool enforceSeamFlux
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)
Apply no-slip velocity values to wall-adjacent cells for this boundary condition.
PetscErrorCode Create_InletProfileFromFile(BoundaryCondition *bc)
Implementation of Create_InletProfileFromFile().
PetscBool isMasterController
static PetscErrorCode Initialize_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx)
Initialize the geometric data used to evaluate a parabolic inlet profile.
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)
Update constant-inlet data required before the next solver step.
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)
Impose the configured constant velocity on inlet boundary cells.
PetscInt lastBulkCorrectionStep
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)
Impose the evaluated parabolic velocity profile on inlet cells.
static PetscErrorCode PostStep_InletParabolicProfile(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Perform post-step bookkeeping for a parabolic inlet boundary.
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.
static PetscErrorCode Apply_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx)
Apply the configured constant driving term to the periodic boundary.
static PetscErrorCode Initialize_PeriodicDrivenConstant(BoundaryCondition *self, BCContext *ctx)
Initialize constant forcing data for a periodically driven boundary.
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 Initialize_PeriodicDrivenInitial(BoundaryCondition *self, BCContext *ctx)
Initialize forcing data for a periodic boundary driven to its initial flux.
static PetscErrorCode Destroy_InletConstantVelocity(BoundaryCondition *self)
Release resources owned by a constant-velocity inlet boundary.
PetscErrorCode Create_PeriodicDrivenInitial(BoundaryCondition *bc)
Internal helper implementation: Create_PeriodicDrivenInitial().
static PetscErrorCode Destroy_PeriodicDrivenConstant(BoundaryCondition *self)
Release resources owned by the constant periodic-driving boundary.
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)
Refresh parabolic-inlet values required before the solver step.
static PetscErrorCode MeasureDrivenFluxes(UserCtx *user, char direction, PetscReal *boundaryFlux, PetscReal *planarAverageFlux)
Measure the two volumetric fluxes the driven-flow controller senses.
static PetscErrorCode PostStep_OutletConservation(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Update outlet-conservation state after a completed solver step.
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)
Release resources owned by a parabolic inlet boundary.
static PetscErrorCode Initialize_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx)
Initialize persistent state for a constant-velocity inlet boundary.
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)
Prepare constant periodic-driving data before the solver step.
static PetscErrorCode PostStep_InletConstantVelocity(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Perform post-step bookkeeping for a constant-velocity inlet boundary.
static PetscErrorCode PreStep_OutletConservation(BoundaryCondition *self, BCContext *ctx, PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution)
Prepare the outlet-conservation correction before advancing the solver.
PetscErrorCode Create_OutletConservation(BoundaryCondition *bc)
Implementation of Create_OutletConservation().
static PetscErrorCode PreStep_PeriodicDrivenInitial(BoundaryCondition *self, BCContext *ctx, PetscReal *in, PetscReal *out)
Latch the initial-state flux once, then drive to it like a constant target.
PetscReal targetVolumetricFlux
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 shared by both periodic driven-flux handlers.
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 GetDrivenSeamFluxFlag(BC_Param *params, PetscBool *value_out, PetscBool *found)
Read the driven-flow seam-flux flag, accepting its deprecated apply_trim spelling.
#define LOCAL
Logging scope definitions for controlling message output.
#define GLOBAL
Scope for global logging across all processes.
const char * BCFaceToString(BCFace face)
Returns the canonical log token for a boundary-face enum value.
#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)
Returns the canonical log token for a boundary mathematical type.
@ 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.
PetscReal boundaryVelocityCorrection
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
PetscBool drivenFluxTargetLatched
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.