I am currently implementing a computational fluid dynamics algorithm in C. It is already working for 2d systems and now I am working on it solving axisymmetric systems.
During the simulation all the data are stored in several 2-dimensional arrays (for the 2-d simulations) and 3-dimensional arrays (for the axisymmetric one).
Currently I have a solver function to solve several of the equations.
void solver(double ** data, Coefficients *coeff, Grid *grid)
Where:
data
contains the array I want to store the solved equations in
This works fine for the 2d system. When doing the axisymmetric system I would like to re-use this function without having to re-write or change it to take a 3d array, as I only need to solve one slice along the axis.
To do this I am thinking of creating a new 2-d array that holds all the pointers to the 2-d slice of the 3-d array.
I have been playing around with some test code to try out this concept but I can't get it to produce output that makes sense. This is what I have come up with so far:
#include <stdlib.h>
#include <stdio.h>
double *** alloc_3d_matrix(int x_dim, int y_dim, int z_dim)
{
int i, j;
double *** m;
m = calloc(x_dim, sizeof(double**));
for (i = 0; i < x_dim; i++)
{
m[i] = calloc(y_dim, sizeof(double*));
for (j = 0; j < y_dim; j++)
{
m[i][j] = calloc(z_dim, sizeof(double));
}
}
return m;
}
double *** alloc_2d_matrix(int x_dim, int y_dim)
{
int i;
double *** m;
m = calloc(x_dim, sizeof(double*));
for (i = 0; i < y_dim; i++)
{
m[i] = calloc(y_dim, sizeof(double));
}
return m;
}
void free_3d_matrix(void *** m, int x_dim, int y_dim)
{
int i, j;
for (i = 0; i < x_dim; i++)
{
for (j = 0; j < y_dim; j++)
{
free(m[i][j]);
}
free(m[i]);
}
free(m);
}
void free_2d_matrix(void ***m, int x_dim)
{
int i;
for (i = 0; i < x_dim; i++)
{
free(m[i]);
}
free(m);
}
void increment(double ** slice)
{
int i, j;
int sum = 0;
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
sum++;
slice[i][j] = sum;
}
}
}
int main()
{
int i, j;
double *** d3, ***d2;
FILE *fp;
fp = fopen("test.txt", "w");
d2 = (double***)alloc_2d_matrix(5, 5);
d3 = alloc_3d_matrix(5, 5, 5);
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
d2[i][j] = &d3[i][j][0];
}
}
increment(*d2);
for (i = 0; i < 5; i++)
{
for (j = 0; j < 5; j++)
{
fprintf(fp,"%f, %p, %p\n", d3[i][j][0], &d3[i][j][0], d2[i][j]);
}
}
fclose(fp);
free_3d_matrix(d3, 5, 5);
return 0;
}
I feel like this should produce an output that looks like this:
1.000000, 00E5A4B0, 00E5A4B0
2.000000, 00E5FCA8, 00E5FCA8
3.000000, 00E5FD00, 00E5FD00
4.000000, 00E5FBA0, 00E5FBA0
5.000000, 00E5F678, 00E5F678
etc.
Instead I'm getting an output of this:
1.000000, 00E5A4B0, 00E5A4B0
6.000000, 00E5FCA8, 00E5FCA8
11.000000, 00E5FD00, 00E5FD00
16.000000, 00E5FBA0, 00E5FBA0
21.000000, 00E5F678, 00E5F678
0.000000, 00E5FB48, 00E5FB48
0.000000, 00E5F728, 00E5F728
0.000000, 00E5F620, 00E5F620
0.000000, 00E5FD58, 00E5FD58
I'm not sure where I have gone wrong in my code and would appreciate any help.
Edit:
Added the rest of the functions.
alloc_2d_matrixis a good indicator that you're doing something you should not do. Can you please show the function (or at least its declaration)?alloc_2d_matrixfunction is not correct. It allocates an array of arrays ofdouble, instead of an array of arrays of pointers todouble. If you compare it to thealloc_3d_matrixfunction you will undoubtedly see that it returns the same type, which means it needs to do just about the same thing (except the innermost allocation). You can avoid this problem by not using the specific types in thesizeofexpression, but instead do e.g.sizeof(*m)for the outer level, andsizeof(*m[i])for the inner.