In order to enable diffusion in an explicit way, this routine solves the diffusion equation in a very basic way using operator splitting. Use it with caution! This is only done within the computational domain of the obstacles.
{
int i, j, k, n;
double dxfac, dyfac, dzfac;
double coefficient_solid;
double alpha_solid_x, alpha_solid_y, alpha_solid_z;
double *temperature_1D, *temperature_1D_future;
double *mass;
double energy_left, energy_right;
double temperature_right_gas, temerpature_left_gas;
double A;
double heat_transfer_coefficient;
int *dom_1D;
int dom_counter;
int i_local_min, i_local_max;
int condition;
dom_counter = 0;
i_local_min = 0;
i_local_max = 0;
temperature_right_gas = 0.0;
temerpature_left_gas = 0.0;
A = 0.0;
heat_transfer_coefficient = 0.0;
condition = 0;
if (
dimension == 3) volume = dxfac * dyfac * dzfac;
dxfac = dxfac*dxfac;
dyfac = dyfac*dyfac;
dzfac = dzfac*dzfac;
if (
dimension > 0) alpha_solid_x = coefficient_solid *
dt / (dxfac);
if (
dimension > 1) alpha_solid_y = coefficient_solid *
dt / (dyfac);
if (
dimension > 2) alpha_solid_z = coefficient_solid *
dt / (dzfac);
if ((alpha_solid_x >= 0.3) && (
dimension > 0)) {
dt = (0.3 * dxfac) / coefficient_solid;
}
if ((alpha_solid_y >= 0.3) && (
dimension > 1)) {
dt = (0.3 * dyfac) / coefficient_solid;
}
if ((alpha_solid_z >= 0.3) && (
dimension > 2)) {
dt = (0.3 * dzfac) / coefficient_solid;
}
#ifdef _OPENMP
#pragma omp parallel default(none) \
private(j, i, k, n, temperature_1D, dom_1D, \
temperature_1D_future, mass, dom_counter, \
i_local_min, i_local_max, energy_left, energy_right, \
condition, heat_transfer_coefficient) \
shared(x, y, z, dom, rho, pre, dt, dxfac, \
dyfac, dzfac, alpha_solid_x, gasconstant, A, \
dimension, volume, \
specific_heat_capacity_gas, \
specific_heat_capacity_obstacle)
{
#endif
init_diffusion(&temperature_1D, &temperature_1D_future, &mass, &dom_1D);
for (k = 0; k <
z; k++) {
#ifdef _OPENMP
#pragma omp for schedule(static)
#endif
for (j = 0; j <
y; j++) {
condition = 0;
i_local_min = 0;
i_local_max = 0;
while (condition == 0) {
dom_counter = 0;
energy_left = 0.0;
energy_right = 0.0;
for (i = i_local_min; i <
x; i++) {
dom_1D[i] =
dom[i][j][k];
if (dom_1D[i] == 1) {
if (dom_counter == 0) i_local_min = i;
dom_counter++;
} else {
if (dom_counter > 0) {
i_local_max = i - 1;
break;
}
}
if (i == (x - 1)) {
i_local_max = i;
if (dom_counter == 0) i_local_min = i;
}
}
if (i == x) {
condition = 1;
}
if (i_local_min != 0) {
energy_left = heat_transfer_coefficient * A * (temperature_1D[i_local_min - 1] - temperature_1D[i_local_min]) *
dt;
}
if (i_local_max != (x - 1)) {
energy_right = heat_transfer_coefficient * A * (temperature_1D[i_local_max + 1] - temperature_1D[i_local_max]) *
dt;
}
if ((energy_left <= 0) && (i_local_min != 0)) {
temperature_1D[i_local_min - 1] = temperature_1D[i_local_min - 1] + fabs(energy_left / (
specific_heat_capacity_gas * mass[i_local_min - 1]));
pre[i_local_min - 1][j][k] = (
gasconstant *
rho[i_local_min - 1][j][k]) * temperature_1D[i_local_min - 1];
pre[i_local_min][j][k] = (
gasconstant *
rho[i_local_min][j][k]) * temperature_1D[i_local_min];
}
if ((energy_left > 0) && (i_local_min != 0)) {
temperature_1D[i_local_min - 1] = temperature_1D[i_local_min - 1] - fabs(energy_left / (
specific_heat_capacity_gas * mass[i_local_min - 1]));
pre[i_local_min - 1][j][k] = (
gasconstant *
rho[i_local_min - 1][j][k]) * temperature_1D[i_local_min - 1];
pre[i_local_min][j][k] = (
gasconstant *
rho[i_local_min][j][k]) * temperature_1D[i_local_min];
}
if ((energy_right > 0) && (i_local_max != (x - 1))) {
temperature_1D[i_local_max + 1] = temperature_1D[i_local_max + 1] - fabs(energy_right / (
specific_heat_capacity_gas * mass[i_local_max + 1]));
pre[i_local_max][j][k] = (
gasconstant *
rho[i_local_max][j][k]) * temperature_1D[i_local_max];
pre[i_local_max + 1][j][k] = (
gasconstant *
rho[i_local_max + 1][j][k]) * temperature_1D[i_local_max + 1];
}
if ((energy_right <= 0) && (i_local_max != (x - 1))) {
temperature_1D[i_local_max + 1] = temperature_1D[i_local_max + 1] + fabs(energy_right / (
specific_heat_capacity_gas * mass[i_local_max + 1]));
pre[i_local_max][j][k] = (
gasconstant *
rho[i_local_max][j][k]) * temperature_1D[i_local_max];
pre[i_local_max + 1][j][k] = (
gasconstant *
rho[i_local_max + 1][j][k]) * temperature_1D[i_local_max + 1];
}
if (dom_counter > 2) {
for (n = i_local_min + 1; n < i_local_max; n++) {
temperature_1D_future[n] = alpha_solid_x * temperature_1D[n + 1] +
(1 - 2 * alpha_solid_x) * temperature_1D[n] +
alpha_solid_x * temperature_1D[n - 1];
}
for (i = i_local_min + 1; i < i_local_max; i++) {
}
}
for (i = i_local_min; i < i_local_max; i++) {
temperature_1D[i] = 0.0;
temperature_1D_future[i] = 0.0;
mass[i] = 0.0;
dom_1D[i] = 0;
}
i_local_min = i_local_max + 1;
}
}
}
free_diffusion(&temperature_1D, &temperature_1D_future, &mass, &dom_1D);
#ifdef _OPENMP
}
#endif
#ifdef _OPENMP
#pragma omp parallel default(none) \
private(j, i, k, n, temperature_1D, dom_1D, \
temperature_1D_future, mass, dom_counter, \
i_local_min, i_local_max, energy_left, \
condition, energy_right, \
heat_transfer_coefficient) \
shared(x, y, z, dom, rho, pre, dt, dxfac, \
dyfac, dzfac, alpha_solid_y, \
gasconstant, A, dimension, volume, \
specific_heat_capacity_gas, \
specific_heat_capacity_obstacle)
{
#endif
init_diffusion(&temperature_1D, &temperature_1D_future, &mass, &dom_1D);
for (k = 0; k <
z; k++) {
#ifdef _OPENMP
#pragma omp for schedule(static)
#endif
for (i = 0; i <
x; i++) {
condition = 0;
i_local_min = 0;
i_local_max = 0;
while (condition == 0) {
dom_counter = 0;
energy_left = 0.0;
energy_right = 0.0;
for (j = i_local_min; j <
y; j++) {
dom_1D[j] =
dom[i][j][k];
if (dom_1D[j] == 1) {
if (dom_counter == 0) i_local_min = j;
dom_counter++;
} else {
if (dom_counter > 0) {
i_local_max = j - 1;
break;
}
}
if (j == (y - 1)) {
i_local_max = j;
if (dom_counter == 0) i_local_min = j;
}
}
if (j == y) {
condition = 1;
}
if (i_local_min != 0) {
energy_left = heat_transfer_coefficient * A * (temperature_1D[i_local_min - 1] - temperature_1D[i_local_min]) *
dt;
}
if (i_local_max != (y - 1)) {
energy_right = heat_transfer_coefficient * A * (temperature_1D[i_local_max + 1] - temperature_1D[i_local_max]) *
dt;
}
if ((energy_left <= 0) && (i_local_min != 0)) {
temperature_1D[i_local_min - 1] = temperature_1D[i_local_min - 1] + fabs(energy_left / (
specific_heat_capacity_gas * mass[i_local_min - 1]));
pre[i][i_local_min - 1][k] = (
gasconstant *
rho[i][i_local_min - 1][k]) * temperature_1D[i_local_min - 1];
pre[i][i_local_min][k] = (
gasconstant *
rho[i][i_local_min][k]) * temperature_1D[i_local_min];
}
if ((energy_left > 0) && (i_local_min != 0)) {
temperature_1D[i_local_min - 1] = temperature_1D[i_local_min - 1] - fabs(energy_left / (
specific_heat_capacity_gas * mass[i_local_min - 1]));
pre[i][i_local_min - 1][k] = (
gasconstant *
rho[i][i_local_min - 1][k]) * temperature_1D[i_local_min - 1];
pre[i][i_local_min][k] = (
gasconstant *
rho[i][i_local_min][k]) * temperature_1D[i_local_min];
}
if ((energy_right > 0) && (i_local_max != (y - 1))) {
temperature_1D[i_local_max + 1] = temperature_1D[i_local_max + 1] - fabs(energy_right / (
specific_heat_capacity_gas * mass[i_local_max + 1]));
pre[i][i_local_max][k] = (
gasconstant *
rho[i][i_local_max][k]) * temperature_1D[i_local_max];
pre[i][i_local_max + 1][k] = (
gasconstant *
rho[i][i_local_max + 1][k]) * temperature_1D[i_local_max + 1];
}
if ((energy_right <= 0) && (i_local_max != (y - 1))) {
temperature_1D[i_local_max + 1] = temperature_1D[i_local_max + 1] + fabs(energy_right / (
specific_heat_capacity_gas * mass[i_local_max + 1]));
pre[i][i_local_max][k] = (
gasconstant *
rho[i][i_local_max][k]) * temperature_1D[i_local_max];
pre[i][i_local_max + 1][k] = (
gasconstant *
rho[i][i_local_max + 1][k]) * temperature_1D[i_local_max + 1];
}
if (dom_counter > 2) {
for (n = i_local_min + 1; n < i_local_max; n++) {
temperature_1D_future[n] = alpha_solid_y * temperature_1D[n + 1] +
(1 - 2 * alpha_solid_y) * temperature_1D[n] +
alpha_solid_y * temperature_1D[n - 1];
}
for (j = i_local_min + 1; j < i_local_max; j++) {
}
for (j = i_local_min; j < i_local_max; j++) {
temperature_1D[j] = 0.0;
temperature_1D_future[j] = 0.0;
mass[j] = 0.0;
dom_1D[j] = 0;
}
}
i_local_min = i_local_max + 1;
}
}
}
free_diffusion(&temperature_1D, &temperature_1D_future, &mass, &dom_1D);
#ifdef _OPENMP
}
#endif
#ifdef _OPENMP
#pragma omp parallel default(none) \
private(j, i, k, n, temperature_1D, dom_1D, \
temperature_1D_future, mass, dom_counter, \
i_local_min, i_local_max, energy_left, \
condition, energy_right, \
heat_transfer_coefficient) \
shared(x, y, z, dom, rho, pre, dt, dxfac, \
dyfac, dzfac, alpha_solid_z, gasconstant, A, \
dimension, volume, \
specific_heat_capacity_gas, \
specific_heat_capacity_obstacle)
{
#endif
init_diffusion(&temperature_1D, &temperature_1D_future, &mass, &dom_1D);
for (j = 0; j <
y; j++) {
#ifdef _OPENMP
#pragma omp for schedule(static)
#endif
for (i = 0; i <
x; i++) {
condition = 0;
i_local_min = 0;
i_local_max = 0;
while (condition == 0) {
dom_counter = 0;
energy_left = 0.0;
energy_right = 0.0;
for (k = i_local_min; k <
z; k++) {
dom_1D[k] =
dom[i][j][k];
if (dom_1D[k] == 1) {
if (dom_counter == 0) i_local_min = k;
dom_counter++;
} else {
if (dom_counter > 0) {
i_local_max = k - 1;
break;
}
}
if (k == (z - 1)) {
i_local_max = k;
if (dom_counter == 0) i_local_min = k;
}
}
if (k == z) {
condition = 1;
}
if (i_local_min != 0) {
energy_left = heat_transfer_coefficient * A * (temperature_1D[i_local_min - 1] - temperature_1D[i_local_min]) *
dt;
}
if (i_local_max != (z - 1)) {
energy_right = heat_transfer_coefficient * A * (temperature_1D[i_local_max + 1] - temperature_1D[i_local_max]) *
dt;
}
if ((energy_left <= 0) && (i_local_min != 0)) {
temperature_1D[i_local_min - 1] = temperature_1D[i_local_min - 1] + fabs(energy_left / (
specific_heat_capacity_gas * mass[i_local_min - 1]));
pre[i][j][i_local_min - 1] = (
gasconstant *
rho[i][j][i_local_min - 1]) * temperature_1D[i_local_min - 1];
pre[i][j][i_local_min] = (
gasconstant *
rho[i][j][i_local_min]) * temperature_1D[i_local_min ];
}
if ((energy_left > 0) && (i_local_min != 0)) {
temperature_1D[i_local_min - 1] = temperature_1D[i_local_min - 1] - fabs(energy_left / (
specific_heat_capacity_gas * mass[i_local_min - 1]));
pre[i][j][i_local_min - 1] = (
gasconstant *
rho[i][j][i_local_min - 1]) * temperature_1D[i_local_min - 1];
pre[i][j][i_local_min] = (
gasconstant *
rho[i][j][i_local_min]) * temperature_1D[i_local_min ];
}
if ((energy_right > 0) && (i_local_max != (z - 1))) {
temperature_1D[i_local_max + 1] = temperature_1D[i_local_max + 1] - fabs(energy_right / (
specific_heat_capacity_gas * mass[i_local_max + 1]));
pre[i][j][i_local_max] = (
gasconstant *
rho[i][j][i_local_max]) * temperature_1D[i_local_max ];
pre[i][j][i_local_max + 1] = (
gasconstant *
rho[i][j][i_local_max + 1]) * temperature_1D[i_local_max + 1];
}
if ((energy_right <= 0) && (i_local_max != (z - 1))) {
temperature_1D[i_local_max + 1] = temperature_1D[i_local_max + 1] + fabs(energy_right / (
specific_heat_capacity_gas * mass[i_local_max + 1]));
pre[i][j][i_local_max] = (
gasconstant *
rho[i][j][i_local_max]) * temperature_1D[i_local_max ];
pre[i][j][i_local_max + 1] = (
gasconstant *
rho[i][j][i_local_max + 1]) * temperature_1D[i_local_max + 1];
}
if (dom_counter > 2) {
for (n = i_local_min + 1; n < i_local_max; n++) {
temperature_1D_future[n] = alpha_solid_z * temperature_1D[n + 1] +
(1 - 2 * alpha_solid_z) * temperature_1D[n] +
alpha_solid_z * temperature_1D[n - 1];
}
for (k = i_local_min + 1; k < i_local_max; k++) {
}
for (k = i_local_min; k < i_local_max; k++) {
temperature_1D[k] = 0.0;
temperature_1D_future[k] = 0.0;
mass[k] = 0.0;
dom_1D[k] = 0;
}
}
i_local_min = i_local_max + 1;
}
}
}
free_diffusion(&temperature_1D, &temperature_1D_future, &mass, &dom_1D);
#ifdef _OPENMP
}
#endif
return 0;
}