예제 #1
0
void SpParMat<IT,NT,DER>::PrintInfo() const
{
	IT mm = getnrow(); 
	IT nn = getncol();
	IT nznz = getnnz();
	
	if (commGrid->myrank == 0)	
		cout << "As a whole: " << mm << " rows and "<< nn <<" columns and "<<  nznz << " nonzeros" << endl; 

#ifdef DEBUG
	if ((commGrid->grrows * commGrid->grcols) ==  1)
		spSeq->PrintInfo();
#endif
}
예제 #2
0
파일: simple.c 프로젝트: rupole1185/EriCa
// Continuity equation is used to find out the pressure corrections
void simple_peqn( void)
{
   double c_a, c_c;
   int    iface, acell, bcell, *FaceintPnt, idir, nniterp;
   double *FacedblPnt, *AA, *CellAdblPnt, *CellBdblPnt, A_a, A_b;
   double  F_i[1], Fp_i[1][1], u_f[ndir], u_a[ndir], u_b[ndir];
   double *phi_a, *dep_a, *phi_b, *dep_b, rho_i, *dd_a, *dd_b, p_sum[ndir];
   double F_pa, F_pb, dx[ndir], dxi, e_xi[ndir], alfa, u_fp, ttollp, ttmmpp;
   struct CSRMat Mat_p;
   struct RHS    Rhs_p;

   p_sol = (double *) calloc( ntot, sizeof(double));

   c_a = 1.0;
   c_c = 1.0;

   matini(ncell, 1, &Mat_p);
   matalc(&Mat_p, dnnz);
   rhsini(ncell, 1, &Rhs_p);

// Rileggersi: Versteeg pagg. 338 e seguenti ...
//    geometrical issues on Collocated grids
//   
// Face interpolation has three different contributions here reported
// u_f = f(U_a,U_b) + f(P_a, P_b) + f(grad(P_a), grad(P_b))
//          1             2                 3
// The first therm is straight forward to compute and is implicit
// The second and the third are explicit at a given time step  

   for (iface=0;iface<nface;iface++) {
      FaceintPnt = setintface( iface);
      FacedblPnt = setdblface( iface);

      //A-B cells
      acell = FaceintPnt[FaceAcl];
      bcell = FaceintPnt[FaceBcl];

      alfa = FacedblPnt[FaceAlfa];
      AA   = &FacedblPnt[FaceSrf];

      //Variables of the two cells
      phi_a = setvar( acell);
      dep_a = setdep( acell);
      phi_b = setvar( bcell);
      dep_b = setdep( bcell);

      //Cell dbl Pnt
      CellAdblPnt = setdblcell( acell);
      CellBdblPnt = setdblcell( bcell);

      rho_i = facevar( alfa, dep_a[Rdep], dep_b[Rdep]);

      // These are the coefficients averaged in all the directions
      //    For ghosts cells the correspondent coefficient
      //    of the fluid cell is considered
      if (acell<ncell) {
         dd_a = setsol( acell, ndir, dd);
         A_a  = fabs( scalarp( ndir, dd_a, AA) / sqrt( scalarp( ndir, AA, AA)));
      }

      if (bcell<ncell) {
         dd_b = setsol( bcell, ndir, dd);
         A_b  = fabs( scalarp( ndir, dd_b, AA) / sqrt( scalarp( ndir, AA, AA)));
      }

      if (acell>=ncell)
         A_a = A_b;

      if (bcell>=ncell)
         A_b = A_a;

      // u* contribution to continuity equation -------------------
      //  1st term 
      //   we use u* to obtain the pressure correction
      for (idir=0;idir<ndir;idir++) {
         u_a[idir] = phi_a[Uvar+idir] + scalarp( ndir, &dep_a[UGrd+ndir*idir], &FacedblPnt[FaceDxA]);
         u_b[idir] = phi_b[Uvar+idir] + scalarp( ndir, &dep_b[UGrd+ndir*idir], &FacedblPnt[FaceDxB]);
      }

      for (idir=0;idir<ndir;idir++)
         u_f[idir] = facevar( alfa, u_a[idir], u_b[idir]);

      F_i[0] = rho_i * scalarp( ndir, AA, u_f);

      //  2nd and 3rd therms: face normal velocities from RhieChow
      F_pa = CellAdblPnt[CellVol] / A_a;
      F_pb = CellBdblPnt[CellVol] / A_b;

      pntsdist( &CellBdblPnt[CellXc], &CellAdblPnt[CellXc], dx);

      dxi = sqrt( scalarp( ndir, dx, dx) );

      for (idir=0;idir<ndir;idir++)
         e_xi[idir] = dx[idir] / dxi;

      double dxn = scalarp( ndir, dx, AA) / sqrt( scalarp( ndir, AA, AA));

      double p_a = phi_a[Pvar] + scalarp( ndir, &dep_a[PGrd], &FacedblPnt[FaceDxA]);
      double p_b = phi_b[Pvar] + scalarp( ndir, &dep_b[PGrd], &FacedblPnt[FaceDxB]);

      /////////////////////////////////////////// VERSTEEG
      u_fp  = facevar( alfa, F_pa, F_pb) * (p_b - p_a) / dxn;

      for (idir=0;idir<ndir;idir++)
         p_sum[idir] = facevar( alfa, F_pa * dep_a[PGrd+idir], F_pb * dep_b[PGrd+idir]);
         //p_sum[idir] = facevar( alfa, F_pa, F_pb) * facevar( 0.5, dep_a[PGrd+idir], dep_b[PGrd+idir]);

      u_fp -= scalarp( ndir, p_sum, e_xi);
      /////////////////////////////////////////// DARWISH
      /*for (idir=0;idir<ndir;idir++)
         p_sum[idir] = -1.0 * facevar( 0.5, dep_a[PGrd+idir], dep_b[PGrd+idir]);

      for (idir=0;idir<ndir;idir++)
         p_sum[idir]+= ( p_b - p_a) / dxn * e_xi[idir];

      u_fp = facevar( alfa, F_pa, F_pb) * scalarp( ndir, p_sum, AA) / sqrt( scalarp( ndir, AA, AA));*/
      ///////////////////////////////////////////

      // There is a sign inconsistency between:
      //    MATHUR AND MURTHY's "Pressure based method for unstructured mesh"
      //    VERSTEEG's "An Introduction to C.F.D."
      F_i[0] -= rho_i * u_fp * sqrt( scalarp( ndir, AA, AA));

      // A CELL fluxes ----------
      getrhs( &Rhs_p, acell,  c_a, F_i);

      // B CELL fluxes ----------
      getrhs( &Rhs_p, bcell, -c_a, F_i);

      // p' contribution to continuity equation -------------------
      // We need to know the sum of all the convective/diffusion
      // terms for the velocity
      double Cnst = rho_i * facevar( alfa, F_pa, F_pb);

      Fp_i[0][0]  = Cnst * scalarp( ndir, AA, AA) / scalarp( ndir, dx, AA);

      // A CELL fluxes ----------          //LE BC qui sono DIFFERENTI!!!
      getnnz( &Mat_p, acell, acell, -c_c, Fp_i);

      if (bcell<ncell) 
         getnnz( &Mat_p, acell, bcell, c_c, Fp_i);
      else 
         getnnz( &Mat_p, acell, acell, c_c * ghst2fld( gbl2ghst( bcell), Pvar), Fp_i);

      // B CELL fluxes ----------
      if (acell<ncell)
         getnnz( &Mat_p, bcell, acell, c_c, Fp_i);
      else 
         getnnz( &Mat_p, bcell, bcell, c_c * ghst2fld( gbl2ghst( acell), Pvar), Fp_i);

      getnnz( &Mat_p, bcell, bcell, -c_c, Fp_i);
   }

#if _DBG == 10
   int icell;
   double *dep, *dd_i;

   for (icell=0;icell<ncell;icell++) {
      dep = setdep( icell);

      dep[DivSdep] = extrhs( icell, 0, &Rhs_p);

      dd_i = setsol( icell, ndir, dd);

      for (idir=0;idir<ndir;idir++)
         dep[DDdep+idir] = dd_i[idir];
   }
#endif

   // Solution -------------
   nniterp = niterp;
   ttollp  = tollp;

//   BiCGS seems to be the best method among the ones implemented ...
//   Cases in future may confirm this assumption ...
//   SORmethd( &Mat_p, &Rhs_p, p_sol, 1.0, &ttollp, &nniterp);
//   pcjacb( &Mat_p);
//   ConjGrad( &Mat_p, &Rhs_p, p_sol, &ttollp, &nniterp);
   BiCGStab( &Mat_p, &Rhs_p, p_sol, &ttollp, &nniterp);

   fprintf(logfile, "    Press iter   = %4d, Res = %f\n", nniterp,  ttollp);

   matdel( &Mat_p);
   rhsdel( &Rhs_p);
}
예제 #3
0
파일: runcartrec.cpp 프로젝트: C-CINA/2dx
int main(int argc, char *argv[])
{
  int ncpus, mypid, nrem, ierr;
  MPI_Status mpistatus;
  MPI_Comm comm = MPI_COMM_WORLD;
  
  // Variables needed for the Cartesian topology.
  int ROW = 0, COL = 1;
  int dims[2], periods[2], keep_dims[2];
  int my2dpid, mycoords[2], srcoords[2], otherpid;
  MPI_Comm comm_2d, comm_row, comm_col; 
		  
// Initialize MPI.
  MPI_Init(&argc, &argv);
  MPI_Comm_size(comm, &ncpus);
  MPI_Comm_rank(comm, &mypid);
  
  if ( argc < 3  ) {
	  printf ("ERROR: %s requires Cartesian dimensions input\n", argv[0]);
	  return -1;
  }
// Set up a Cartesian virtual topology and get the rank and coordinates of the processes in the topology. 
  dims[ROW] = atoi(argv[1]); // Row dimension of the topology
  dims[COL] = atoi(argv[2]); // Column dimension of the topology
  
  if (dims[ROW]*dims[COL] != ncpus){
	printf("ERROR: Row dim and col dim not equal to ncpus\n");
	return -1;
  }
  
  periods[ROW] = periods[COL] = 1; // Set the periods for wrap-around
  
  MPI_Cart_create(comm, 2, dims, periods, 1, &comm_2d);
  MPI_Comm_rank(comm_2d, &my2dpid); //Get my pid in the new 2D topology
  MPI_Cart_coords(comm_2d, my2dpid, 2, mycoords); // Get my coordinates
  
  /* Create the row-based sub-topology */ 
  keep_dims[ROW] = 0; 
  keep_dims[COL] = 1; 
  MPI_Cart_sub(comm_2d, keep_dims, &comm_row); 
 
  /* Create the column-based sub-topology */ 
  keep_dims[ROW] = 1; 
  keep_dims[COL] = 0; 
  MPI_Cart_sub(comm_2d, keep_dims, &comm_col); 

// STEP 1: Have processor (0,0) read in the entire set of 2D images, divide up the images, and send corresponding images to processors in processor group: g_c_0  Do the same for the angles.
  
  if (mycoords[ROW] == 0 && mycoords[COL] == 0){ //I'm processor (0,0)
    FILE *fp, *fpa;
    char imagefname[80]="tf2d84.raw", anglesfname[80]="angles.dat";
	  
    fp = fopen(imagefname,"r");
    fread(&nangs, sizeof(int), 1, fp);
    fread(&nx, sizeof(int), 1, fp);
    fread(&ny, sizeof(int), 1, fp);
    
    images = new float[nx*ny*nangs];
    fread(images, sizeof(float), nx*ny*nangs, fp);
    fclose(fp);
    
    fpa = fopen(anglesfname,"r");
    angles = new float[3*nangs];
    for (int i = 0; i< 3*nangs; i++)
      fscanf(fpa, "%f",&angles[i]);
       
    fclose(fpa);
    printf("There are %d 2D images of size %d x %d\n", nangs, nx, ny);
  }
  
  // Broadcast variables nangs, nx, ny to all processors
  srcoords[ROW] = srcoords[COL] = 0;
  MPI_Cart_rank(comm_2d, srcoords, &otherpid); 
  
  MPI_Bcast (&nangs, 1, MPI_INT, otherpid, comm_2d);
  MPI_Bcast (&nx, 1, MPI_INT, otherpid, comm_2d);
  MPI_Bcast (&ny, 1, MPI_INT, otherpid, comm_2d);
  
  // Send images and angles from Processor (0,0) to processors in group g_c_0
  int *psize = new int[dims[ROW]];
  int *nbase = new int[dims[ROW]];
  
  nangsloc = setpart_gc1(comm_2d, nangs, psize, nbase);
  imagesloc = new float[psize[mycoords[ROW]]*nx*ny];
  reprojloc = new float[psize[mycoords[ROW]]*nx*ny];
  anglesloc = new float[psize[mycoords[ROW]]*3];
  
// printf("My coords are (%d,%d) and nangsloc = %d\n", mycoords[ROW], mycoords[COL], nangsloc);
  
  if (mycoords[COL] == 0 && mycoords[ROW] == 0) { //I'm Proc. (0,0)
    for(int ip = 0; ip < dims[ROW]; ++ip){
      int begidx = nbase[ip]*nx*ny;
      if (ip !=0){ // Proc (0,0) sends images and angle data to other processors
	 srcoords[COL] = 0;
	 srcoords[ROW] = ip;
	 MPI_Cart_rank(comm_2d, srcoords, &otherpid);
	 MPI_Send(&images[begidx],psize[ip]*nx*ny, MPI_FLOAT, otherpid, otherpid, comm_2d);
	 MPI_Send(&angles[nbase[ip]*3],psize[ip]*3, MPI_FLOAT, otherpid, otherpid, comm_2d);
      }
      else{ // ip = 0: Proc (0,0) needs to copy images and angles into its imagesloc and anglesloc
	for (int i = 0; i < psize[ip]*nx*ny; i++){
	  imagesloc[i] = images[begidx+i];
	}
	for (int i = 0; i < psize[ip]*3; i++){
		anglesloc[i] = angles[nbase[ip]*3 + i];
	}
	//printf("Finished copying to Proc (0,0) local");
      }
    } //End for loop
  } //End if
  
  if (mycoords[COL] == 0 && mycoords[ROW] != 0) { //I'm in g_c_0 and I'm not Processor (0,0) so I should receive data.
    MPI_Recv(imagesloc, psize[mycoords[ROW]]*nx*ny, MPI_FLOAT, 0, mypid, comm_2d, &mpistatus);
    MPI_Recv(anglesloc, psize[mycoords[ROW]]*3, MPI_FLOAT, 0, mypid, comm_2d, &mpistatus);
  }
  // Now have all the processors in group g_c_0 broadcast the images and angles along the row communicator
  srcoords[ROW] = 0;
  MPI_Cart_rank(comm_row, srcoords, &otherpid);
  MPI_Bcast(imagesloc, nangsloc*nx*ny, MPI_FLOAT, otherpid , comm_row);
  MPI_Bcast(anglesloc, nangsloc*3, MPI_FLOAT, otherpid , comm_row);
 
// Now distribute the volume (in spherical format) among columns of processors and use nnz to determine the splitting.  Note: ptrs and coord are on all processors
  int radius;
  int volsize[3], origin[3];
  volsize[0] = nx;
  volsize[1] = nx;
  volsize[2] = nx;
  origin[0] = nx/2+1;
  origin[1] = nx/2+1;
  origin[2] = nx/2+1;
  radius = nx/2-1;
   
  ierr = getnnz( volsize, radius, origin, &nrays, &nnz);
   
  int * ptrs = new int[nrays+1];
  int * cord = new int[3*nrays];
  ierr = getcb2sph(volsize, radius, origin, nnz, ptrs, cord);
		  
  int *nnzpart = new int[dims[COL]];
  int *nnzbase = new int[dims[COL]+1]; 
  nnzloc = setpart_gr1(comm_2d, nnz, nnzpart, nnzbase);
  
  int *ptrstart = new int[dims[COL]+1];
  nraysloc = sphpart(comm_2d, nrays, ptrs, nnzbase, ptrstart);
  
  myptrstart = ptrstart[mycoords[COL]];
  int nnzall[dims[COL]];
  for (int i = 0; i<dims[COL]; i++)
    nnzall[i] = ptrs[ptrstart[i+1]] - ptrs[ptrstart[i]];
  
  nnzloc = nnzall[mycoords[COL]];
  
  // Print some stuff.
 printf("My coords are (%d,%d) and nangsloc = %d, nraysloc = %d, myptrstart = %d, nnzloc = %d\n", mycoords[ROW], mycoords[COL], nangsloc, nraysloc, myptrstart, nnzloc);
  
  float *bvol_loc = new float[nnzloc];
  float *vol_sphloc = new float[nnzloc];
  for (int i=0; i< nnzloc; i++)
    bvol_loc[i] = 0.0;
  
  // STEP 2: Have everyone perform the backprojection operation for their assigned images and portions of the volume.  Then perform an Allreduce along the columns.
  
  float phi, theta, psi;
  float dm[8];
  
  for (int i=0; i<nangsloc; i++){
    phi = anglesloc[3*i+0];
    theta = anglesloc[3*i+1];
    psi = anglesloc[3*i+2];
    dm[6] = 0;
    dm[7] = 0;
 
    make_proj_mat(phi, theta, psi, dm);

    ierr = bckpj3_Cart(volsize, nraysloc, nnzloc, dm, origin, radius, ptrs, cord, myptrstart, &imagesloc[nx*ny*i], bvol_loc);
  }
  
  // Now an all reduce along the columns
  MPI_Allreduce (bvol_loc, vol_sphloc, nnzloc, MPI_FLOAT, MPI_SUM, comm_col);
  
  // For testing purposes, we bring all the portions of the volume back together onto Proc (0,0). Note: we only need to deal with the first row of processors.
  if (mycoords[COL] != 0 && mycoords[ROW] == 0) {
	//Send data to Processor (0,0)
	srcoords[COL] = srcoords[ROW] = 0;
	MPI_Cart_rank(comm_2d, srcoords, &otherpid);
	MPI_Send(vol_sphloc, nnzloc, MPI_FLOAT, otherpid, otherpid, comm_2d);
  }
  float *onevol_sph = new float[nnz];
  if (mycoords[COL] == 0 && mycoords[ROW] ==0){
	  //Copy data and recieve data
	float *vol_sph = new float[nnz];
	for (int i=0; i<nnzloc; i++)
	  vol_sph[i] = vol_sphloc[i];
	
	for (int i=1; i<dims[COL]; i++){
	  srcoords[ROW] = 0;
	  srcoords[COL] = i;
	  MPI_Cart_rank(comm_2d, srcoords, &otherpid);
	 	
	  MPI_Recv(&vol_sph[ptrs[ptrstart[i]]-1], nnzall[i], MPI_FLOAT, otherpid, mypid, comm_2d, &mpistatus);
	}
	//printf("Finished combining all volume parts\n");
  
  //Now compute the back projection serially on one processor (0,0)
    for (int i=0; i< nnz; i++)
      onevol_sph[i] = 0.0;
    
    for (int i=0; i<nangs; i++){
    	    phi = angles[3*i+0];
	    theta = angles[3*i+1];
	    psi = angles[3*i+2];
	    dm[6] = 0;
	    dm[7] = 0;
 
	    make_proj_mat(phi, theta, psi, dm);
  
	    ierr = bckpj3(volsize, nrays, nnz, dm, origin, radius, ptrs, cord, &images[nx*ny*i], onevol_sph);
    }
    
    float err=0;
    for (int i=0; i< nnz; i++){
	    err = err+(onevol_sph[i]-vol_sph[i])*(onevol_sph[i]-vol_sph[i]);
    }
    err = sqrt(err);
    printf("Cumulative error for backprojection is %f\n", err);
    delete [] vol_sph;
  }
  
    // STEP 3: Now perform a forward projection operation for the assigned images and portions of the volume.  Then perform an all_reduce along the rows.
  float * newimagesloc = new float[nangsloc*nx*ny];
  for (int i=0; i<nangsloc*nx*ny; i++)
	  newimagesloc[i] = 0.0;
  	
  for (int i=0; i<nangsloc; i++){
  phi = anglesloc[3*i+0];
	  theta = anglesloc[3*i+1];
	  psi = anglesloc[3*i+2];
	  dm[6] = 0;
	  dm[7] = 0;
    
	  make_proj_mat(phi, theta, psi, dm);
  
	 ierr = fwdpj3_Cart(volsize, nraysloc, nnzloc, dm, origin, radius, ptrs, cord, myptrstart, vol_sphloc, &newimagesloc[nx*ny*i]);
  }

  // Now an all reduce along the rows
  MPI_Allreduce (newimagesloc, reprojloc, nangsloc*nx*ny, MPI_FLOAT, MPI_SUM, comm_row);
 
  delete [] newimagesloc;
  // For testing purposes, we bring all the 2D images together onto Proc (0,0). Note: we only need to deal with the first column of processors.
  if (mycoords[ROW] != 0 && mycoords[COL] == 0) {
	//Send data to Processor (0,0)
	  srcoords[COL] = srcoords[ROW] = 0;
	  MPI_Cart_rank(comm_2d, srcoords, &otherpid);
	  MPI_Send(reprojloc, nangsloc*nx*ny, MPI_FLOAT, otherpid, otherpid, comm_2d);
  }
  if (mycoords[COL] == 0 && mycoords[ROW] ==0){
	  //Copy data and recieve data
	  float *reproj = new float[nangs*nx*ny];
	  for (int i=0; i<nangsloc*nx*ny; i++)
		  reproj[i] = reprojloc[i];
	
	  for (int i=1; i<dims[ROW]; i++){
		  srcoords[COL] = 0;
		  srcoords[ROW] = i;
		  MPI_Cart_rank(comm_2d, srcoords, &otherpid);
	 	
		  MPI_Recv(&reproj[nbase[i]*nx*ny], psize[i]*nx*ny, MPI_FLOAT, otherpid, mypid, comm_2d, &mpistatus);
	  }
  delete [] reprojloc;
  // Now compute the forward projection serially on one processor (0,0)

	  float *allimages = new float[nangs*nx*ny];
	  for (int i=0; i< nangs*nx*ny; i++)
		  allimages[i] = 0.0;
    
	  for (int i=0; i<nangs; i++){
	    phi = angles[3*i+0];
	    theta = angles[3*i+1];
	    psi = angles[3*i+2];
	    dm[6] = 0;
	    dm[7] = 0;
    
	    make_proj_mat(phi, theta, psi, dm);
		  
	    ierr = fwdpj3(volsize, nrays, nnz, dm, origin, radius, ptrs, cord, onevol_sph, &allimages[nx*ny*i]);

	  }

	  //  Now compute the overall error.
int idx;	
  float err=0, max =0;
	  for (int i=0; i< nangs*nx*ny; i++){
		//if (allimages[i]!=reproj[i] && i < 256)
		//	printf("i= %d\n",i);
		
	    err = err+(allimages[i]-reproj[i])*(allimages[i]-reproj[i]);

		if (fabs(allimages[i]-reproj[i]) > max){
			max = fabs(allimages[i]-reproj[i]);
idx = i;
}
	  }
err = sqrt(err);  
	  printf("Cumulative error for forward projection is %f with max error of %f occuring at %d\n", err, max, idx);
printf("Max error: compare %f and %f\n",allimages[idx], reproj[idx]);

	  delete [] reproj;
	  delete [] allimages;
	  delete [] angles;
	  delete [] images;
  }
  delete [] onevol_sph;
  delete [] vol_sphloc;
  delete [] bvol_loc;  
  delete [] ptrs;
  delete [] cord;
  delete [] nnzpart;
  delete [] nnzbase;
  delete [] ptrstart;
  delete [] anglesloc;
  delete [] imagesloc;
  delete [] nbase;
  delete [] psize;	  
  
  MPI_Comm_free(&comm_2d);
  MPI_Comm_free(&comm_row);
  MPI_Comm_free(&comm_col);
  
  MPI_Finalize();
}
예제 #4
0
파일: convflx.c 프로젝트: rupole1185/EriCa
// Convective fluxes
void convflx(struct CSRMat *Mat, struct RHS *Rhs )
{
   int iface, acell, bcell, *FaceintPnt, idir, ivar;
   double *AA, u_i[ndir], rho_a, rho_b, rho_i, *FacedblPnt, *varPnt, *dep_a;
   double phi_a[nvar], phi_b[nvar], F_a[nvar][nvar], F_b[nvar][nvar], *dep_b;
   double Flux_a[nvar], Flux_b[nvar], Flux[nvar], alfa, mssflw;

   for (iface=0;iface<nface;iface++)  {

      //Setting Pointers
      FaceintPnt = setintface( iface);
      FacedblPnt = setdblface( iface);

      //A-B cells
      acell = FaceintPnt[FaceAcl];
      bcell = FaceintPnt[FaceBcl];

      //Initialization of F_a and F_b
      memset(F_a, 0.0, nvar*nvar* sizeof(double));
      memset(F_b, 0.0, nvar*nvar* sizeof(double));

      /*Variables to convect*/
      varPnt = setvar( acell);
      dep_a  = setdep( acell);
      memcpy( phi_a, varPnt, nvar * sizeof(double));
      rho_a = dep_a[Rdep];

      varPnt = setvar( bcell);
      dep_b  = setdep( bcell);
      memcpy( phi_b, varPnt, nvar * sizeof(double));
      rho_b  = dep_b[Rdep];

      //Convective fluxes calculation:
      // Coeff * Phi_a + Coeff * Phi_b
      // Coeff = max(F_i, ..., 0) depends on the convective scheme

      //Convective fluxes: Rho * u * A * Phi ---------------------------
      alfa  = FacedblPnt[FaceAlfa];

      rho_i   = facevar( alfa, rho_a, rho_b);
      AA      = &FacedblPnt[FaceSrf];

      for (idir=0;idir<ndir;idir++) 
         u_i[idir] = facevar( alfa, \
                     phi_a[Uvar+idir] + scalarp( ndir, &dep_a[UGrd+ndir*idir], &FacedblPnt[FaceDxA]), \
                     phi_b[Uvar+idir] + scalarp( ndir, &dep_b[UGrd+ndir*idir], &FacedblPnt[FaceDxB]));

      mssflw = rho_i * scalarp( ndir, u_i, AA);

      //conv returns the convective scheme
      convscheme( iconv, nvar, 1.0,       mssflw, F_a);
      convscheme( iconv, nvar,-1.0,-1.0 * mssflw, F_b);

      //////------------------------ PRESS-VEL COUPLING
      presflx(phi_a, F_a);
      presflx(phi_b, F_b);
      /////--------------------------------------------

      // Flux calculation
      matvecdstd(nvar, F_a, phi_a, Flux_a);
      matvecdstd(nvar, F_b, phi_b, Flux_b);
      summvec(nvar, Flux_a, Flux_b, Flux);

      // Function to add 2 RHS (it is the explicit part!!)
      getrhs( Rhs, acell, -1.0 * (1.0 - theta), Flux);
      getrhs( Rhs, bcell,  1.0 * (1.0 - theta), Flux);

      // A CELL fluxes ------------------------------------------------
      getnnz( Mat, acell, acell, 1.0 * theta, F_a);

      if (bcell<ncell) 
         getnnz( Mat, acell, bcell, 1.0 * theta, F_b);
      else 
         getrhs( Rhs, acell, -1.0 * theta, Flux_b);

      // B CELL fluxes ------------------------------------------------
      if (acell<ncell) 
         getnnz( Mat, bcell, acell, -1.0 * theta, F_a);
      else 
         getrhs( Rhs, bcell, 1.0 * theta, Flux_a);

      getnnz( Mat, bcell, bcell, -1.0 * theta, F_b);

      // Non-orthogonality --------------------------------------------
      // It is like an explicit flux where (Var * Dx) replaces phi
      for (ivar=0;ivar<nvar;ivar++) {
         phi_a[ivar] = scalarp( ndir, &dep_a[PGrd+(ivar*ndir)], &FacedblPnt[FaceDxA]);
         phi_b[ivar] = scalarp( ndir, &dep_b[PGrd+(ivar*ndir)], &FacedblPnt[FaceDxB]);
      }

      presflx( phi_a, F_a);
      presflx( phi_b, F_b);
 
      matvecdstd(nvar, F_a, phi_a, Flux_a);
      matvecdstd(nvar, F_b, phi_b, Flux_b);
      summvec(nvar, Flux_a, Flux_b, Flux);

      getrhs( Rhs, acell, -1.0, Flux);
      getrhs( Rhs, bcell,  1.0, Flux);
   }
}
예제 #5
0
파일: viscflx.c 프로젝트: rupole1185/EriCa
// Viscous fluxes
void viscflx(struct CSRMat *Mat, struct RHS *Rhs )
{
   int iface, ivar, acell, bcell, *FaceintPnt, idir;
   double *AA, *FacedblPnt, *varPnt, *dep_a, *dep_b;
   double phi_a[nvar], phi_b[nvar], F_i[nvar][nvar];
   double Flux_a[nvar], Flux_b[nvar], Flux[nvar], alfa;
   double *CellAdblPnt, *CellBdblPnt, dx[ndir];
   double mu_i[nvar];

   if (MUdep == -1)
      return;

   for (iface=0;iface<nface;iface++)  {
      //Setting Pointers
      FaceintPnt = setintface( iface);
      FacedblPnt = setdblface( iface);

      //A-B cells
      acell = FaceintPnt[FaceAcl];
      bcell = FaceintPnt[FaceBcl];

      //Cell pointers 
      CellAdblPnt = setdblcell( acell);
      CellBdblPnt = setdblcell( bcell);

      //Initialization of F_i and mu_i
      memset(F_i , 0.0, nvar * nvar * sizeof(double));

      /*Variables*/
      varPnt = setvar( acell);
      dep_a  = setdep( acell);
      memcpy( phi_a, varPnt, nvar * sizeof(double));

      varPnt = setvar( bcell);
      dep_b  = setdep( bcell);
      memcpy( phi_b, varPnt, nvar * sizeof(double));

      alfa  = FacedblPnt[FaceAlfa];

      // To better understand the ViscousFlux check the formula 11.22
      //  of the Versteeg book (page 332)

      //Cell centres distance
      pntsdist( &CellBdblPnt[CellXc], &CellAdblPnt[CellXc], dx);

      AA   = &FacedblPnt[FaceSrf];

      // Flux Matrix -----------
      setmuvar( mu_i, alfa, dep_a, dep_b, phi_a, phi_b);
      viscscheme( nvar, mu_i, AA, dx, F_i);

      // Note: in continuity equation there is no diffusion
      phi_a[Pvar] = 0.0; 
      phi_b[Pvar] = 0.0;

      for (ivar=0;ivar<nvar;ivar++) 
         phi_a[ivar] *= -1.0;

      // Flux calculation
      matvecdstd(nvar, F_i, phi_a, Flux_a);
      matvecdstd(nvar, F_i, phi_b, Flux_b);
      summvec(nvar, Flux_a, Flux_b, Flux);

      // Function to add 2 RHS (it is the explicit part!!)
      getrhs( Rhs, acell, -1.0 * (1.0 - theta), Flux);
      getrhs( Rhs, bcell,  1.0 * (1.0 - theta), Flux);

      // A CELL fluxes ------------------------------------------------
      getnnz( Mat, acell, acell, -1.0 * theta, F_i);

      if (bcell<ncell) 
         getnnz( Mat, acell, bcell,  1.0 * theta, F_i);
      else 
         getrhs( Rhs, acell, -1.0 * theta, Flux_b);

      // B CELL fluxes ------------------------------------------------
      if (acell<ncell) 
         getnnz( Mat, bcell, acell,  1.0 * theta, F_i);
      else 
         getrhs( Rhs, bcell,  1.0 * theta, Flux_a);
         // NB: this should be negative, but Flux_a has already been 
         //   multiplied by a negative value!!

      getnnz( Mat, bcell, bcell, -1.0 * theta, F_i);

      // Non-orthogonality --------------------------------------------
      // STANDARD MODE ################################################
      for (ivar=0;ivar<nvar;ivar++) {
         phi_a[ivar] = scalarp( ndir, &dep_a[PGrd+(ivar*ndir)], &FacedblPnt[FaceDxA]);
         phi_b[ivar] = scalarp( ndir, &dep_b[PGrd+(ivar*ndir)], &FacedblPnt[FaceDxB]);
      }

      for (ivar=0;ivar<nvar;ivar++) 
         phi_a[ivar] *= -1.0;

      phi_a[Pvar] = 0.0; 
      phi_b[Pvar] = 0.0;

      matvecdstd(nvar, F_i, phi_a, Flux_a);
      matvecdstd(nvar, F_i, phi_b, Flux_b);
      summvec(nvar, Flux_a, Flux_b, Flux);

      getrhs( Rhs, acell, -1.0, Flux);
      getrhs( Rhs, bcell,  1.0, Flux);

      // MATHUR & MURTHY ##############################################
      /*double grdavg[ndir];

      for (ivar=0;ivar<nvar;ivar++) {
         for (idir=0;idir<ndir;idir++)
            grdavg[idir] = facevar( alfa, dep_a[PGrd+(ivar*ndir)+idir], dep_b[PGrd+(ivar*ndir)+idir]);

         Flux[ivar] = scalarp( ndir, grdavg, AA);
         Flux[ivar]-= scalarp( ndir, grdavg, dx) * scalarp( ndir, AA, AA) / scalarp( ndir, AA, dx);
         Flux[ivar]*= mu_i[ivar];
      }

      getrhs( Rhs, acell,  1.0, Flux);
      getrhs( Rhs, bcell, -1.0, Flux);*/
   }
}