int ML_Epetra::MultiLevelPreconditioner::SetupCoordinates() { ML* ml_ptr = 0; int NumDimensions; double* in_x_coord = 0; double* in_y_coord = 0; double* in_z_coord = 0; // Check first for node coordinates, then for edge coordinates for (int ii=0; ii<2; ii++) { switch (ii) { case 0: ml_ptr = ml_; //??else ml_ptr = ml_; in_x_coord = List_.get("x-coordinates", (double *)0); in_y_coord = List_.get("y-coordinates", (double *)0); in_z_coord = List_.get("z-coordinates", (double *)0); break; case 1: if (AMGSolver_ == ML_MAXWELL) { ml_ptr = ml_nodes_; in_x_coord = List_.get("node: x-coordinates", (double *)0); in_y_coord = List_.get("node: y-coordinates", (double *)0); in_z_coord = List_.get("node: z-coordinates", (double *)0); } else { in_x_coord = NULL; in_y_coord = NULL; in_z_coord = NULL; } break; } NumDimensions = 0; if (!(in_x_coord == 0 && in_y_coord == 0 && in_z_coord == 0)) { ML_Aggregate_Viz_Stats *grid_info = (ML_Aggregate_Viz_Stats *) ml_ptr->Grid[LevelID_[0]].Grid; ML_Operator* AAA = &(ml_ptr->Amat[LevelID_[0]]); int n = AAA->invec_leng, Nghost = 0; if (AAA->getrow->pre_comm) { if (AAA->getrow->pre_comm->total_rcv_length <= 0) ML_CommInfoOP_Compute_TotalRcvLength(AAA->getrow->pre_comm); Nghost = AAA->getrow->pre_comm->total_rcv_length; } std::vector<double> tmp(Nghost + n); for (int i = 0 ; i < Nghost + n ; ++i) tmp[i] = 0.0; n /= NumPDEEqns_; Nghost /= NumPDEEqns_; if (in_x_coord) { NumDimensions++; double* x_coord = (double *) ML_allocate(sizeof(double) * (Nghost+n)); for (int i = 0 ; i < n ; ++i) tmp[i * NumPDEEqns_] = in_x_coord[i]; ML_exchange_bdry(&tmp[0],AAA->getrow->pre_comm, NumPDEEqns_ * n, AAA->comm, ML_OVERWRITE,NULL); for (int i = 0 ; i < n + Nghost ; ++i) x_coord[i] = tmp[i * NumPDEEqns_]; grid_info->x = x_coord; } if (in_y_coord) { NumDimensions++; double* y_coord = (double *) ML_allocate(sizeof(double) * (Nghost+n)); for (int i = 0 ; i < n ; ++i) tmp[i * NumPDEEqns_] = in_y_coord[i]; ML_exchange_bdry(&tmp[0],AAA->getrow->pre_comm, NumPDEEqns_ * n, AAA->comm, ML_OVERWRITE,NULL); for (int i = 0 ; i < n + Nghost ; ++i) y_coord[i] = tmp[i * NumPDEEqns_]; grid_info->y = y_coord; } if (in_z_coord) { NumDimensions++; double* z_coord = (double *) ML_allocate(sizeof(double) * (Nghost+n)); for (int i = 0 ; i < n ; ++i) tmp[i * NumPDEEqns_] = in_z_coord[i]; ML_exchange_bdry(&tmp[0],AAA->getrow->pre_comm, NumPDEEqns_ * n, AAA->comm, ML_OVERWRITE,NULL); for (int i = 0 ; i < n + Nghost ; ++i) z_coord[i] = tmp[i * NumPDEEqns_]; grid_info->z = z_coord; } grid_info->Ndim = NumDimensions; } // if (!(in_x_coord == 0 && in_y_coord == 0 && in_z_coord == 0)) } //for (int ii=0; ii<2; ii++) return(0); }
// ================================================ ====== ==== ==== == = // Copied from ml_agg_genP.c static void ML_Init_Aux(ML_Operator* A, Teuchos::ParameterList &List) { int i, j, n, count, num_PDEs, BlockRow, BlockCol; double threshold; int* columns; double* values; int allocated, entries = 0; int N_dimensions; int DiagID; double DiagValue; int** filter; double dist; double *LaplacianDiag; int Nghost; // Boundary exchange the coords double *x_coord=0, *y_coord=0, *z_coord=0; RefMaxwell_SetupCoordinates(A,List,x_coord,y_coord,z_coord); int dim=(x_coord!=0) + (y_coord!=0) + (z_coord!=0); /* Sanity Checks */ if(dim == 0 || ((!x_coord && (y_coord || z_coord)) || (x_coord && !y_coord && z_coord))){ std::cerr<<"Error: Coordinates not defined. This is necessary for aux aggregation (found "<<dim<<" coordinates).\n"; exit(-1); } num_PDEs = A->num_PDEs; N_dimensions = dim; threshold = A->aux_data->threshold; ML_Operator_AmalgamateAndDropWeak(A, num_PDEs, 0.0); n = A->invec_leng; Nghost = ML_CommInfoOP_Compute_TotalRcvLength(A->getrow->pre_comm); LaplacianDiag = (double *) ML_allocate((A->getrow->Nrows+Nghost+1)* sizeof(double)); filter = (int**) ML_allocate(sizeof(int*) * n); allocated = 128; columns = (int *) ML_allocate(allocated * sizeof(int)); values = (double *) ML_allocate(allocated * sizeof(double)); for (i = 0 ; i < n ; ++i) { BlockRow = i; DiagID = -1; DiagValue = 0.0; ML_get_matrix_row(A,1,&i,&allocated,&columns,&values, &entries,0); for (j = 0; j < entries; j++) { BlockCol = columns[j]; if (BlockRow != BlockCol) { dist = 0.0; switch (N_dimensions) { case 3: dist += (z_coord[BlockRow] - z_coord[BlockCol]) * (z_coord[BlockRow] - z_coord[BlockCol]); case 2: dist += (y_coord[BlockRow] - y_coord[BlockCol]) * (y_coord[BlockRow] - y_coord[BlockCol]); case 1: dist += (x_coord[BlockRow] - x_coord[BlockCol]) * (x_coord[BlockRow] - x_coord[BlockCol]); } if (dist == 0.0) { printf("node %d = %e ", i, x_coord[BlockRow]); if (N_dimensions > 1) printf(" %e ", y_coord[BlockRow]); if (N_dimensions > 2) printf(" %e ", z_coord[BlockRow]); printf("\n"); printf("node %d = %e ", j, x_coord[BlockCol]); if (N_dimensions > 1) printf(" %e ", y_coord[BlockCol]); if (N_dimensions > 2) printf(" %e ", z_coord[BlockCol]); printf("\n"); printf("Operator has inlen = %d and outlen = %d\n", A->invec_leng, A->outvec_leng); } dist = 1.0 / dist; DiagValue += dist; } else if (columns[j] == i) { DiagID = j; } } if (DiagID == -1) { fprintf(stderr, "ERROR: matrix has no diagonal!\n" "ERROR: (file %s, line %d)\n", __FILE__, __LINE__); exit(EXIT_FAILURE); } LaplacianDiag[BlockRow] = DiagValue; } if ( A->getrow->pre_comm != NULL ) ML_exchange_bdry(LaplacianDiag,A->getrow->pre_comm,A->getrow->Nrows, A->comm, ML_OVERWRITE,NULL); for (i = 0 ; i < n ; ++i) { BlockRow = i; ML_get_matrix_row(A,1,&i,&allocated,&columns,&values, &entries,0); for (j = 0; j < entries; j++) { BlockCol = columns[j]; if (BlockRow != BlockCol) { dist = 0.0; switch (N_dimensions) { case 3: dist += (z_coord[BlockRow] - z_coord[BlockCol]) * (z_coord[BlockRow] - z_coord[BlockCol]); case 2: dist += (y_coord[BlockRow] - y_coord[BlockCol]) * (y_coord[BlockRow] - y_coord[BlockCol]); case 1: dist += (x_coord[BlockRow] - x_coord[BlockCol]) * (x_coord[BlockRow] - x_coord[BlockCol]); } dist = 1.0 / dist; values[j] = dist; } } count = 0; for (j = 0 ; j < entries ; ++j) { if ( (i != columns[j]) && (values[j]*values[j] < LaplacianDiag[BlockRow]*LaplacianDiag[columns[j]]*threshold*threshold)){ columns[count++] = columns[j]; } } /* insert the rows */ filter[BlockRow] = (int*) ML_allocate(sizeof(int) * (count + 1)); filter[BlockRow][0] = count; for (j = 0 ; j < count ; ++j) filter[BlockRow][j + 1] = columns[j]; } ML_free(columns); ML_free(values); ML_free(LaplacianDiag); ML_Operator_UnAmalgamateAndDropWeak(A, num_PDEs, 0.0); A->aux_data->aux_func_ptr = A->getrow->func_ptr; A->getrow->func_ptr = ML_Aux_Getrow; A->aux_data->filter = filter; A->aux_data->filter_size = n; // Cleanup ML_free(x_coord); ML_free(y_coord); ML_free(z_coord); }
// ====================================================================== int ML_Operator_Add2(ML_Operator *A, ML_Operator *B, ML_Operator *C, int matrix_type, double scalarA, double scalarB) { int A_allocated = 0, *A_bindx = NULL, B_allocated = 0, *B_bindx = NULL; double *A_val = NULL, *B_val = NULL, *hashed_vals; int i, A_length, B_length, *hashed_inds; int max_nz_per_row = 0, min_nz_per_row=1e6, j; int hash_val, index_length; int *columns, *rowptr, nz_ptr, hash_used, global_col; double *values; struct ML_CSR_MSRdata *temp; int *A_gids, *B_gids; int max_per_proc; #ifdef ML_WITH_EPETRA int count; #endif if (A->getrow == NULL) pr_error("ML_Operator_Add: A does not have a getrow function.\n"); if (B->getrow == NULL) pr_error("ML_Operator_Add: B does not have a getrow function.\n"); if (A->getrow->Nrows != B->getrow->Nrows) { printf("ML_Operator_Add: Can not add, two matrices do not have the same"); printf(" number of rows %d vs %d",A->getrow->Nrows,B->getrow->Nrows); exit(1); } if (A->invec_leng != B->invec_leng) { printf("ML_Operator_Add: Can not add, two matrices do not have the same"); printf(" number of columns %d vs %d",A->getrow->Nrows,B->getrow->Nrows); exit(1); } /* let's just count some things */ index_length = A->invec_leng + 1; if (A->getrow->pre_comm != NULL) { ML_CommInfoOP_Compute_TotalRcvLength(A->getrow->pre_comm); index_length += A->getrow->pre_comm->total_rcv_length; } if (B->getrow->pre_comm != NULL) { ML_CommInfoOP_Compute_TotalRcvLength(B->getrow->pre_comm); index_length += B->getrow->pre_comm->total_rcv_length; } ML_create_unique_col_id(A->invec_leng, &A_gids, A->getrow->pre_comm, &max_per_proc,A->comm); ML_create_unique_col_id(B->invec_leng, &B_gids, B->getrow->pre_comm, &max_per_proc,B->comm); hashed_inds = (int *) ML_allocate(sizeof(int)*index_length); hashed_vals = (double *) ML_allocate(sizeof(double)*index_length); for (i = 0; i < index_length; i++) hashed_inds[i] = -1; for (i = 0; i < index_length; i++) hashed_vals[i] = 0.; nz_ptr = 0; for (i = 0 ; i < A->getrow->Nrows; i++) { hash_used = 0; ML_get_matrix_row(A, 1, &i, &A_allocated, &A_bindx, &A_val, &A_length, 0); for (j = 0; j < A_length; j++) { global_col = A_gids[A_bindx[j]]; ML_hash_it(global_col, hashed_inds, index_length,&hash_used,&hash_val); hashed_inds[hash_val] = global_col; hashed_vals[hash_val] += scalarA * A_val[j]; A_bindx[j] = hash_val; } ML_get_matrix_row(B, 1, &i, &B_allocated, &B_bindx, &B_val, &B_length, 0); for (j = 0; j < B_length; j++) { global_col = B_gids[B_bindx[j]]; ML_hash_it(global_col, hashed_inds, index_length,&hash_used, &hash_val); hashed_inds[hash_val] = global_col; hashed_vals[hash_val] += scalarB*B_val[j]; B_bindx[j] = hash_val; } for (j = 0; j < A_length; j++) { nz_ptr++; hashed_inds[A_bindx[j]] = -1; hashed_vals[A_bindx[j]] = 0.; } for (j = 0; j < B_length; j++) { if (hashed_inds[B_bindx[j]] != -1) { nz_ptr++; hashed_inds[B_bindx[j]] = -1; hashed_vals[B_bindx[j]] = 0.; } } } nz_ptr++; columns = 0; values = 0; rowptr = (int *) ML_allocate(sizeof(int)*(A->outvec_leng+1)); if (matrix_type == ML_CSR_MATRIX) { columns= (int *) ML_allocate(sizeof(int)*nz_ptr); values = (double *) ML_allocate(sizeof(double)*nz_ptr); } #ifdef ML_WITH_EPETRA else if (matrix_type == ML_EpetraCRS_MATRIX) { columns= (int *) ML_allocate(sizeof(int)*(index_length+1)); values = (double *) ML_allocate(sizeof(double)*(index_length+1)); } #endif else { pr_error("ML_Operator_Add: Unknown matrix type\n"); } nz_ptr = 0; rowptr[0] = 0; for (i = 0 ; i < A->getrow->Nrows; i++) { hash_used = 0; ML_get_matrix_row(A, 1, &i, &A_allocated, &A_bindx, &A_val, &A_length, 0); for (j = 0; j < A_length; j++) { global_col = A_gids[A_bindx[j]]; ML_hash_it(global_col, hashed_inds, index_length,&hash_used, &hash_val); hashed_inds[hash_val] = global_col; hashed_vals[hash_val] += scalarA * A_val[j]; A_bindx[j] = hash_val; } ML_get_matrix_row(B, 1, &i, &B_allocated, &B_bindx, &B_val, &B_length, 0); for (j = 0; j < B_length; j++) { global_col = B_gids[B_bindx[j]]; ML_hash_it(global_col, hashed_inds, index_length,&hash_used, &hash_val); hashed_inds[hash_val] = global_col; hashed_vals[hash_val] += scalarB*B_val[j]; B_bindx[j] = hash_val; } #ifdef ML_WITH_EPETRA if (matrix_type == ML_EpetraCRS_MATRIX) { for (j = 0; j < A_length; j++) { columns[j] = hashed_inds[A_bindx[j]]; values[j] = hashed_vals[A_bindx[j]]; nz_ptr++; hashed_inds[A_bindx[j]] = -1; hashed_vals[A_bindx[j]] = 0.; } count = A_length; for (j = 0; j < B_length; j++) { if (hashed_inds[B_bindx[j]] != -1) { columns[count] = hashed_inds[B_bindx[j]]; values[count++] = hashed_vals[B_bindx[j]]; nz_ptr++; hashed_inds[B_bindx[j]] = -1; hashed_vals[B_bindx[j]] = 0.; } } ML_Epetra_CRSinsert(C,i,columns,values,count); } else { #endif for (j = 0; j < A_length; j++) { columns[nz_ptr] = hashed_inds[A_bindx[j]]; values[nz_ptr] = hashed_vals[A_bindx[j]]; nz_ptr++; hashed_inds[A_bindx[j]] = -1; hashed_vals[A_bindx[j]] = 0.; } for (j = 0; j < B_length; j++) { if (hashed_inds[B_bindx[j]] != -1) { columns[nz_ptr] = hashed_inds[B_bindx[j]]; values[nz_ptr] = hashed_vals[B_bindx[j]]; nz_ptr++; hashed_inds[B_bindx[j]] = -1; hashed_vals[B_bindx[j]] = 0.; } } #ifdef ML_WITH_EPETRA } #endif rowptr[i+1] = nz_ptr; j = rowptr[i+1] - rowptr[i]; if (j > max_nz_per_row) max_nz_per_row = j; if (j < min_nz_per_row && j>0) min_nz_per_row = j; } if (matrix_type == ML_CSR_MATRIX) { temp = (struct ML_CSR_MSRdata *) ML_allocate(sizeof(struct ML_CSR_MSRdata)); if (temp == NULL) pr_error("ML_Operator_Add: no space for temp\n"); temp->columns = columns; temp->values = values; temp->rowptr = rowptr; ML_Operator_Set_ApplyFuncData(C, B->invec_leng, A->outvec_leng, temp,A->outvec_leng, NULL,0); ML_Operator_Set_Getrow(C, A->outvec_leng, CSR_getrow); ML_Operator_Set_ApplyFunc (C, CSR_matvec); ML_globalcsr2localcsr(C, max_per_proc); C->data_destroy = ML_CSR_MSRdata_Destroy; C->max_nz_per_row = max_nz_per_row; C->min_nz_per_row = min_nz_per_row; C->N_nonzeros = nz_ptr; } #ifdef ML_WITH_EPETRA else { ML_free(rowptr); ML_free(columns); ML_free(values); } #endif ML_free(A_gids); ML_free(B_gids); ML_free(hashed_vals); ML_free(hashed_inds); ML_free(A_val); ML_free(A_bindx); ML_free(B_val); ML_free(B_bindx); return 1; }
// ================================================ ====== ==== ==== == = int RefMaxwell_SetupCoordinates(ML_Operator* A, Teuchos::ParameterList &List_, double *&coordx, double *&coordy, double *&coordz) // Coppied From int ML_Epetra::MultiLevelPreconditioner::SetupCoordinates() { double* in_x_coord = 0; double* in_y_coord = 0; double* in_z_coord = 0; int NumPDEEqns_ =1; // Always use 1 because A is a nodal matrix. // For node coordinates in_x_coord = List_.get("x-coordinates", (double *)0); in_y_coord = List_.get("y-coordinates", (double *)0); in_z_coord = List_.get("z-coordinates", (double *)0); if (!(in_x_coord == 0 && in_y_coord == 0 && in_z_coord == 0)) { ML_Operator* AAA = A; int n = AAA->invec_leng, Nghost = 0; if (AAA->getrow->pre_comm) { if (AAA->getrow->pre_comm->total_rcv_length <= 0) ML_CommInfoOP_Compute_TotalRcvLength(AAA->getrow->pre_comm); Nghost = AAA->getrow->pre_comm->total_rcv_length; } std::vector<double> tmp(Nghost + n); for (int i = 0 ; i < Nghost + n ; ++i) tmp[i] = 0.0; n /= NumPDEEqns_; Nghost /= NumPDEEqns_; if (in_x_coord) { double* x_coord = (double *) ML_allocate(sizeof(double) * (Nghost+n)); for (int i = 0 ; i < n ; ++i) tmp[i * NumPDEEqns_] = in_x_coord[i]; ML_exchange_bdry(&tmp[0],AAA->getrow->pre_comm, NumPDEEqns_ * n, AAA->comm, ML_OVERWRITE,NULL); for (int i = 0 ; i < n + Nghost ; ++i) x_coord[i] = tmp[i * NumPDEEqns_]; coordx = x_coord; } if (in_y_coord) { double* y_coord = (double *) ML_allocate(sizeof(double) * (Nghost+n)); for (int i = 0 ; i < n ; ++i) tmp[i * NumPDEEqns_] = in_y_coord[i]; ML_exchange_bdry(&tmp[0],AAA->getrow->pre_comm, NumPDEEqns_ * n, AAA->comm, ML_OVERWRITE,NULL); for (int i = 0 ; i < n + Nghost ; ++i) y_coord[i] = tmp[i * NumPDEEqns_]; coordy = y_coord; } if (in_z_coord) { double* z_coord = (double *) ML_allocate(sizeof(double) * (Nghost+n)); for (int i = 0 ; i < n ; ++i) tmp[i * NumPDEEqns_] = in_z_coord[i]; ML_exchange_bdry(&tmp[0],AAA->getrow->pre_comm, NumPDEEqns_ * n, AAA->comm, ML_OVERWRITE,NULL); for (int i = 0 ; i < n + Nghost ; ++i) z_coord[i] = tmp[i * NumPDEEqns_]; coordz = z_coord; } } // if (!(in_x_coord == 0 && in_y_coord == 0 && in_z_coord == 0)) return(0); }