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__ "PostStep_InletConstantVelocity"
422 PetscReal *local_inflow_contribution,
423 PetscReal *local_outflow_contribution)
428 PetscBool can_service;
431 (void)local_outflow_contribution;
433 PetscFunctionBeginUser;
435 DMDALocalInfo *info = &user->
info;
438 PetscInt IM_nodes_global, JM_nodes_global,KM_nodes_global;
440 IM_nodes_global = user->
IM;
441 JM_nodes_global = user->
JM;
442 KM_nodes_global = user->
KM;
444 ierr =
CanRankServiceFace(info,IM_nodes_global,JM_nodes_global,KM_nodes_global,face_id,&can_service); CHKERRQ(ierr);
447 if (!can_service) PetscFunctionReturn(0);
449 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
451 PetscReal local_flux = 0.0;
453 PetscInt xs = info->xs, xe = info->xs + info->xm;
454 PetscInt ys = info->ys, ye = info->ys + info->ym;
455 PetscInt zs = info->zs, ze = info->zs + info->zm;
456 PetscInt mx = info->mx, my = info->my, mz = info->mz;
458 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
459 if (xs == 0) lxs = xs + 1;
460 if (xe == mx) lxe = xe - 1;
461 if (ys == 0) lys = ys + 1;
462 if (ye == my) lye = ye - 1;
463 if (zs == 0) lzs = zs + 1;
464 if (ze == mz) lze = ze - 1;
471 for (PetscInt k = lzs; k < lze; k++) {
472 for (PetscInt j = lys; j < lye; j++) {
473 local_flux += ucont[k][j][i].
x;
481 for (PetscInt k = lzs; k < lze; k++) {
482 for (PetscInt i = lxs; i < lxe; i++) {
483 local_flux += ucont[k][j][i].
y;
491 for (PetscInt j = lys; j < lye; j++) {
492 for (PetscInt i = lxs; i < lxe; i++) {
493 local_flux += ucont[k][j][i].
z;
499 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
501 *local_inflow_contribution += local_flux;
504 face_id, local_flux);
506 PetscFunctionReturn(0);
511#define __FUNCT__ "Destroy_InletConstantVelocity"
517 PetscFunctionBeginUser;
518 if (self && self->
data) {
519 PetscFree(self->
data);
522 PetscFunctionReturn(0);
552 PetscReal *in, PetscReal *out);
554 PetscReal *in, PetscReal *out);
572#define __FUNCT__ "Create_InletParabolicProfile"
582 PetscFunctionBeginUser;
584 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
587 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
588 bc->
data = (
void*)data;
598 PetscFunctionReturn(0);
603#define __FUNCT__ "Initialize_InletParabolicProfile"
615 PetscFunctionBeginUser;
621 &data->
v_max, &found); CHKERRQ(ierr);
623 LOG_ALLOW(
GLOBAL,
LOG_WARNING,
"Initialize_InletParabolicProfile: 'v_max' not found in params for face %d. Defaulting to 0.0.\n", face_id);
627 PetscReal cs1_dim, cs2_dim;
628 PetscBool cs1_periodic, cs2_periodic;
633 cs1_dim = (PetscReal)user->
JM;
634 cs2_dim = (PetscReal)user->
KM;
635 cs1_periodic = (PetscBool)(simCtx->
j_periodic != 0);
636 cs2_periodic = (PetscBool)(simCtx->
k_periodic != 0);
640 cs1_dim = (PetscReal)user->
IM;
641 cs2_dim = (PetscReal)user->
KM;
642 cs1_periodic = (PetscBool)(simCtx->
i_periodic != 0);
643 cs2_periodic = (PetscBool)(simCtx->
k_periodic != 0);
648 cs1_dim = (PetscReal)user->
IM;
649 cs2_dim = (PetscReal)user->
JM;
650 cs1_periodic = (PetscBool)(simCtx->
i_periodic != 0);
651 cs2_periodic = (PetscBool)(simCtx->
j_periodic != 0);
662 data->
cs1_half = cs1_periodic ? PETSC_MAX_REAL : 0.5 * (cs1_dim - 1.0);
663 data->
cs2_half = cs2_periodic ? PETSC_MAX_REAL : 0.5 * (cs2_dim - 1.0);
672 PetscFunctionReturn(0);
677#define __FUNCT__ "PreStep_InletParabolicProfile"
682 PetscReal *local_inflow_contribution,
683 PetscReal *local_outflow_contribution)
687 (void)local_inflow_contribution;
688 (void)local_outflow_contribution;
690 PetscFunctionBeginUser;
691 PetscFunctionReturn(0);
697#define __FUNCT__ "PostStep_InletParabolicProfile"
702 PetscReal *local_inflow_contribution,
703 PetscReal *local_outflow_contribution)
708 PetscBool can_service;
711 (void)local_outflow_contribution;
713 PetscFunctionBeginUser;
715 DMDALocalInfo *info = &user->
info;
718 PetscInt IM_nodes_global, JM_nodes_global, KM_nodes_global;
720 IM_nodes_global = user->
IM;
721 JM_nodes_global = user->
JM;
722 KM_nodes_global = user->
KM;
725 face_id, &can_service); CHKERRQ(ierr);
727 if (!can_service) PetscFunctionReturn(0);
729 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
731 PetscReal local_flux = 0.0;
733 PetscInt xs = info->xs, xe = info->xs + info->xm;
734 PetscInt ys = info->ys, ye = info->ys + info->ym;
735 PetscInt zs = info->zs, ze = info->zs + info->zm;
736 PetscInt mx = info->mx, my = info->my, mz = info->mz;
738 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
739 if (xs == 0) lxs = xs + 1;
740 if (xe == mx) lxe = xe - 1;
741 if (ys == 0) lys = ys + 1;
742 if (ye == my) lye = ye - 1;
743 if (zs == 0) lzs = zs + 1;
744 if (ze == mz) lze = ze - 1;
750 for (PetscInt k = lzs; k < lze; k++) {
751 for (PetscInt j = lys; j < lye; j++) {
752 local_flux += ucont[k][j][i].
x;
760 for (PetscInt k = lzs; k < lze; k++) {
761 for (PetscInt i = lxs; i < lxe; i++) {
762 local_flux += ucont[k][j][i].
y;
770 for (PetscInt j = lys; j < lye; j++) {
771 for (PetscInt i = lxs; i < lxe; i++) {
772 local_flux += ucont[k][j][i].
z;
778 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
780 *local_inflow_contribution += local_flux;
783 face_id, local_flux);
785 PetscFunctionReturn(0);
790#define __FUNCT__ "Destroy_InletParabolicProfile"
796 PetscFunctionBeginUser;
797 if (self && self->
data) {
798 PetscFree(self->
data);
801 PetscFunctionReturn(0);
817 PetscReal *in, PetscReal *out);
819 PetscReal *in, PetscReal *out);
841 const char **value_out, PetscBool *found)
843 PetscFunctionBeginUser;
844 *found = PETSC_FALSE;
846 for (
BC_Param *param = params; param; param = param->
next) {
847 if (strcasecmp(param->key, key) == 0) {
848 *value_out = param->value;
850 PetscFunctionReturn(0);
853 PetscFunctionReturn(0);
866 PetscInt *n1, PetscInt *n2)
868 PetscFunctionBeginUser;
886 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE,
887 "Unsupported face id %d for inlet profile dimensions.", face_id);
889 if (*n1 <= 0 || *n2 <= 0) {
890 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
891 "Invalid inlet profile dimensions (%d, %d) for grid (%d, %d, %d).",
892 *n1, *n2, user->
IM, user->
JM, user->
KM);
894 PetscFunctionReturn(0);
915 char magic[32] = {0};
916 PetscInt frame_count = 0, n1 = 0, n2 = 0;
918 PetscFunctionBeginUser;
919 fd = fopen(source_file,
"r");
920 if (!fd) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_OPEN,
921 "Cannot open PICSLICE inlet profile file: %s", source_file);
923 if (fscanf(fd,
"%31s", magic) != 1 || strcmp(magic,
"PICSLICE") != 0) {
925 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
926 "PICSLICE inlet profile file %s must begin with PICSLICE header.", source_file);
928 if (fscanf(fd,
"%d", &frame_count) != 1) {
930 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
931 "PICSLICE inlet profile file %s missing frame count.", source_file);
933 if (frame_count != 1) {
935 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
936 "PICSLICE inlet profile file %s has %d frames; static handler requires 1.",
937 source_file, frame_count);
939 if (fscanf(fd,
"%d %d", &n1, &n2) != 2) {
941 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
942 "PICSLICE inlet profile file %s missing slice dimensions.", source_file);
944 if (n1 != expected_n1 || n2 != expected_n2) {
946 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
947 "PICSLICE inlet profile dimensions mismatch for %s: expected (%d, %d), found (%d, %d).",
948 source_file, expected_n1, expected_n2, n1, n2);
953 ierr = PetscMalloc1(n1 * n2, &data->
profile); CHKERRQ(ierr);
957 for (PetscInt idx = 0; idx < n1 * n2; idx++) {
958 PetscReal value = 0.0;
959 if (fscanf(fd,
"%le", &value) != 1) {
961 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_READ,
962 "PICSLICE inlet profile file %s ended early: expected %d values.",
963 source_file, n1 * n2);
965 if (PetscIsInfOrNanReal(value) || value < 0.0) {
967 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
968 "PICSLICE inlet profile file %s contains invalid speed %.6e at flat index %d.",
969 source_file, (
double)value, idx);
977 if (fscanf(fd,
"%63s", extra) == 1) {
979 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_FILE_UNEXPECTED,
980 "PICSLICE inlet profile file %s has extra token after %d values: %s",
981 source_file, n1 * n2, extra);
984 PetscFunctionReturn(0);
1019 PetscInt i, PetscInt j, PetscInt k,
1020 Cmpnts metric, PetscReal sign)
1022 PetscReal normal_speed = 0.0;
1023 Cmpnts velocity = {0.0, 0.0, 0.0};
1025 switch (self->
type) {
1031 PetscReal cs1 = 0.0, cs2 = 0.0;
1044 const PetscReal profile = PetscMax(0.0, 1.0 - cs1_norm * cs1_norm)
1045 * PetscMax(0.0, 1.0 - cs2_norm * cs2_norm);
1046 normal_speed = data->
v_max * profile;
1061 const PetscReal area = sqrt(metric.
x * metric.
x + metric.
y * metric.
y + metric.
z * metric.
z);
1064 if (area <= 0.0)
return velocity;
1065 velocity.
x = sign * normal_speed * metric.
x / area;
1066 velocity.
y = sign * normal_speed * metric.
y / area;
1067 velocity.
z = sign * normal_speed * metric.
z / area;
1080 PetscErrorCode ierr;
1083 PetscBool can_service;
1084 DMDALocalInfo *info = &user->
info;
1085 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet;
1088 PetscFunctionBeginUser;
1092 PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1093 "Common inlet application cannot service handler type %d.", self->
type);
1096 if (!can_service) PetscFunctionReturn(0);
1098 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1099 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1100 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1101 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1102 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1103 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1105 const PetscInt xs = info->xs, xe = info->xs + info->xm;
1106 const PetscInt ys = info->ys, ye = info->ys + info->ym;
1107 const PetscInt zs = info->zs, ze = info->zs + info->zm;
1108 const PetscInt mx = info->mx, my = info->my, mz = info->mz;
1109 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1111 if (xe == mx) lxe--;
1113 if (ye == my) lye--;
1115 if (ze == mz) lze--;
1120 const PetscReal sign = (face_id ==
BC_FACE_NEG_X) ? 1.0 : -1.0;
1121 const PetscInt i = (face_id ==
BC_FACE_NEG_X) ? xs : mx - 2;
1122 const PetscInt ib = i + (sign < 0);
1123 for (PetscInt k = lzs; k < lze; k++) {
1124 for (PetscInt j = lys; j < lye; j++) {
1125 if ((sign > 0 && nvert[k][j][i + 1] > 0.1) ||
1126 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1127 const Cmpnts metric = csi[k][j][i];
1130 ubcs[k][j][ib] = velocity;
1131 ucont[k][j][i].
x = velocity.
x * metric.
x + velocity.
y * metric.
y + velocity.
z * metric.
z;
1137 const PetscReal sign = (face_id ==
BC_FACE_NEG_Y) ? 1.0 : -1.0;
1138 const PetscInt j = (face_id ==
BC_FACE_NEG_Y) ? ys : my - 2;
1139 const PetscInt jb = j + (sign < 0);
1140 for (PetscInt k = lzs; k < lze; k++) {
1141 for (PetscInt i = lxs; i < lxe; i++) {
1142 if ((sign > 0 && nvert[k][j + 1][i] > 0.1) ||
1143 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1144 const Cmpnts metric = eta[k][j][i];
1147 ubcs[k][jb][i] = velocity;
1148 ucont[k][j][i].
y = velocity.
x * metric.
x + velocity.
y * metric.
y + velocity.
z * metric.
z;
1154 const PetscReal sign = (face_id ==
BC_FACE_NEG_Z) ? 1.0 : -1.0;
1155 const PetscInt k = (face_id ==
BC_FACE_NEG_Z) ? zs : mz - 2;
1156 const PetscInt kb = k + (sign < 0);
1157 for (PetscInt j = lys; j < lye; j++) {
1158 for (PetscInt i = lxs; i < lxe; i++) {
1159 if ((sign > 0 && nvert[k + 1][j][i] > 0.1) ||
1160 (sign < 0 && nvert[k][j][i] > 0.1))
continue;
1161 const Cmpnts metric = zet[k][j][i];
1164 ubcs[kb][j][i] = velocity;
1165 ucont[k][j][i].
z = velocity.
x * metric.
x + velocity.
y * metric.
y + velocity.
z * metric.
z;
1171 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1172 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1173 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1174 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1175 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1176 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1177 PetscFunctionReturn(0);
1181#define __FUNCT__ "Create_InletProfileFromFile"
1190 PetscErrorCode ierr;
1191 PetscFunctionBeginUser;
1193 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"BoundaryCondition is NULL");
1196 ierr = PetscMalloc1(1, &data); CHKERRQ(ierr);
1203 bc->
data = (
void*)data;
1213 PetscFunctionReturn(0);
1217#define __FUNCT__ "Initialize_InletProfileFromFile"
1230 PetscErrorCode ierr;
1234 PetscBool found = PETSC_FALSE;
1235 const char *source_file = NULL;
1236 PetscInt expected_n1 = 0, expected_n2 = 0;
1238 PetscFunctionBeginUser;
1240 &source_file, &found); CHKERRQ(ierr);
1241 if (!found || !source_file || source_file[0] ==
'\0') {
1242 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
1243 "InletProfileFromFile requires source_file parameter for face %d.", face_id);
1246 ierr = PetscStrallocpy(source_file, &data->
source_file); CHKERRQ(ierr);
1251 " Inlet Face %d (Prescribed Flow): source=%s dims=(%d,%d) speed[min,max]=[%.6e, %.6e]\n",
1256 PetscFunctionReturn(0);
1260#define __FUNCT__ "PreStep_InletProfileFromFile"
1274 PetscReal *local_inflow_contribution,
1275 PetscReal *local_outflow_contribution)
1279 (void)local_inflow_contribution;
1280 (void)local_outflow_contribution;
1281 PetscFunctionBeginUser;
1282 PetscFunctionReturn(0);
1287#define __FUNCT__ "PostStep_InletProfileFromFile"
1301 PetscReal *local_inflow_contribution,
1302 PetscReal *local_outflow_contribution)
1304 PetscErrorCode ierr;
1307 PetscBool can_service;
1310 (void)local_outflow_contribution;
1312 PetscFunctionBeginUser;
1313 DMDALocalInfo *info = &user->
info;
1317 if (!can_service) PetscFunctionReturn(0);
1319 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1320 PetscReal local_flux = 0.0;
1322 PetscInt xs = info->xs, xe = info->xs + info->xm;
1323 PetscInt ys = info->ys, ye = info->ys + info->ym;
1324 PetscInt zs = info->zs, ze = info->zs + info->zm;
1325 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1327 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1328 if (xs == 0) lxs = xs + 1;
1329 if (xe == mx) lxe = xe - 1;
1330 if (ys == 0) lys = ys + 1;
1331 if (ye == my) lye = ye - 1;
1332 if (zs == 0) lzs = zs + 1;
1333 if (ze == mz) lze = ze - 1;
1339 for (PetscInt k = lzs; k < lze; k++)
1340 for (PetscInt j = lys; j < lye; j++)
1341 local_flux += ucont[k][j][i].x;
1346 for (PetscInt k = lzs; k < lze; k++)
1347 for (PetscInt i = lxs; i < lxe; i++)
1348 local_flux += ucont[k][j][i].y;
1353 for (PetscInt j = lys; j < lye; j++)
1354 for (PetscInt i = lxs; i < lxe; i++)
1355 local_flux += ucont[k][j][i].z;
1359 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1360 *local_inflow_contribution += local_flux;
1363 face_id, local_flux);
1365 PetscFunctionReturn(0);
1369#define __FUNCT__ "Destroy_InletProfileFromFile"
1378 PetscFunctionBeginUser;
1379 if (self && self->
data) {
1383 PetscFree(self->
data);
1386 PetscFunctionReturn(0);
1407 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution);
1410 PetscReal *in, PetscReal *out);
1413#define __FUNCT__ "Create_OutletConservation"
1422 PetscFunctionBeginUser;
1424 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
1440 PetscFunctionReturn(0);
1444#define __FUNCT__ "PreStep_OutletConservation"
1449 PetscReal *local_inflow_contribution, PetscReal *local_outflow_contribution)
1451 PetscErrorCode ierr;
1454 DMDALocalInfo* info = &user->
info;
1455 PetscBool can_service;
1459 (void)local_inflow_contribution;
1461 PetscFunctionBeginUser;
1465 const PetscInt IM_nodes_global = user->
IM;
1466 const PetscInt JM_nodes_global = user->
JM;
1467 const PetscInt KM_nodes_global = user->
KM;
1468 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1471 PetscFunctionReturn(0);
1477 Cmpnts ***ucat, ***csi, ***eta, ***zet;
1479 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1480 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1481 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1482 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1483 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1485 PetscReal local_flux_out = 0.0;
1486 const PetscInt xs=info->xs, xe=info->xs+info->xm;
1487 const PetscInt ys=info->ys, ye=info->ys+info->ym;
1488 const PetscInt zs=info->zs, ze=info->zs+info->zm;
1489 const PetscInt mx=info->mx, my=info->my, mz=info->mz;
1492 PetscInt lxs = xs;
if (xs == 0) lxs = xs + 1;
1493 PetscInt lxe = xe;
if (xe == mx) lxe = xe - 1;
1494 PetscInt lys = ys;
if (ys == 0) lys = ys + 1;
1495 PetscInt lye = ye;
if (ye == my) lye = ye - 1;
1496 PetscInt lzs = zs;
if (zs == 0) lzs = zs + 1;
1497 PetscInt lze = ze;
if (ze == mz) lze = ze - 1;
1502 const PetscInt i_cell = xs + 1;
1503 const PetscInt i_face = xs;
1504 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1505 if (nvert[k][j][i_cell] < 0.1) {
1506 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);
1512 const PetscInt i_cell = xe - 2;
1513 const PetscInt i_face = xe - 2;
1514 for (
int k=lzs; k<lze; k++)
for (
int j=lys; j<lye; j++) {
1515 if (nvert[k][j][i_cell] < 0.1) {
1516 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);
1522 const PetscInt j_cell = ys + 1;
1523 const PetscInt j_face = ys;
1524 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1525 if (nvert[k][j_cell][i] < 0.1) {
1526 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);
1532 const PetscInt j_cell = ye - 2;
1533 const PetscInt j_face = ye - 2;
1534 for (
int k=lzs; k<lze; k++)
for (
int i=lxs; i<lxe; i++) {
1535 if (nvert[k][j_cell][i] < 0.1) {
1536 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);
1542 const PetscInt k_cell = zs + 1;
1543 const PetscInt k_face = zs;
1544 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1545 if (nvert[k_cell][j][i] < 0.1) {
1546 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);
1552 const PetscInt k_cell = ze - 2;
1553 const PetscInt k_face = ze - 2;
1554 for (
int j=lys; j<lye; j++)
for (
int i=lxs; i<lxe; i++) {
1555 if (nvert[k_cell][j][i] < 0.1) {
1556 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);
1564 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1565 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1566 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1567 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1568 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1571 *local_outflow_contribution += local_flux_out;
1573 PetscFunctionReturn(0);
1577#define __FUNCT__ "Apply_OutletConservation"
1586 PetscErrorCode ierr;
1590 DMDALocalInfo* info = &user->
info;
1591 PetscBool can_service;
1593 PetscFunctionBeginUser;
1596 const PetscInt IM_nodes_global = user->
IM;
1597 const PetscInt JM_nodes_global = user->
JM;
1598 const PetscInt KM_nodes_global = user->
KM;
1599 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1603 PetscFunctionReturn(0);
1611 PetscReal velocity_correction = (PetscAbsReal(user->
simCtx->
AreaOutSum) > 1e-12)
1622 Cmpnts ***ubcs, ***ucont, ***csi, ***eta, ***zet, ***ucat;
1624 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1625 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1626 ierr = DMDAVecGetArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1627 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1628 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1629 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1630 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1633 PetscInt xs = info->xs, xe = info->xs + info->xm;
1634 PetscInt ys = info->ys, ye = info->ys + info->ym;
1635 PetscInt zs = info->zs, ze = info->zs + info->zm;
1636 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1637 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1639 if (xs == 0) lxs = xs + 1;
1640 if (xe == mx) lxe = xe - 1;
1641 if (ys == 0) lys = ys + 1;
1642 if (ye == my) lye = ye - 1;
1643 if (zs == 0) lzs = zs + 1;
1644 if (ze == mz) lze = ze - 1;
1649 const PetscInt i_cell = xs + 1;
1650 const PetscInt i_face = xs;
1651 const PetscInt i_dummy = xs;
1652 for (PetscInt k = lzs; k < lze; k++) {
1653 for (PetscInt j = lys; j < lye; j++) {
1654 if (nvert[k][j][i_cell] < 0.1) {
1656 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1659 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);
1661 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));
1663 PetscReal Correction_flux = velocity_correction*Cell_Area;
1665 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1672 const PetscInt i_cell = xe - 2;
1673 const PetscInt i_face = xe - 2;
1674 const PetscInt i_dummy = xe - 1;
1675 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++){
1676 if(nvert[k][j][i_cell]<0.1){
1678 ubcs[k][j][i_dummy] = ucat[k][j][i_cell];
1681 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);
1683 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));
1685 PetscReal Correction_flux = velocity_correction*Cell_Area;
1687 ucont[k][j][i_face].
x = Uncorrected_local_flux + Correction_flux;
1693 const PetscInt j_cell = ys + 1;
1694 const PetscInt j_face = ys;
1695 const PetscInt j_dummy = ys;
1696 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1697 if(nvert[k][j_cell][i]<0.1){
1699 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1702 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);
1704 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));
1706 PetscReal Correction_flux = velocity_correction*Cell_Area;
1708 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1714 const PetscInt j_cell = ye - 2;
1715 const PetscInt j_face = ye - 2;
1716 const PetscInt j_dummy = ye - 1;
1717 for(PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++){
1718 if(nvert[k][j_cell][i]<0.1){
1720 ubcs[k][j_dummy][i] = ucat[k][j_cell][i];
1723 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);
1725 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));
1727 PetscReal Correction_flux = velocity_correction*Cell_Area;
1729 ucont[k][j_face][i].
y = Uncorrected_local_flux + Correction_flux;
1735 const PetscInt k_cell = zs + 1;
1736 const PetscInt k_face = zs;
1737 const PetscInt k_dummy = zs;
1738 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1739 if(nvert[k_cell][j][i]<0.1){
1741 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
1744 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));
1746 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));
1748 PetscReal Correction_flux = velocity_correction*Cell_Area;
1750 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
1756 const PetscInt k_cell = ze - 2;
1757 const PetscInt k_face = ze - 2;
1758 const PetscInt k_dummy = ze - 1;
1759 for(PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++){
1760 if(nvert[k_cell][j][i]<0.1){
1762 ubcs[k_dummy][j][i] = ucat[k_cell][j][i];
1765 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));
1767 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));
1769 PetscReal Correction_flux = velocity_correction*Cell_Area;
1771 ucont[k_face][j][i].
z = Uncorrected_local_flux + Correction_flux;
1779 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Ubcs, &ubcs); CHKERRQ(ierr);
1780 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
1781 ierr = DMDAVecRestoreArrayRead(user->
fda,user->
lUcat, (
const Cmpnts***)&ucat); CHKERRQ(ierr);
1782 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
1783 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
1784 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
1785 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1788 PetscFunctionReturn(0);
1792#define __FUNCT__ "PostStep_OutletConservation"
1797 PetscReal *local_inflow_contribution,
1798 PetscReal *local_outflow_contribution)
1800 PetscErrorCode ierr;
1803 DMDALocalInfo* info = &user->
info;
1804 PetscBool can_service;
1807 (void)local_inflow_contribution;
1809 PetscFunctionBeginUser;
1810 const PetscInt IM_nodes_global = user->
IM;
1811 const PetscInt JM_nodes_global = user->
JM;
1812 const PetscInt KM_nodes_global = user->
KM;
1813 ierr =
CanRankServiceFace(info, IM_nodes_global, JM_nodes_global, KM_nodes_global, face_id, &can_service); CHKERRQ(ierr);
1815 if (!can_service) PetscFunctionReturn(0);
1821 ierr = DMDAVecGetArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1822 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1824 PetscReal local_flux = 0.0;
1826 PetscInt xs = info->xs, xe = info->xs + info->xm;
1827 PetscInt ys = info->ys, ye = info->ys + info->ym;
1828 PetscInt zs = info->zs, ze = info->zs + info->zm;
1829 PetscInt mx = info->mx, my = info->my, mz = info->mz;
1831 PetscInt lxs = xs, lxe = xe, lys = ys, lye = ye, lzs = zs, lze = ze;
1832 if (xs == 0) lxs = xs + 1;
1833 if (xe == mx) lxe = xe - 1;
1834 if (ys == 0) lys = ys + 1;
1835 if (ye == my) lye = ye - 1;
1836 if (zs == 0) lzs = zs + 1;
1837 if (ze == mz) lze = ze - 1;
1842 const PetscInt i_cell = xs + 1;
1843 const PetscInt i_face = xs;
1844 for (PetscInt k = lzs; k < lze; k++) {
1845 for (PetscInt j = lys; j < lye; j++) {
1846 if (nvert[k][j][i_cell] < 0.1) {
1847 local_flux += ucont[k][j][i_face].
x;
1854 const PetscInt i_cell = xe - 2;
1855 const PetscInt i_face = xe - 2;
1856 for (PetscInt k = lzs; k < lze; k++) {
1857 for (PetscInt j = lys; j < lye; j++) {
1858 if (nvert[k][j][i_cell] < 0.1) {
1859 local_flux += ucont[k][j][i_face].
x;
1866 const PetscInt j_cell = ys + 1;
1867 const PetscInt j_face = ys;
1868 for (PetscInt k = lzs; k < lze; k++) {
1869 for (PetscInt i = lxs; i < lxe; i++) {
1870 if (nvert[k][j_cell][i] < 0.1) {
1871 local_flux += ucont[k][j_face][i].
y;
1878 const PetscInt j_cell = ye - 2;
1879 const PetscInt j_face = ye - 2;
1880 for (PetscInt k = lzs; k < lze; k++) {
1881 for (PetscInt i = lxs; i < lxe; i++) {
1882 if (nvert[k][j_cell][i] < 0.1) {
1883 local_flux += ucont[k][j_face][i].
y;
1890 const PetscInt k_cell = zs + 1;
1891 const PetscInt k_face = zs;
1892 for (PetscInt j = lys; j < lye; j++) {
1893 for (PetscInt i = lxs; i < lxe; i++) {
1894 if (nvert[k_cell][j][i] < 0.1) {
1895 local_flux += ucont[k_face][j][i].
z;
1902 const PetscInt k_cell = ze - 2;
1903 const PetscInt k_face = ze - 2;
1904 for (PetscInt j = lys; j < lye; j++) {
1905 for (PetscInt i = lxs; i < lxe; i++) {
1906 if (nvert[k_cell][j][i] < 0.1) {
1907 local_flux += ucont[k_face][j][i].
z;
1915 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
Ucont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1916 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1919 *local_outflow_contribution += local_flux;
1922 face_id, local_flux);
1924 PetscFunctionReturn(0);
1936 PetscFunctionBeginUser;
1938 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition is NULL");
1951 PetscFunctionReturn(0);
1956#define __FUNCT__ "MeasureDrivenFluxes"
1976 PetscReal *boundaryFlux,
1977 PetscReal *planarAverageFlux)
1979 PetscErrorCode ierr;
1980 DMDALocalInfo info = user->
info;
1983 PetscFunctionBeginUser;
1988 ierr = DMDAVecGetArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
1989 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
1992 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
1993 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
1994 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
1995 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
1996 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
1997 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2000 PetscReal localCurrentBoundaryFlux = 0.0;
2001 PetscReal localAveragePlanarVolumetricFluxTerm = 0.0;
2004 switch (direction) {
2008 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2009 if (nvert[k][j][i + 1] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
x;
2012 for (i = info.xs; i < lxe; i++) {
2013 for (k = lzs; k < lze; k++)
for (j = lys; j < lye; j++) {
2014 if (nvert[k][j][i + 1] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
x / (PetscReal)(info.mx - 1);
2021 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2022 if (nvert[k][j + 1][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
y;
2025 for (j = info.ys; j < lye; j++) {
2026 for (k = lzs; k < lze; k++)
for (i = lxs; i < lxe; i++) {
2027 if (nvert[k][j + 1][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
y / (PetscReal)(info.my - 1);
2034 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2035 if (nvert[k + 1][j][i] < 0.1) localCurrentBoundaryFlux += ucont[k][j][i].
z;
2038 for (k = info.zs; k < lze; k++) {
2039 for (j = lys; j < lye; j++)
for (i = lxs; i < lxe; i++) {
2040 if (nvert[k + 1][j][i] < 0.1) localAveragePlanarVolumetricFluxTerm += ucont[k][j][i].
z / (PetscReal)(info.mz - 1);
2045 SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG,
2046 "MeasureDrivenFluxes received an unknown driven direction '%c'.", direction);
2050 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lUcont, (
const Cmpnts***)&ucont); CHKERRQ(ierr);
2051 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2054 ierr = MPI_Allreduce(&localCurrentBoundaryFlux, boundaryFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2055 ierr = MPI_Allreduce(&localAveragePlanarVolumetricFluxTerm, planarAverageFlux, 1, MPI_DOUBLE, MPI_SUM, PETSC_COMM_WORLD); CHKERRQ(ierr);
2057 PetscFunctionReturn(0);
2096#define __FUNCT__ "Create_PeriodicDrivenConstant"
2103 PetscErrorCode ierr;
2104 PetscFunctionBeginUser;
2106 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition object is NULL in Create_PeriodicDrivenConstantFlux");
2110 ierr = PetscNew(&data); CHKERRQ(ierr);
2119 bc->
data = (
void*)data;
2136 PetscFunctionReturn(0);
2140#define __FUNCT__ "Initialize_PeriodicDrivenConstant"
2146 PetscErrorCode ierr;
2151 PetscFunctionBeginUser;
2157 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2158 "Configuration Error: Handler PERIODIC_DRIVEN_CONSTANT_FLUX on Face %s must be applied to a face with mathematical_type PERIODIC.",
2183 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2184 "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).",
2199 PetscBool trimfound;
2206 PetscFunctionReturn(0);
2210#define __FUNCT__ "PreStep_PeriodicDrivenConstant"
2215 PetscReal *local_inflow_contribution,
2216 PetscReal *local_outflow_contribution)
2218 PetscErrorCode ierr;
2223 PetscFunctionBeginUser;
2227 PetscFunctionReturn(0);
2233 PetscReal globalCurrentBoundaryFlux, globalAveragePlanarVolumetricFlux;
2235 &globalAveragePlanarVolumetricFlux); CHKERRQ(ierr);
2239 PetscReal globalBoundaryArea;
2265 if (globalBoundaryArea > 1.0e-12) {
2281 LOG_ALLOW(
GLOBAL,
LOG_INFO,
" - Avg Planar Volumetric Flux (Stable): %.6e\n", globalAveragePlanarVolumetricFlux);
2287 (void)local_inflow_contribution;
2288 (void)local_outflow_contribution;
2290 PetscFunctionReturn(0);
2294#define __FUNCT__ "Apply_PeriodicDrivenConstant"
2300 PetscErrorCode ierr;
2304 PetscBool can_service;
2306 PetscFunctionBeginUser;
2311 PetscFunctionReturn(0);
2316 PetscFunctionReturn(0);
2322 DMDALocalInfo info = user->
info;
2323 Cmpnts ***ucont, ***uch, ***csi, ***eta, ***zet;
2326 ierr = DMDAVecGetArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
2327 ierr = DMDAVecGetArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2328 ierr = DMDAVecGetArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2329 ierr = DMDAVecGetArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2330 ierr = DMDAVecGetArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2331 ierr = DMDAVecGetArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2333 PetscInt lxs = (info.xs == 0) ? 1 : info.xs;
2334 PetscInt lys = (info.ys == 0) ? 1 : info.ys;
2335 PetscInt lzs = (info.zs == 0) ? 1 : info.zs;
2336 PetscInt lxe = (info.xs + info.xm == info.mx) ? info.mx - 1 : info.xs + info.xm;
2337 PetscInt lye = (info.ys + info.ym == info.my) ? info.my - 1 : info.ys + info.ym;
2338 PetscInt lze = (info.zs + info.zm == info.mz) ? info.mz - 1 : info.zs + info.zm;
2343 PetscInt i_face = (face_id ==
BC_FACE_NEG_X) ? info.xs : info.mx - 2;
2344 PetscInt i_nvert = (face_id ==
BC_FACE_NEG_X) ? info.xs + 1 : info.mx - 2;
2346 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt j = lys; j < lye; j++) {
2347 if (nvert[k][j][i_nvert] < 0.1) {
2348 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);
2351 uch[k][j][i_face].
x = fluxTrim;
2357 PetscInt j_face = (face_id ==
BC_FACE_NEG_Y) ? info.ys : info.my - 2;
2358 PetscInt j_nvert = (face_id ==
BC_FACE_NEG_Y) ? info.ys + 1 : info.my - 2;
2360 for (PetscInt k = lzs; k < lze; k++)
for (PetscInt i = lxs; i < lxe; i++) {
2361 if (nvert[k][j_nvert][i] < 0.1) {
2362 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);
2365 uch[k][j_face][i].
y = fluxTrim;
2371 PetscInt k_face = (face_id ==
BC_FACE_NEG_Z) ? info.zs : info.mz - 2;
2372 PetscInt k_nvert = (face_id ==
BC_FACE_NEG_Z) ? info.zs + 1 : info.mz - 2;
2374 for (PetscInt j = lys; j < lye; j++)
for (PetscInt i = lxs; i < lxe; i++) {
2375 if (nvert[k_nvert][j][i] < 0.1) {
2376 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);
2379 uch[k_face][j][i].
z = fluxTrim;
2386 ierr = DMDAVecRestoreArray(user->
fda, user->
Ucont, &ucont); CHKERRQ(ierr);
2387 ierr = DMDAVecRestoreArray(user->
fda, user->
Bcs.
Uch, &uch); CHKERRQ(ierr);
2388 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lCsi, (
const Cmpnts***)&csi); CHKERRQ(ierr);
2389 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lEta, (
const Cmpnts***)&eta); CHKERRQ(ierr);
2390 ierr = DMDAVecRestoreArrayRead(user->
fda, user->
lZet, (
const Cmpnts***)&zet); CHKERRQ(ierr);
2391 ierr = DMDAVecRestoreArrayRead(user->
da, user->
lNvert, (
const PetscReal***)&nvert); CHKERRQ(ierr);
2393 PetscFunctionReturn(0);
2397#define __FUNCT__ "Destroy_PeriodicDrivenConstant"
2403 PetscFunctionBeginUser;
2406 if (self && self->
data) {
2408 PetscFree(self->
data);
2417 PetscFunctionReturn(0);
2442#define __FUNCT__ "Create_PeriodicDrivenInitial"
2449 PetscErrorCode ierr;
2450 PetscFunctionBeginUser;
2452 if (!bc) SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_NULL,
"Input BoundaryCondition object is NULL in Create_PeriodicDrivenInitial");
2456 ierr = PetscNew(&data); CHKERRQ(ierr);
2465 bc->
data = (
void*)data;
2480 PetscFunctionReturn(0);
2484#define __FUNCT__ "Initialize_PeriodicDrivenInitial"
2496 PetscErrorCode ierr;
2501 PetscFunctionBeginUser;
2507 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2508 "Configuration Error: Handler PERIODIC_DRIVEN_INITIAL_FLUX on Face %s must be applied to a face with mathematical_type PERIODIC.",
2525 PetscReal unused_flux;
2532 &unused_flux, &found); CHKERRQ(ierr);
2534 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_USER_INPUT,
2535 "Configuration Error: Handler PERIODIC_DRIVEN_INITIAL_FLUX on Face %s takes no 'target_flux' parameter; "
2536 "it measures the flux of the initial condition and holds that. Use handler 'constant_flux' to prescribe a target.",
2540 LOG_ALLOW(
GLOBAL,
LOG_INFO,
"Driven Flow (Dir %c): target volumetric flux will be latched from the initial state.\n",
2544 PetscBool trimfound;
2551 PetscFunctionReturn(0);
2555#define __FUNCT__ "PreStep_PeriodicDrivenInitial"
2567 PetscReal *local_inflow_contribution,
2568 PetscReal *local_outflow_contribution)
2570 PetscErrorCode ierr;
2574 PetscFunctionBeginUser;
2578 PetscReal boundaryFlux, planarAverageFlux;
2592 PetscFunctionReturn(0);
2596 &boundaryFlux, &planarAverageFlux); CHKERRQ(ierr);
2602 "Driven Flow (Dir %c): latched initial volumetric flux %.6e as the target.\n",
2611 local_inflow_contribution,
2612 local_outflow_contribution); CHKERRQ(ierr);
2614 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_InletVelocity(BoundaryCondition *self, BCContext *ctx)
Applies a Cartesian inlet velocity through the common face-layout path.
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.
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 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.
static Cmpnts EvaluateInletCartesianVelocity(const BoundaryCondition *self, BCFace face_id, PetscInt i, PetscInt j, PetscInt k, Cmpnts metric, PetscReal sign)
Evaluates one existing inlet mode as a Cartesian boundary velocity.
PetscErrorCode Create_WallNoSlip(BoundaryCondition *bc)
Implementation of Create_WallNoSlip().
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_INLET_PARABOLIC
@ BC_HANDLER_INLET_CONSTANT_VELOCITY
@ BC_HANDLER_PERIODIC_DRIVEN_INITIAL_FLUX
@ BC_HANDLER_PERIODIC_DRIVEN_CONSTANT_FLUX
@ BC_HANDLER_INLET_PROFILE_FROM_FILE
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
PetscReal drivenFluxMeasured
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.