Changes between Initial Version and Version 1 of cypress/Programming/HeatMassTransfer/ex25.c


Ignore:
Timestamp:
May 14, 2015 3:27:28 PM (7 years ago)
Author:
cmaggio
Comment:

migrated content from ccs wiki

Legend:

Unmodified
Added
Removed
Modified
  • cypress/Programming/HeatMassTransfer/ex25.c

    v1 v1  
     1= Ex25.c =
     2{{{#!C
     3/*
     4  Large Scale Computing
     5  2D Convective Heat/Mass Transfer
     6  ex25.c : Numerical Analysis
     7  Solve for
     8  duphi/dx dvphi/dy = d2phi/dx2 + d2phi/dy2
     9  the boundary conditions:
     10  phi = 0 along y=0, phi = 1 along y = 1
     11  dphi/dx=0 along y=+-0.5
     12 
     13 */
     14#include<stdio.h>
     15#include<stdlib.h>
     16#include<math.h>
     17#include"slu.h"
     18 
     19/* min and max macros */
     20#define max(a,b)        (((a) > (b)) ? (a) : (b))
     21#define min(a,b)        (((a) < (b)) ? (a) : (b))
     22 
     23#define NUM 100  /* number of points for x and y*/
     24 
     25int main(int argc, char **argv){
     26  int i,j,k,n;
     27  int iw,ie,is,in;
     28  double d,x,y,u0,u,v;
     29  double dl;
     30  double ae,aw,an,as,ap;
     31  double phi[NUM * NUM]; /* define 1D array of length NUM * NUM */
     32  double rhs[NUM * NUM]; /* define 1D array of length NUM * NUM */
     33  double nzval[5 * NUM * NUM]; /* non-zero elements of A */
     34  int colind[5 * NUM * NUM]; /* column indices of nonzeros */
     35  int rowptr[NUM * NUM + 1]; /**/
     36  int nnz;
     37  FILE *fp;
     38 
     39  if (argc < 3){
     40    printf("Usage:%s [D] [U0]\n",argv[0]);
     41    exit(-1);
     42  }
     43 
     44  /* set parameters */
     45  d = atof(argv[1]);
     46  u0 = atof(argv[2]);
     47  printf("D=%e U0=%e\n",d,u0);
     48 
     49  /*assuming dx = dy : domain is 1x1 */
     50  dl = 1.0 / (double)(NUM - 1);
     51 
     52  /* initial & boundary conditions */
     53  for (n = 0 ; n < NUM * NUM ; n++){
     54    phi[n] = 0.0;
     55  }
     56  for (i = 0 ; i < NUM ; i++){
     57    n = i + NUM * (NUM - 1);
     58    phi[n] = 1.0; /* fixed phi=1 */
     59  }
     60 
     61  /* Setup Matrix A and RHS */
     62  nnz = 0;
     63  for (n = 0 ; n < NUM * NUM ; n++){
     64    /* compute i,j indices */
     65    i = n % NUM; /* i is residual */
     66    j = n / NUM; /* j is division */
     67    ie = n + 1;
     68    iw = n - 1;
     69    in = n + NUM;
     70    is = n - NUM;
     71 
     72    /* (x,y) at p-pont */
     73    x = -0.5 + (double)i / (double)(NUM - 1);
     74    y = (double)j / (double)(NUM - 1);
     75 
     76    /* set general RHS */
     77    rhs[n] = 0.0;
     78 
     79    /* set first nonzero column of row index(i,j) */
     80    rowptr[n] = nnz;
     81 
     82    /* general coefficients */
     83    /* (u,v) = u0(x,-y) */
     84    u = u0 * (x + dl * 0.5); /* u at e-point*/
     85    ae = d / dl + max(-u,0.0);
     86    u = u0 * (x - dl * 0.5); /* u at w-point*/
     87    aw = d / dl + max(u,0.0);
     88    v = -u0 * (y + dl * 0.5); /* v at n-point*/
     89    an = d / dl + max(-v,0.0);
     90    v = -u0 * (y - dl * 0.5); /* v at s-point*/
     91    as = d / dl + max(v,0.0);
     92    ap = ae + aw + an + as;
     93 
     94    /* sounth */
     95    if (is >= 0){
     96      nzval[nnz] = as;
     97      colind[nnz] = is;
     98      nnz++;
     99    }     
     100 
     101    /* west */
     102    if (iw >= 0){
     103      nzval[nnz] = aw;
     104      colind[nnz] = iw;
     105      nnz++;
     106    }
     107 
     108    /* diagonal Element */
     109    nzval[nnz] = -ap;
     110    colind[nnz] = n;
     111    nnz++;
     112 
     113    /* east */
     114    if (ie < NUM * NUM){
     115      nzval[nnz] = ae;
     116      colind[nnz] = ie;
     117      nnz++;
     118    }
     119 
     120    /* north */
     121    if (in < NUM * NUM){
     122      nzval[nnz] = an;
     123      colind[nnz] = in;
     124      nnz++;
     125    }
     126  }
     127  rowptr[NUM * NUM] = nnz;
     128 
     129 
     130  /* Setting Boundary Conditions */
     131  for (i = 0 ; i < NUM ; i++){
     132    /* Bottom fixed phi=0 */
     133    n = i;
     134    for (k = rowptr[n] ; k < rowptr[n+1] ; k++){
     135      if (n == colind[k]){
     136        nzval[k] = -1.0; /* diag=-1 */
     137        rhs[n] = nzval[k] * phi[n];
     138      }else{
     139        nzval[k] = 0.0; /* off-diag=0 */
     140      }
     141    }
     142    /* Top fixed phi=1 */
     143    n = i + NUM * (NUM - 1);
     144    for (k = rowptr[n] ; k < rowptr[n+1] ; k++){
     145      if (n == colind[k]){
     146        nzval[k] = -1.0; /* diag=-1 */
     147        rhs[n] = nzval[k] * phi[n];
     148      }else{
     149        nzval[k] = 0.0; /* off-diag=0 */
     150      }
     151    }
     152  }
     153  for (j = 0 ; j < NUM ; j++){
     154    /* Left  dphi/dx=0 */
     155    n = j * NUM;
     156    ie = n + 1;
     157    rhs[n] = 0.0;
     158    for (k = rowptr[n] ; k < rowptr[n+1] ; k++){
     159      if (n == colind[k]){
     160        nzval[k] = -1.0; /* diag=-1 */
     161      }else{
     162        if (ie == colind[k]){
     163          nzval[k] = 1.0; /* off-diag_e=1 */
     164        }else{
     165          nzval[k] = 0.0; /* off-diag_else=0 */
     166        }
     167      }
     168    }
     169    /* Right dphi/dx=0 */
     170    n = NUM - 1 + j * NUM;
     171    iw = n - 1;
     172    rhs[n] = 0.0;
     173    for (k = rowptr[n] ; k < rowptr[n+1] ; k++){
     174      if (n == colind[k]){
     175        nzval[k] = -1.0; /* diag=-1 */
     176      }else{
     177        if (iw == colind[k]){
     178          nzval[k] = 1.0; /* off-diag_w=1 */
     179        }else{
     180          nzval[k] = 0.0; /* off-diag_else=0 */
     181        }
     182      }
     183    }
     184  }
     185 
     186  /* solve with SuperLU */
     187  k = solve_slu(NUM * NUM, nnz, nzval, colind, rowptr, phi, rhs);
     188  if (k != 0){
     189    printf("calculation failed\n");
     190    exit(-1);
     191  }
     192 
     193  /* Output Result */
     194  fp = fopen("res.dat","w");
     195  if (fp == NULL){
     196    printf("File could not create\n");
     197    exit(-1);
     198  }
     199 
     200  for (i = 0 ;i < NUM ; i++){
     201    for (j = 0 ; j < NUM ; j++){
     202      x = -0.5 + (double)i / (double)(NUM - 1);
     203      y = (double)j / (double)(NUM - 1);
     204      fprintf(fp,"%e %e %e\n",x,y,phi[i + NUM * j]);
     205    }
     206  }
     207  fclose(fp);
     208 
     209  printf("Done\n");
     210}
     211}}}