/*BHEADER********************************************************************** * (c) 1997 The Regents of the University of California * * See the file COPYRIGHT_and_DISCLAIMER for a complete copyright * notice, contact person, and disclaimer. * * $Revision$ *********************************************************************EHEADER*/ /****************************************************************************** * * Constructors and destructors for stencil structure. * *****************************************************************************/ #include "headers.h" /*-------------------------------------------------------------------------- * hypre_StructStencilCreate *--------------------------------------------------------------------------*/ hypre_StructStencil * hypre_StructStencilCreate( int dim, int size, hypre_Index *shape ) { hypre_StructStencil *stencil; int abs_offset; int max_offset; int s, d; stencil = hypre_TAlloc(hypre_StructStencil, 1); hypre_StructStencilShape(stencil) = shape; hypre_StructStencilSize(stencil) = size; hypre_StructStencilDim(stencil) = dim; hypre_StructStencilRefCount(stencil) = 1; /* compute max_offset */ max_offset = 0; for (s = 0; s < size; s++) { for (d = 0; d < 3; d++) { abs_offset = hypre_IndexD(shape[s], d); abs_offset = (abs_offset < 0) ? -abs_offset : abs_offset; max_offset = hypre_max(abs_offset, max_offset); } } hypre_StructStencilMaxOffset(stencil) = max_offset; return stencil; } /*-------------------------------------------------------------------------- * hypre_StructStencilRef *--------------------------------------------------------------------------*/ hypre_StructStencil * hypre_StructStencilRef( hypre_StructStencil *stencil ) { hypre_StructStencilRefCount(stencil) ++; return stencil; } /*-------------------------------------------------------------------------- * hypre_StructStencilDestroy *--------------------------------------------------------------------------*/ int hypre_StructStencilDestroy( hypre_StructStencil *stencil ) { int ierr = 0; if (stencil) { hypre_StructStencilRefCount(stencil) --; if (hypre_StructStencilRefCount(stencil) == 0) { hypre_TFree(hypre_StructStencilShape(stencil)); hypre_TFree(stencil); } } return ierr; } /*-------------------------------------------------------------------------- * hypre_StructStencilElementRank * Returns the rank of the `stencil_element' in `stencil'. * If the element is not found, a -1 is returned. *--------------------------------------------------------------------------*/ int hypre_StructStencilElementRank( hypre_StructStencil *stencil, hypre_Index stencil_element ) { hypre_Index *stencil_shape; int rank; int i; rank = -1; stencil_shape = hypre_StructStencilShape(stencil); for (i = 0; i < hypre_StructStencilSize(stencil); i++) { if ((hypre_IndexX(stencil_shape[i]) == hypre_IndexX(stencil_element)) && (hypre_IndexY(stencil_shape[i]) == hypre_IndexY(stencil_element)) && (hypre_IndexZ(stencil_shape[i]) == hypre_IndexZ(stencil_element)) ) { rank = i; break; } } return rank; } /*-------------------------------------------------------------------------- * hypre_StructStencilSymmetrize: * Computes a new "symmetrized" stencil. * * An integer array called `symm_elements' is also set up. A non-negative * value of `symm_elements[i]' indicates that the `i'th stencil element * is a "symmetric element". That is, this stencil element is the * transpose element of an element that is not a "symmetric element". *--------------------------------------------------------------------------*/ int hypre_StructStencilSymmetrize( hypre_StructStencil *stencil, hypre_StructStencil **symm_stencil_ptr, int **symm_elements_ptr ) { hypre_Index *stencil_shape = hypre_StructStencilShape(stencil); int stencil_size = hypre_StructStencilSize(stencil); hypre_StructStencil *symm_stencil; hypre_Index *symm_stencil_shape; int symm_stencil_size; int *symm_elements; int no_symmetric_stencil_element; int i, j, d; int ierr = 0; /*------------------------------------------------------ * Copy stencil elements into `symm_stencil_shape' *------------------------------------------------------*/ symm_stencil_shape = hypre_CTAlloc(hypre_Index, 2*stencil_size); for (i = 0; i < stencil_size; i++) { hypre_CopyIndex(stencil_shape[i], symm_stencil_shape[i]); } /*------------------------------------------------------ * Create symmetric stencil elements and `symm_elements' *------------------------------------------------------*/ symm_elements = hypre_CTAlloc(int, 2*stencil_size); for (i = 0; i < 2*stencil_size; i++) symm_elements[i] = -1; symm_stencil_size = stencil_size; for (i = 0; i < stencil_size; i++) { if (symm_elements[i] < 0) { /* note: start at i to handle "center" element correctly */ no_symmetric_stencil_element = 1; for (j = i; j < stencil_size; j++) { if ( (hypre_IndexX(symm_stencil_shape[j]) == -hypre_IndexX(symm_stencil_shape[i]) ) && (hypre_IndexY(symm_stencil_shape[j]) == -hypre_IndexY(symm_stencil_shape[i]) ) && (hypre_IndexZ(symm_stencil_shape[j]) == -hypre_IndexZ(symm_stencil_shape[i]) ) ) { /* only "off-center" elements have symmetric entries */ if (i != j) symm_elements[j] = i; no_symmetric_stencil_element = 0; } } if (no_symmetric_stencil_element) { /* add symmetric stencil element to `symm_stencil' */ for (d = 0; d < 3; d++) { hypre_IndexD(symm_stencil_shape[symm_stencil_size], d) = -hypre_IndexD(symm_stencil_shape[i], d); } symm_elements[symm_stencil_size] = i; symm_stencil_size++; } } } symm_stencil = hypre_StructStencilCreate(hypre_StructStencilDim(stencil), symm_stencil_size, symm_stencil_shape); *symm_stencil_ptr = symm_stencil; *symm_elements_ptr = symm_elements; return ierr; }