blob: dfe2e30e41c5e7c6c9254a9a940dc27b39ea7396 [file] [log] [blame]
/*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;
}