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; }
/* 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; }
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; }
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; }
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; }
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; }
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); }