Exemplo n.º 1
0
void Fox(
         int              n         /* in  */,
         GRID_INFO_T*     grid      /* in  */,
         LOCAL_MATRIX_T*  local_A   /* in  */,
         LOCAL_MATRIX_T*  local_B   /* in  */,
         LOCAL_MATRIX_T*  local_C   /* out */) {
    
    LOCAL_MATRIX_T*  temp_A; /* Storage for the sub-    */
    /* matrix of A used during */
    /* the current stage       */
    int              stage;
    int              bcast_root;
    int              n_bar;  /* n/sqrt(p)               */
    int              source;
    int              dest;
    MPI_Status       status;
    
    n_bar = n/grid->q;
    Set_to_zero(local_C);
    
    /* Calculate addresses for circular shift of B */
    source = (grid->my_row + 1) % grid->q;
    dest = (grid->my_row + grid->q - 1) % grid->q;
    
    /* Set aside storage for the broadcast block of A */
    temp_A = Local_matrix_allocate(n_bar);
    
    for (stage = 0; stage < grid->q; stage++) {
        bcast_root = (grid->my_row + stage) % grid->q;
        if (bcast_root == grid->my_col) {
            MPI_Bcast(local_A, 1, local_matrix_mpi_t,
                      bcast_root, grid->row_comm);
            Local_matrix_multiply(local_A, local_B,
                                  local_C);
        } else {
            MPI_Bcast(temp_A, 1, local_matrix_mpi_t,
                      bcast_root, grid->row_comm);
            Local_matrix_multiply(temp_A, local_B,
                                  local_C);
        }
        MPI_Sendrecv_replace(local_B, 1, local_matrix_mpi_t,
                             dest, 0, source, 0, grid->col_comm, &status);
    } /* for */
    
} /* Fox */
Exemplo n.º 2
0
/************************************************
*        Complex root search subroutine         *
* --------------------------------------------- *
* This routine searches for the complex roots   *
* of an analytical function by encircling the   *
* zero and estimating where it is. The circle   *
* is subsequently tightened by a factor e, and  *
* a new estimate made.                          *
* The inputs to the subroutine are;             *
*     w      initial radius of search circle    *
*     x0,y0  the initial guess                  *
*     e      factor by which circle is reduced  *
*     n      maximum number of iterations       *
*     m      evaluation points per quadrant     *
* The routine returns Z=X+IY (X,Y), and the     *
* number of iterations, k.                      *
************************************************/
void Zcircle(double w, double e, double x0, double y0, int n, int m, 
				double &xx, double &yy, dielectric &epsilon)  {
  //Labels: 50,100,200,250,300,310,320,330,340,350,400,450
  //        460,470,500,510,520,521
  int i,j,m3,m4;
  double X[80],Y[80],U[80],V[80];
  double a,b1,b2,PI,x1,x2,xm1,xm2;
  double x3,y3,x4,y1,y2,y4,uu,vv;
  int k;
  double yy0;
  m=m*4; k=1;
  PI = 4*atan(1);
  a=2*PI/m;
e50:for (i=1; i<m+1; i++) {
    X[i]=w*cos(a*(i-1))+x0;
    Y[i]=w*sin(a*(i-1))+yy0;
	}
   std::cout<<"Determine the corresponding U[i] and V[i]"<<std::endl;
  for (i=1; i<m+1; i++) {
    xx=X[i] ; yy=Y[i];
    //Eval(xx,yy,&uu,&vv);
	std::cout<<"Calling epsilon.determinant ..."<<std::endl;
	std::cout<<k<<"  "<<i<<" A kx_re: "<<xx<<" kx_im: "<<yy<<std::endl;
	epsilon.determinant(xx,yy,&uu,&vv);
	std::cout<<"B det_re: "<<uu<<" det_im: "<<vv<<std::endl;
    U[i]=uu;
    V[i]=vv;
  }
   std::cout<<"Find the position at which uu changes sign"<<std::endl;
  // in the counterclockwise direction
  i=1; uu=U[i];
e100: Auxilliary(m,&i,&j);
  if (uu*U[i]<0) goto e200;
   std::cout<<"Guard against infinite loop B"<<std::endl;
   std::cout<<uu*U[i]<<std::endl;
  if (i==1) Set_to_zero(&xx,&yy);
  goto e100;
   std::cout<<"Transition found"<<std::endl;
e200: xm1=i;
   std::cout<<"Search for the other transition, starting"<<std::endl;
  // on the other side of the circle
  i=(int) xm1+m/2;
  if (i>m) i=i-m;
  j=i;
  uu=U[i];
   std::cout<<"Flip directions alternately"<<std::endl;
e250: Auxilliary(m,&i,&j);
  if (uu*U[i]<0) goto e300;
  if (uu*U[j]<0) goto e310;
   std::cout<<"Guard against infinite loop C"<<std::endl;
  if (i==xm1+(xm2/2)) Set_to_zero(&xx,&yy);
  if (j==xm1+(xm2/2)) Set_to_zero(&xx,&yy);
  goto e250;
   std::cout<<"Transition found"<<std::endl;
e300: m3=i;
  goto e320;
   std::cout<<"Transition found"<<std::endl;
e310: if (j==m) j=0;
  m3=j+1;
   std::cout<<"xm1 and m3 have been determined, now for xm2 and m4"<<std::endl;
  // now for the vv transitions                         
e320: i=(int) xm1+m/4;
  if (i>m) i=i-m;
  j=i; vv=V[i];
e330: Auxilliary(m,&i,&j);
  if (vv*V[i]<0) goto e340;
  if (vv*V[j]<0) goto e350;
   std::cout<<"Guard against infinite loop A"<<std::endl;
  if (i==xm1+m/4) Set_to_zero(&xx,&yy);
  if (j==xm1+m/4) Set_to_zero(&xx,&yy);
  goto e330;
   std::cout<<"xm2 has been found"<<std::endl;
e340: xm2=i;
  goto e400;
e350: if (j==m) j=0;
  xm2=j+1;
   std::cout<<"xm2 has been found, now for m4"<<std::endl;
e400: i=(int) xm2+m/2;
  if (i>m) i=i-m;
  j=i; vv=V[i];
e450: Auxilliary(m,&i,&j);
  if (uu*V[i]<0) goto e460;
  if (vv*V[j]<0) goto e470;
  // Guard against infinite loop
  if (i==xm2+m/2) Set_to_zero(&xx,&yy);
  if (j==xm2+m/2) Set_to_zero(&xx,&yy);
  goto e450;
e460: m4=i;
  goto e500;
e470: if (j==m) j=0;
  m4=j+1;
   std::cout<<"All the intersections have been determinep"<<std::endl;
  // Interpolate to find the four (x,y) coordinates
e500: i=(int) xm1;
  Interpolation(m,i,j,X,Y,U,V,&xx,&yy);
  x1=xx ; y1=yy ; i=(int) xm2;
  Interpolation(m,i,j,X,Y,U,V,&xx,&yy);
  x2=xx ; y2=yy ; i=m3;
  Interpolation(m,i,j,X,Y,U,V,&xx,&yy);
  x3=xx ; y3=yy ; i=m4;
  Interpolation(m,i,j,X,Y,U,V,&xx,&yy);
  x4=xx ; y4=yy;
   std::cout<<"Calculate the intersection of the lines"<<std::endl;
  // Guard against a divide by zero
  if (x1!=x3) goto e510;
  xx=x1; yy=(y1+y3)/2.0;
  goto e520;
e510: xm1=(y3-y1)/(x3-x1);
  if (x2!=x4) goto e520;
  xm2=1e8;
  goto e521;
e520: xm2=(y2-y4)/(x2-x4);
e521: b1=y1-xm1*x1;
  b2=y2-xm2*x2;
  xx=-(b1-b2)/(xm1-xm2);
  yy=(xm1*b2+xm2*b1)/(xm1+xm2);
   std::cout<<"is another iteration in order ?"<<std::endl;
  if (k==n) return;
  x0=xx ; yy0=yy ; k=k+1 ; w=w*e;
  goto e50;
} // Zcircle