Specify both spatial and temporal temperature profile on a wall zone


In some heat transfer simulations, user will want to impose a temperature profile on a given wall zone that is
varying both spatially and temporally. That is, at different times, the spatial profiles are different. Often, user
has a tabular data that is obtained from an experiment.

Specifying a temporal only OR spatial only can be done using profile.

How about both ?
A UDF has been written to read an input file containing both the spatial and temporal variations of a scalar
quantity. The format of this file follows the standard profile format closely and is explained at the end of this
file.

The UDF contains three sections:
----------------------------------------------------
- ReadFile
Type: On-Demand
Purpose: To read the input file table
- GetData
Type: Function
Purpose: Interpolate data
- Tspec
Type: Profile
Purpose: Assign data to each face of the face zone

How to use it ?
-----------------------
- The input file needs to be named as DataFile (can be changed inside the UDF)
- Execute the ReadFile on-demand function after reading the case file and before
reading the data file
This must be done everytime Fluent is restarted
- Hook the Tspec profile function to the temperature field of a wall zone
- Iterate as usual

The format of input file is given below:
-----------------------------------------------------------
- The first line contains the NPtsTm (number of time steps points) and
NPtsData (number of data points)
- Next line is a blank
- Next NPtsTm lines contain the time data
- Next line is a blank
- Next NPtsData lines contain the x-coordinates data
- Next line is a blank
- Next NPtsData lines contain the y-coordinates data
- Next line is a blank
- Next NPtsData lines contain the z-coordinates data
- Next line is a blank
- Next NptsData lines contain the first scalar data at time#0
- Next line is a blank
- Next NptsData lines contain the first scalar data at time#1
- ... so on ... until the last time data is given

%-------------------------------------------------------------------------------------------------------------------------------------------------------------------%

#include "udf.h"

int NPtsTm,NPtsData;
int DataIsRead = 0;
float *tmarr,*xarr,*yarr,*zarr,**Tarr;

DEFINE_ON_DEMAND(ReadFile)
{
int n,i;
float data;
FILE* fp;

fp = fopen("DataFile","r");
if ( fp!=NULL )
Message("Reading file n");
else
Message("Error in opening file n");

fscanf(fp,"%d %dn",&NPtsTm,&NPtsData);
Message("n");
Message("There are %d time entries and %d spatial entriesn",NPtsTm,NPtsData);

/* Dynamic allocation for 1D array */

tmarr = (float *) malloc(NPtsTm*sizeof(float));
xarr = (float *) malloc(NPtsData*sizeof(float));
yarr = (float *) malloc(NPtsData*sizeof(float));
zarr = (float *) malloc(NPtsData*sizeof(float));

/* Dynamic allocation for 2D array */
{
float *temp;
temp = (float * ) malloc(NPtsTm*NPtsData*sizeof(float));
Tarr = (float **) malloc(NPtsTm*sizeof(float *));

for(n=0;n<NPtsTm;n++)
Tarr[n] = temp + n*NPtsData;
}

if ( (tmarr==NULL)||(xarr==NULL)||(yarr==NULL)||(zarr==NULL)||(Tarr==NULL) )
Message("Memory allocation error n");

fscanf(fp,"n");
Message("n");
Message("The following is the %d time entriesn",NPtsTm);
for ( n=0;n<NPtsTm;n++ )
{
fscanf(fp,"%f n",&data);
tmarr[n] = data;
Message(" %fn",data);
}

fscanf(fp,"n");
for ( i=0;i<NPtsData;i++ )
{
fscanf(fp,"%f n",&data);
xarr[i] = data;
}

fscanf(fp,"n");
for ( i=0;i<NPtsData;i++ )
{
fscanf(fp,"%f n",&data);
yarr[i] = data;
}

fscanf(fp,"n");
for ( i=0;i<NPtsData;i++ )
{
fscanf(fp,"%f n",&data);
zarr[i] = data;
}

for ( n=0;n<NPtsTm;n++ )
{
fscanf(fp,"n");
for ( i=0;i<NPtsData;i++ )
{
fscanf(fp,"%f n",&data);
Tarr[n][i] = data;
}
}

DataIsRead = 1;
fclose(fp);

/* Output check */

Message("n");
Message("The following is the %d coordinate entriesn",NPtsData);
for ( i=0;i<NPtsData;i++ )
{
Message(" %f %f %fn",xarr[i],yarr[i],zarr[i]);
}

for ( n=0;n<NPtsTm;n++ )
{
Message("n");
Message("The following is scalar data for time entry # %dn",n);
for ( i=0;i<NPtsData;i++ )
{
Message(" %fn",Tarr[n][i]);
}
}
}

/*----------------------------------------------------------------------------*/

float GetData(float xf, float yf, float zf, float tm)
{
int n,nL,nU,i;
float tmL,tmU,data,dataL,dataU,sf,smin;

tm += 1.0e-7;

/* Find the time bracket */

nL = 0;
nU = 1;
tmL = tmarr[nL];
tmU = tmarr[nU];

for ( n=0;n<NPtsTm;n++ )
{
if ( (tm>=tmarr[n])&&(tm<=tmarr[n+1]) )
{
nL = n;
nU = n+1;
tmL = tmarr[nL];
tmU = tmarr[nU];
break;
}
}

/* Find data at the lower and upper time bound */

smin = 1.0e30;
dataL = 0.0;
dataU = 0.0;

for ( i=0;i<NPtsData;i++ )
{
sf = sqrt( pow((xarr[i]-xf),2) + pow((yarr[i]-yf),2) + pow((zarr[i]-zf),2) );
if ( sf<=smin )
{
smin = sf;
dataL = Tarr[nL][i];
dataU = Tarr[nU][i];
}
}

/* Interpolate between lower and upper time values */

data = dataL + ( tm - tmL )/( tmU - tmL )*( dataU - dataL );

return data;
}

/*----------------------------------------------------------------------------*/

DEFINE_PROFILE(Tspec,tf,pos)
{
face_t f;
float tm,xf[ND_ND];

tm = RP_Get_Real("flow-time");

begin_f_loop(f,tf)
{
F_CENTROID(xf,f,tf);
F_PROFILE(f,tf,pos) = GetData(xf[0],xf[1],xf[2],tm);
}
end_f_loop(f,tf)
}





Show Form
No comments yet. Be the first to add a comment!