Beispiel #1
0
int myinterp(ML_Operator *mydata, int leng1, double p[], int leng2, double ap[])
{
   int i, fine_i, fine_size, coarse_size, proc_id;
   double ghost;
   struct data *data;
   ML_Operator *mat_in;

   mat_in = (ML_Operator *) mydata;
   data = (struct data *) ML_Get_MyMatvecData(mat_in);
   coarse_size = data->from_size;
   fine_size   = data->to_size;
   proc_id     = data->processor_info[PROC_ID];

   for (i = 0; i < fine_size; i++) ap[i] = 0.0;
   fine_i = 1 - proc_id;
   for (i = 0; i < coarse_size; i++) {
      ap[fine_i] += p[i];
      ap[fine_i+1] += .5*p[i];
      if (fine_i != 0) ap[fine_i-1] += .5*p[i];
      fine_i += 2;
   }
   ghost = get_boundary(p, coarse_size, data->processor_info);
   if (proc_id == 0) ap[fine_i - 1] += .5*ghost;

   return 0;
}
Beispiel #2
0
/* Application specific matrix-vector product. */
int Poisson_matvec(ML_Operator *mat_in, int in_length, double p[], int out_length,
                   double ap[])
{
   int i, proc, *itemp;
   double new_p[5];

   itemp = (int *) ML_Get_MyMatvecData(mat_in);
   
   proc  = *itemp; 

   for (i = 0; i < in_length; i++) new_p[i] = p[i];
   Poisson_comm(new_p, &proc);

   for (i = 0; i < out_length; i++) ap[i] = 2.*new_p[i];

   if (proc == 0) {
      ap[0] -= new_p[2];
      ap[1] -= new_p[3];
   }
   if (proc == 1) {
      ap[0] -= new_p[1]; ap[0] -= new_p[4];
      ap[1] -= new_p[2]; ap[1] -= new_p[0];
      ap[2] -= new_p[3]; ap[2] -= new_p[1];
   }
   return 0;
}
Beispiel #3
0
int Tmat_matvec(void *data, int Nlocal_nodes, double p[], int Nlocal_edges, double Ap[])
{
  int i, global_id, ii, jj, nx, horv;
  struct user_partition *Edge_Partition;
  struct user_partition *Node_Partition;
  ML_Operator *Kn_mat;
  struct Tmat_data *Tmat_data;
  int *my_local_id;
  double *temp;
  ML_Operator *mat_in;

  mat_in = (ML_Operator *) data; 
  Tmat_data = (struct Tmat_data *) ML_Get_MyMatvecData(mat_in); 
  Node_Partition = Tmat_data->node;
  Edge_Partition = Tmat_data->edge;
  Kn_mat              = Tmat_data->Kn;
  my_local_id = Node_Partition->my_local_ids;
  temp = (double *) malloc(sizeof(double)*(Nlocal_nodes + 
					   Node_Partition->Nghost));

  for (i = 0; i < Nlocal_nodes; i++) temp[i] = p[i];
  update_ghost_nodes(temp, Node_Partition);



  nx = (int) sqrt( ((double) Node_Partition->Nglobal) + .00001);
#ifdef periodic
  nx = (int) sqrt( ((double) Node_Partition->Nglobal - 2) + .00001); 
#endif

  for (i = 0; i < Nlocal_edges; i++) {
    global_id = (Edge_Partition->my_global_ids)[i];
    inv2dindex(global_id, &ii, &jj, nx, &horv);
    Ap[i] = 0.;


    if (horv == HORIZONTAL) {
      Ap[i] += -1.*temp[my_local_id[southwest2d(ii,jj,nx)]];
      Ap[i] +=  1.*temp[my_local_id[southeast2d(ii,jj,nx)]];
#ifdef periodic
      Ap[i] +=  1.*temp[Nlocal_nodes-2];
#endif
    }
    else {
      Ap[i] += -1.*temp[my_local_id[northwest2d(ii,jj,nx)]];
      Ap[i] +=  1.*temp[my_local_id[southwest2d(ii,jj,nx)]];
#ifdef periodic
      Ap[i] +=  1.*temp[Nlocal_nodes-1];
#endif
    }
  }
  free(temp);
  return 1;

}
Beispiel #4
0
int Ke_matvec(void *data, int Nlocal_edges, double p[], int N_out, double Ap[])
{
  int i, global_id, ii, jj, nx, horv;
  double dcenter, doffdiag, sigma = .0001, *temp;
  int *my_local_ids;
  struct user_partition *Edge_Partition;
  ML_Operator *mat_in;

  mat_in = (ML_Operator *) data;
  Edge_Partition = (struct user_partition *) ML_Get_MyMatvecData(mat_in);
  my_local_ids = Edge_Partition->my_local_ids;
  nx = (int) sqrt( ((double) Edge_Partition->Nglobal/2) + .00001);
  dcenter  = 2 + 2.*sigma/((double) ( 3 * nx * nx));
  doffdiag = -1 + sigma/((double) ( 6 * nx * nx));
  temp = (double *) malloc(sizeof(double)*(3*nx + Nlocal_edges));

  for (i = 0; i < Nlocal_edges; i++) temp[i] = p[i];
  update_ghost_edges(temp, (void *) Edge_Partition);

  for (i = 0; i < Nlocal_edges; i++) {
    global_id = (Edge_Partition->my_global_ids)[i];
    Ap[i] = dcenter*temp[i];
    inv2dindex(global_id, &ii, &jj, nx, &horv);
    if (horv == HORIZONTAL) {
      Ap[i] += doffdiag*temp[my_local_ids[north2d(ii,jj,nx)]];
      Ap[i] +=       1.*temp[my_local_ids[west2d(ii,jj,nx)]];
      Ap[i] +=      -1.*temp[my_local_ids[east2d(ii,jj,nx)]];

      if (jj == 0) jj = nx-1;
      else jj--;

      Ap[i] +=      -1.*temp[my_local_ids[west2d(ii,jj,nx)]];
      Ap[i] += doffdiag*temp[my_local_ids[south2d(ii,jj,nx)]];
      Ap[i] +=       1.*temp[my_local_ids[east2d(ii,jj,nx)]];
    }
    else {
      Ap[i] += -1.*temp[my_local_ids[north2d(ii,jj,nx)]];
      Ap[i] += doffdiag*temp[my_local_ids[east2d(ii,jj,nx)]];
      Ap[i] +=  1.*temp[my_local_ids[south2d(ii,jj,nx)]];

      if (ii == 0) ii = nx-1;
      else ii--;

      Ap[i] += doffdiag*temp[my_local_ids[west2d(ii,jj,nx)]];
      Ap[i] += -1.*temp[my_local_ids[south2d(ii,jj,nx)]];
      Ap[i] +=  1.*temp[my_local_ids[north2d(ii,jj,nx)]];
    }
  }
  free(temp);
  return 1;
}
Beispiel #5
0
int mymatvec(ML_Operator *mydata, int leng1, double p[], int leng2, double ap[])
{
   int i, size, proc_id;
   double ghost;
   struct data *data;
   ML_Operator *mat_in;

   mat_in = (ML_Operator *) mydata;
   data = (struct data *) ML_Get_MyMatvecData(mat_in);
   size = data->to_size;
   proc_id   = data->processor_info[PROC_ID];
   for (i = 0; i < size; i++ ) {
      ap[i] = 2*p[i];
      if (i !=      0) ap[i] -= p[i-1];
      if (i != size-1) ap[i] -= p[i+1];
   }
   ghost = get_boundary(p, size, data->processor_info);
   if (proc_id == 0) ap[size-1] -= ghost;
   else              ap[0]      -= ghost;

   return 0;
}
Beispiel #6
0
int myrestrict(ML_Operator *mydata, int leng1, double p[], int leng2, double ap[])
{
   int i, fine_i, coarse_size, proc_id;
   struct data *data;
   double ghost;
   ML_Operator *mat_in;

   mat_in = (ML_Operator *) mydata;
   data = (struct data *) ML_Get_MyMatvecData(mat_in);
   coarse_size = data->to_size;
   proc_id   = data->processor_info[PROC_ID];
   fine_i = 1 - proc_id;
   for (i = 0; i < coarse_size; i++) {
      ap[i] = .5*p[fine_i] + .25*p[fine_i+1];
      if (fine_i != 0) ap[i] += .25*p[fine_i-1];
      ap[i] *= 4.;
      fine_i += 2;
   }
   ghost = get_boundary(p, fine_i, data->processor_info);
   if (proc_id == 1) ap[0] += ghost;
   return 0;
}
Beispiel #7
0
Datei: ml.c Projekt: Kun-Qu/petsc
static int PetscML_matvec(ML_Operator *ML_data,int in_length,double p[],int out_length,double ap[])
{
  PetscErrorCode ierr;
  FineGridCtx    *ml=(FineGridCtx*)ML_Get_MyMatvecData(ML_data);
  Mat            A=ml->A, Aloc=ml->Aloc; 
  PetscMPIInt    size;
  PetscScalar    *pwork=ml->pwork; 
  PetscInt       i;

  PetscFunctionBegin;
  ierr = MPI_Comm_size(((PetscObject)A)->comm,&size);CHKERRQ(ierr);
  if (size == 1){
    ierr = VecPlaceArray(ml->x,p);CHKERRQ(ierr);
  } else {
    for (i=0; i<in_length; i++) pwork[i] = p[i]; 
    PetscML_comm(pwork,ml);
    ierr = VecPlaceArray(ml->x,pwork);CHKERRQ(ierr);
  }
  ierr = VecPlaceArray(ml->y,ap);CHKERRQ(ierr);
  ierr = MatMult(Aloc,ml->x,ml->y);CHKERRQ(ierr);
  ierr = VecResetArray(ml->x);CHKERRQ(ierr);
  ierr = VecResetArray(ml->y);CHKERRQ(ierr);
  PetscFunctionReturn(0);
}