// // setup the boundary condition. // void setup_bc(int *update, int *update_index, int N_update, int **bc_indx, int *n_bc){ int x, y, z; int indx; int ymin = 4 * ny / 10; int ymax = 6 * ny / 10; int entry; x = 0; z = 0; *n_bc = 0; #define MAX_BC ny *bc_indx = (int *) malloc( 4 * MAX_BC * sizeof(int)); for(y = ymin; y < ymax; y++){ indx = pos_to_row(x, y, z) + 1; if((entry = AZ_find_index(indx, update, N_update)) != -1){ (*bc_indx)[4 * (*n_bc)+0] = x; (*bc_indx)[4 * (*n_bc)+1] = y - ymin; (*bc_indx)[4 * (*n_bc)+2] = z; (*bc_indx)[4 * (*n_bc)+3] = update_index[entry]; (*n_bc)++; } } }
//============================================================================== int AztecDVBR_Matrix::getBlockSize(int blkRow, int blkCol, int& ptRows, int& ptCols) { int index; ptRows = 0; ptCols = 0; if (!inUpdate(blkRow, index)) { fei::console_out() << "AztecDVBR_Matrix::getBlockSize: ERROR: blkRow " << blkRow << " not in local update list." << FEI_ENDL; return(1); } ptRows = Amat_->rpntr[index+1] - Amat_->rpntr[index]; int local = inUpdate(blkCol, index); if (local) { ptCols = Amat_->rpntr[index+1] - Amat_->rpntr[index]; } else { index = AZ_find_index(blkCol, remoteInds_, numRemoteBlocks_); if (index < 0) return(1); else ptCols = remoteBlockSizes_[index]; } return(0); }
void print_global_element(int element,int update[],int data_org[], int update_index[], int rpntr[], double vector[],int proc_config[]) { /* * Print out the vector element corresponding to the global numbering * 'element'. Note: if the VBR format is used, this routine will print * out all the vector elements corresponding to this block. * * Author: Ray Tuminaro, Div 1422, SNL * Date: 6/15/96 * * Parameters * * element == On input, global number of vector element that * will be printed. * update == On input, list of pts updated on this node * data_org == On input, indicates how the data is set out on * this node. For example, data_org[] contains * information on how many unknowns are internal, * external, and border unknowns as well as which * points need to be communicated. See User's Guide * for more details. * update_index == On input, ordering of update locally on this * processor. For example, 'update_index[i]' gives * the index location of the block which has the * global index 'update[i]'. * rpntr == On input, rpntr[i+1]-rpntr[i] gives the block * size of the ith local block. * vector == On input, vector to be printed (just one element). * proc_config == On input, processor information: * proc_config[AZ_node] = name of this processor * proc_config[AZ_N_procs] = # of processors used */ int i,k; /* synchronize things */ fflush(stdout); i = AZ_gsum_int(1,proc_config); i = AZ_find_index(element,update, data_org[AZ_N_int_blk]+data_org[AZ_N_bord_blk]); if (i !=-1) { i = update_index[i]; if (data_org[AZ_matrix_type] == AZ_MSR_MATRIX) fprintf(stdout,"(%d) = %e\n",element,vector[i]); else if (data_org[AZ_matrix_type] == AZ_VBR_MATRIX) { for (k = rpntr[i]; k < rpntr[i+1]; k++ ) fprintf(stdout,"(%d,%d) = %e\n",element,k-rpntr[i],vector[k]); } fflush(stdout); } /* synchronize things */ i = AZ_gsum_int(i,proc_config); }
//============================================================================== void AztecDVBR_Matrix::insertList(int item, int*& list, int& len) { // //insert 'item' in 'list', if it's not already in there, //and update the list's length, 'len'. // //We want to keep the list ordered, so we'll insert item in //the list after the biggest existing entry that's smaller, and //before the smallest existing entry that's bigger. // if (len <= 0) { list = new int[1]; list[0] = item; len = 1; return; } int index = AZ_find_index(item, list, len); if (index >= 0) return; int* newList = new int[len+1]; //bring over the contents of the old list, putting in the new //one at the appropriate point. int inserted = 0; for(int i=0; i<len; i++) { if (!inserted) { if (list[i] < item) newList[i] = list[i]; else { newList[i] = item; inserted = 1; } } else newList[i] = list[i-1]; } //now put in the last list entry if (inserted) newList[len] = list[len-1]; else newList[len] = item; //delete the old memory and reset the pointer. if (len > 0) delete [] list; list = newList; //update the length. len++; }
//============================================================================== int AztecDVBR_Matrix::inUpdate(int globalIndex, int& localIndex) const { // // This function determines whether globalIndex is in the local update set, // and if it is, returns in localIndex the local index for it. If update_index_ // has already been allocated and set (by AZ_transform) then localIndex is // taken from there. // If globalIndex is not in the update set, inUpdate returns 0. // localIndex = AZ_find_index(globalIndex, amap_->getBlockUpdate(), N_update_); if(localIndex==-1)return(0); if(isLoaded_){ localIndex = update_index_[localIndex]; } return(1); }
//============================================================================== void AztecDVBR_Matrix::calcIndx(int nnzBlks) { // //This function allocates and fills the Amat_->indx array, which holds info //on the number of entries in each nonzero block. // //indx[0..bpntr[M]], (where M = number of local block rows) //indx[0] = 0 //indx[k+1]-indx[k] = number of entries in nonzero block k // Amat_->indx = new int[nnzBlks+1]; //we need to obtain block sizes for all local nonzero blocks. rpntr //gives us the sizes for the blocks with column indices in the local //update set, but we'll have to do some message passing to obtain the //sizes of blocks with column indices in other procs' update sets. int numProcs = amap_->getProcConfig()[AZ_N_procs]; if (numProcs > 1) { //form a list of the column indices that are not local. calcRemoteInds(remoteInds_, numRemoteBlocks_); //now get sizes of blocks that correspond to remote rows. remoteBlockSizes_ = new int[numRemoteBlocks_]; getRemoteBlkSizes(remoteBlockSizes_, remoteInds_, numRemoteBlocks_); } //now we're ready to set the block sizes in Amat_->indx. int index; Amat_->indx[0] = 0; for(int i=0; i<amap_->getNumLocalBlocks(); i++) { int rowBlkSize = Amat_->rpntr[i+1] - Amat_->rpntr[i]; int colStart = Amat_->bpntr[i]; int colEnd = Amat_->bpntr[i+1] - 1; for(int j=colStart; j<=colEnd; j++) { if (inUpdate(Amat_->bindx[j], index)) { int colBlkSize = Amat_->rpntr[index+1] - Amat_->rpntr[index]; Amat_->indx[j+1] = Amat_->indx[j] + rowBlkSize*colBlkSize; } else { //it's a remoteIndex if (numProcs == 1) { char mesg[80]; sprintf(mesg,"calcIndx: blk col index %d not in update set.", Amat_->bindx[j]); messageAbort(mesg); } index = AZ_find_index(Amat_->bindx[j], remoteInds_, numRemoteBlocks_); if (index >= 0) { Amat_->indx[j+1] = Amat_->indx[j] + rowBlkSize*remoteBlockSizes_[index]; } else { //if it wasn't in update or remoteInds, then panic! messageAbort("calcIndx: block column index not found."); } } } // end for j loop nnzPerRow_[i] = Amat_->indx[colEnd+1] - Amat_->indx[colStart]; } // end for i loop localNNZ_ = Amat_->indx[nnzBlks]; }