- Generalized the Struct communication routines to handle data transformations - Added more flexibility to Set(Box)Values routines for efficiency. - Inter-part shared boundary data is now updated appropriately - Added SetNeighborPart function (to replace SetNeighborBox) - Added a finite-element-style input file capability for the sstruct driver - The Split solver can now be used standalone (added to struct/sstruct drivers) - Added a Jacobi block solver to Split (useful for regression testing) - Added regression tests for the new SetNeighborPart features
1263 lines
44 KiB
C
1263 lines
44 KiB
C
/*BHEADER**********************************************************************
|
|
* Copyright (c) 2007, Lawrence Livermore National Security, LLC.
|
|
* Produced at the Lawrence Livermore National Laboratory.
|
|
* Written by the HYPRE team. UCRL-CODE-222953.
|
|
* All rights reserved.
|
|
*
|
|
* This file is part of HYPRE (see http://www.llnl.gov/CASC/hypre/).
|
|
* Please see the COPYRIGHT_and_LICENSE file for the copyright notice,
|
|
* disclaimer, contact information and the GNU Lesser General Public License.
|
|
*
|
|
* HYPRE is free software; you can redistribute it and/or modify it under the
|
|
* terms of the GNU General Public License (as published by the Free Software
|
|
* Foundation) version 2.1 dated February 1999.
|
|
*
|
|
* HYPRE is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
* WARRANTY; without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the terms and conditions of the GNU General
|
|
* Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program; if not, write to the Free Software Foundation,
|
|
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* $Revision$
|
|
***********************************************************************EHEADER*/
|
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Member functions for hypre_SStructPMatrix class.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "headers.h"
|
|
|
|
/*==========================================================================
|
|
* SStructPMatrix routines
|
|
*==========================================================================*/
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixRef( hypre_SStructPMatrix *matrix,
|
|
hypre_SStructPMatrix **matrix_ref )
|
|
{
|
|
hypre_SStructPMatrixRefCount(matrix) ++;
|
|
*matrix_ref = matrix;
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixCreate( MPI_Comm comm,
|
|
hypre_SStructPGrid *pgrid,
|
|
hypre_SStructStencil **stencils,
|
|
hypre_SStructPMatrix **pmatrix_ptr )
|
|
{
|
|
hypre_SStructPMatrix *pmatrix;
|
|
int nvars;
|
|
int **smaps;
|
|
hypre_StructStencil ***sstencils;
|
|
hypre_StructMatrix ***smatrices;
|
|
int **symmetric;
|
|
|
|
hypre_StructStencil *sstencil;
|
|
int *vars;
|
|
hypre_Index *sstencil_shape;
|
|
int sstencil_size;
|
|
int new_dim;
|
|
int *new_sizes;
|
|
hypre_Index **new_shapes;
|
|
int size;
|
|
hypre_StructGrid *sgrid;
|
|
|
|
int vi, vj;
|
|
int i, j, k;
|
|
|
|
pmatrix = hypre_TAlloc(hypre_SStructPMatrix, 1);
|
|
|
|
hypre_SStructPMatrixComm(pmatrix) = comm;
|
|
hypre_SStructPMatrixPGrid(pmatrix) = pgrid;
|
|
hypre_SStructPMatrixStencils(pmatrix) = stencils;
|
|
nvars = hypre_SStructPGridNVars(pgrid);
|
|
hypre_SStructPMatrixNVars(pmatrix) = nvars;
|
|
|
|
/* create sstencils */
|
|
smaps = hypre_TAlloc(int *, nvars);
|
|
sstencils = hypre_TAlloc(hypre_StructStencil **, nvars);
|
|
new_sizes = hypre_TAlloc(int, nvars);
|
|
new_shapes = hypre_TAlloc(hypre_Index *, nvars);
|
|
size = 0;
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
sstencils[vi] = hypre_TAlloc(hypre_StructStencil *, nvars);
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
sstencils[vi][vj] = NULL;
|
|
new_sizes[vj] = 0;
|
|
}
|
|
|
|
sstencil = hypre_SStructStencilSStencil(stencils[vi]);
|
|
vars = hypre_SStructStencilVars(stencils[vi]);
|
|
sstencil_shape = hypre_StructStencilShape(sstencil);
|
|
sstencil_size = hypre_StructStencilSize(sstencil);
|
|
|
|
smaps[vi] = hypre_TAlloc(int, sstencil_size);
|
|
for (i = 0; i < sstencil_size; i++)
|
|
{
|
|
j = vars[i];
|
|
new_sizes[j]++;
|
|
}
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
if (new_sizes[vj])
|
|
{
|
|
new_shapes[vj] = hypre_TAlloc(hypre_Index, new_sizes[vj]);
|
|
new_sizes[vj] = 0;
|
|
}
|
|
}
|
|
for (i = 0; i < sstencil_size; i++)
|
|
{
|
|
j = vars[i];
|
|
k = new_sizes[j];
|
|
hypre_CopyIndex(sstencil_shape[i], new_shapes[j][k]);
|
|
smaps[vi][i] = k;
|
|
new_sizes[j]++;
|
|
}
|
|
new_dim = hypre_StructStencilDim(sstencil);
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
if (new_sizes[vj])
|
|
{
|
|
sstencils[vi][vj] = hypre_StructStencilCreate(new_dim,
|
|
new_sizes[vj],
|
|
new_shapes[vj]);
|
|
}
|
|
size = hypre_max(size, new_sizes[vj]);
|
|
}
|
|
}
|
|
hypre_SStructPMatrixSMaps(pmatrix) = smaps;
|
|
hypre_SStructPMatrixSStencils(pmatrix) = sstencils;
|
|
hypre_TFree(new_sizes);
|
|
hypre_TFree(new_shapes);
|
|
|
|
/* create smatrices */
|
|
smatrices = hypre_TAlloc(hypre_StructMatrix **, nvars);
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
smatrices[vi] = hypre_TAlloc(hypre_StructMatrix *, nvars);
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
smatrices[vi][vj] = NULL;
|
|
if (sstencils[vi][vj] != NULL)
|
|
{
|
|
sgrid = hypre_SStructPGridSGrid(pgrid, vi);
|
|
smatrices[vi][vj] =
|
|
hypre_StructMatrixCreate(comm, sgrid, sstencils[vi][vj]);
|
|
}
|
|
}
|
|
}
|
|
hypre_SStructPMatrixSMatrices(pmatrix) = smatrices;
|
|
|
|
/* create symmetric */
|
|
symmetric = hypre_TAlloc(int *, nvars);
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
symmetric[vi] = hypre_TAlloc(int, nvars);
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
symmetric[vi][vj] = 0;
|
|
}
|
|
}
|
|
hypre_SStructPMatrixSymmetric(pmatrix) = symmetric;
|
|
|
|
hypre_SStructPMatrixSEntriesSize(pmatrix) = size;
|
|
hypre_SStructPMatrixSEntries(pmatrix) = hypre_TAlloc(int, size);
|
|
|
|
hypre_SStructPMatrixRefCount(pmatrix) = 1;
|
|
|
|
*pmatrix_ptr = pmatrix;
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixDestroy( hypre_SStructPMatrix *pmatrix )
|
|
{
|
|
hypre_SStructStencil **stencils;
|
|
int nvars;
|
|
int **smaps;
|
|
hypre_StructStencil ***sstencils;
|
|
hypre_StructMatrix ***smatrices;
|
|
int **symmetric;
|
|
int vi, vj;
|
|
|
|
if (pmatrix)
|
|
{
|
|
hypre_SStructPMatrixRefCount(pmatrix) --;
|
|
if (hypre_SStructPMatrixRefCount(pmatrix) == 0)
|
|
{
|
|
stencils = hypre_SStructPMatrixStencils(pmatrix);
|
|
nvars = hypre_SStructPMatrixNVars(pmatrix);
|
|
smaps = hypre_SStructPMatrixSMaps(pmatrix);
|
|
sstencils = hypre_SStructPMatrixSStencils(pmatrix);
|
|
smatrices = hypre_SStructPMatrixSMatrices(pmatrix);
|
|
symmetric = hypre_SStructPMatrixSymmetric(pmatrix);
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
HYPRE_SStructStencilDestroy(stencils[vi]);
|
|
hypre_TFree(smaps[vi]);
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
hypre_StructStencilDestroy(sstencils[vi][vj]);
|
|
hypre_StructMatrixDestroy(smatrices[vi][vj]);
|
|
}
|
|
hypre_TFree(sstencils[vi]);
|
|
hypre_TFree(smatrices[vi]);
|
|
hypre_TFree(symmetric[vi]);
|
|
}
|
|
hypre_TFree(stencils);
|
|
hypre_TFree(smaps);
|
|
hypre_TFree(sstencils);
|
|
hypre_TFree(smatrices);
|
|
hypre_TFree(symmetric);
|
|
hypre_TFree(hypre_SStructPMatrixSEntries(pmatrix));
|
|
hypre_TFree(pmatrix);
|
|
}
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
int
|
|
hypre_SStructPMatrixInitialize( hypre_SStructPMatrix *pmatrix )
|
|
{
|
|
int nvars = hypre_SStructPMatrixNVars(pmatrix);
|
|
int **symmetric = hypre_SStructPMatrixSymmetric(pmatrix);
|
|
int num_ghost[6] = {1, 1, 1, 1, 1, 1};
|
|
hypre_StructMatrix *smatrix;
|
|
int vi, vj;
|
|
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
smatrix = hypre_SStructPMatrixSMatrix(pmatrix, vi, vj);
|
|
if (smatrix != NULL)
|
|
{
|
|
HYPRE_StructMatrixSetSymmetric(smatrix, symmetric[vi][vj]);
|
|
hypre_StructMatrixSetNumGhost(smatrix, num_ghost);
|
|
hypre_StructMatrixInitialize(smatrix);
|
|
/* needed to get AddTo accumulation correct between processors */
|
|
hypre_StructMatrixClearGhostValues(smatrix);
|
|
}
|
|
}
|
|
}
|
|
|
|
hypre_SStructPMatrixAccumulated(pmatrix) = 0;
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* (action > 0): add-to values
|
|
* (action = 0): set values
|
|
* (action < 0): get values
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixSetValues( hypre_SStructPMatrix *pmatrix,
|
|
hypre_Index index,
|
|
int var,
|
|
int nentries,
|
|
int *entries,
|
|
double *values,
|
|
int action )
|
|
{
|
|
hypre_SStructStencil *stencil = hypre_SStructPMatrixStencil(pmatrix, var);
|
|
int *smap = hypre_SStructPMatrixSMap(pmatrix, var);
|
|
int *vars = hypre_SStructStencilVars(stencil);
|
|
hypre_StructMatrix *smatrix;
|
|
int *sentries;
|
|
int i;
|
|
|
|
smatrix = hypre_SStructPMatrixSMatrix(pmatrix, var, vars[entries[0]]);
|
|
|
|
sentries = hypre_SStructPMatrixSEntries(pmatrix);
|
|
for (i = 0; i < nentries; i++)
|
|
{
|
|
sentries[i] = smap[entries[i]];
|
|
}
|
|
|
|
/* set values inside the grid */
|
|
hypre_StructMatrixSetValues(smatrix, index, nentries, sentries, values,
|
|
action, -1, 0);
|
|
|
|
/* set values outside the grid in ghost zones (for AddTo and Get) */
|
|
if (action != 0)
|
|
{
|
|
hypre_SStructPGrid *pgrid = hypre_SStructPMatrixPGrid(pmatrix);
|
|
hypre_Index varoffset;
|
|
hypre_BoxArray *grid_boxes;
|
|
hypre_Box *box;
|
|
int done = 0;
|
|
|
|
grid_boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(smatrix));
|
|
|
|
hypre_ForBoxI(i, grid_boxes)
|
|
{
|
|
box = hypre_BoxArrayBox(grid_boxes, i);
|
|
if ((hypre_IndexX(index) >= hypre_BoxIMinX(box)) &&
|
|
(hypre_IndexX(index) <= hypre_BoxIMaxX(box)) &&
|
|
(hypre_IndexY(index) >= hypre_BoxIMinY(box)) &&
|
|
(hypre_IndexY(index) <= hypre_BoxIMaxY(box)) &&
|
|
(hypre_IndexZ(index) >= hypre_BoxIMinZ(box)) &&
|
|
(hypre_IndexZ(index) <= hypre_BoxIMaxZ(box)) )
|
|
{
|
|
done = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!done)
|
|
{
|
|
hypre_SStructVariableGetOffset(hypre_SStructPGridVarType(pgrid, var),
|
|
hypre_SStructPGridNDim(pgrid), varoffset);
|
|
hypre_ForBoxI(i, grid_boxes)
|
|
{
|
|
box = hypre_BoxArrayBox(grid_boxes, i);
|
|
if ((hypre_IndexX(index) >=
|
|
hypre_BoxIMinX(box) - hypre_IndexX(varoffset)) &&
|
|
(hypre_IndexX(index) <=
|
|
hypre_BoxIMaxX(box) + hypre_IndexX(varoffset)) &&
|
|
(hypre_IndexY(index) >=
|
|
hypre_BoxIMinY(box) - hypre_IndexY(varoffset)) &&
|
|
(hypre_IndexY(index) <=
|
|
hypre_BoxIMaxY(box) + hypre_IndexY(varoffset)) &&
|
|
(hypre_IndexZ(index) >=
|
|
hypre_BoxIMinZ(box) - hypre_IndexZ(varoffset)) &&
|
|
(hypre_IndexZ(index) <=
|
|
hypre_BoxIMaxZ(box) + hypre_IndexZ(varoffset)) )
|
|
{
|
|
hypre_StructMatrixSetValues(smatrix, index, nentries, sentries,
|
|
values, action, i, 1);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* (action > 0): add-to values
|
|
* (action = 0): set values
|
|
* (action < 0): get values
|
|
* (action =-2): get values and zero out
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixSetBoxValues( hypre_SStructPMatrix *pmatrix,
|
|
hypre_Index ilower,
|
|
hypre_Index iupper,
|
|
int var,
|
|
int nentries,
|
|
int *entries,
|
|
double *values,
|
|
int action )
|
|
{
|
|
hypre_SStructStencil *stencil = hypre_SStructPMatrixStencil(pmatrix, var);
|
|
int *smap = hypre_SStructPMatrixSMap(pmatrix, var);
|
|
int *vars = hypre_SStructStencilVars(stencil);
|
|
hypre_StructMatrix *smatrix;
|
|
hypre_Box *box;
|
|
hypre_Box *value_box;
|
|
int *sentries;
|
|
int i;
|
|
|
|
smatrix = hypre_SStructPMatrixSMatrix(pmatrix, var, vars[entries[0]]);
|
|
|
|
box = hypre_BoxCreate();
|
|
hypre_CopyIndex(ilower, hypre_BoxIMin(box));
|
|
hypre_CopyIndex(iupper, hypre_BoxIMax(box));
|
|
value_box = box;
|
|
|
|
sentries = hypre_SStructPMatrixSEntries(pmatrix);
|
|
for (i = 0; i < nentries; i++)
|
|
{
|
|
sentries[i] = smap[entries[i]];
|
|
}
|
|
|
|
/* set values inside the grid */
|
|
hypre_StructMatrixSetBoxValues(smatrix, box, value_box, nentries, sentries,
|
|
values, action, -1, 0);
|
|
|
|
/* set values outside the grid in ghost zones (for AddTo and Get) */
|
|
if (action != 0)
|
|
{
|
|
hypre_SStructPGrid *pgrid = hypre_SStructPMatrixPGrid(pmatrix);
|
|
hypre_Index varoffset;
|
|
hypre_BoxArray *grid_boxes;
|
|
hypre_BoxArray *left_boxes, *done_boxes, *temp_boxes;
|
|
hypre_Box *left_box, *done_box, *int_box;
|
|
int j;
|
|
|
|
hypre_SStructVariableGetOffset(hypre_SStructPGridVarType(pgrid, var),
|
|
hypre_SStructPGridNDim(pgrid), varoffset);
|
|
grid_boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(smatrix));
|
|
|
|
left_boxes = hypre_BoxArrayCreate(1);
|
|
done_boxes = hypre_BoxArrayCreate(2);
|
|
temp_boxes = hypre_BoxArrayCreate(0);
|
|
|
|
/* done_box always points to the first box in done_boxes */
|
|
done_box = hypre_BoxArrayBox(done_boxes, 0);
|
|
/* int_box always points to the second box in done_boxes */
|
|
int_box = hypre_BoxArrayBox(done_boxes, 1);
|
|
|
|
hypre_CopyBox(box, hypre_BoxArrayBox(left_boxes, 0));
|
|
hypre_BoxArraySetSize(left_boxes, 1);
|
|
hypre_SubtractBoxArrays(left_boxes, grid_boxes, temp_boxes);
|
|
|
|
hypre_BoxArraySetSize(done_boxes, 0);
|
|
hypre_ForBoxI(i, grid_boxes)
|
|
{
|
|
hypre_SubtractBoxArrays(left_boxes, done_boxes, temp_boxes);
|
|
hypre_BoxArraySetSize(done_boxes, 1);
|
|
hypre_CopyBox(hypre_BoxArrayBox(grid_boxes, i), done_box);
|
|
hypre_BoxIMinX(done_box) -= hypre_IndexX(varoffset);
|
|
hypre_BoxIMinY(done_box) -= hypre_IndexY(varoffset);
|
|
hypre_BoxIMinZ(done_box) -= hypre_IndexZ(varoffset);
|
|
hypre_BoxIMaxX(done_box) += hypre_IndexX(varoffset);
|
|
hypre_BoxIMaxY(done_box) += hypre_IndexY(varoffset);
|
|
hypre_BoxIMaxZ(done_box) += hypre_IndexZ(varoffset);
|
|
hypre_ForBoxI(j, left_boxes)
|
|
{
|
|
left_box = hypre_BoxArrayBox(left_boxes, j);
|
|
hypre_IntersectBoxes(left_box, done_box, int_box);
|
|
hypre_StructMatrixSetBoxValues(smatrix, int_box, value_box,
|
|
nentries, sentries,
|
|
values, action, i, 1);
|
|
}
|
|
}
|
|
|
|
hypre_BoxArrayDestroy(left_boxes);
|
|
hypre_BoxArrayDestroy(done_boxes);
|
|
hypre_BoxArrayDestroy(temp_boxes);
|
|
}
|
|
|
|
hypre_BoxDestroy(box);
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixAccumulate( hypre_SStructPMatrix *pmatrix )
|
|
{
|
|
hypre_SStructPGrid *pgrid = hypre_SStructPMatrixPGrid(pmatrix);
|
|
int nvars = hypre_SStructPMatrixNVars(pmatrix);
|
|
int ndim = hypre_SStructPGridNDim(pgrid);
|
|
HYPRE_SStructVariable *vartypes = hypre_SStructPGridVarTypes(pgrid);
|
|
|
|
hypre_StructMatrix *smatrix;
|
|
hypre_Index varoffset;
|
|
int num_ghost[6];
|
|
hypre_StructGrid *sgrid;
|
|
int vi, vj, d;
|
|
|
|
hypre_CommInfo *comm_info;
|
|
hypre_CommPkg *comm_pkg;
|
|
hypre_CommHandle *comm_handle;
|
|
|
|
/* if values already accumulated, just return */
|
|
if (hypre_SStructPMatrixAccumulated(pmatrix))
|
|
{
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
smatrix = hypre_SStructPMatrixSMatrix(pmatrix, vi, vj);
|
|
if (smatrix != NULL)
|
|
{
|
|
sgrid = hypre_StructMatrixGrid(smatrix);
|
|
/* assumes vi and vj vartypes are the same */
|
|
hypre_SStructVariableGetOffset(vartypes[vi], ndim, varoffset);
|
|
for (d = 0; d < 3; d++)
|
|
{
|
|
num_ghost[2*d] = hypre_IndexD(varoffset, d);
|
|
num_ghost[2*d+1] = hypre_IndexD(varoffset, d);
|
|
}
|
|
|
|
/* accumulate values from AddTo */
|
|
hypre_CreateCommInfoFromNumGhost(sgrid, num_ghost, &comm_info);
|
|
hypre_CommPkgCreate(comm_info,
|
|
hypre_StructMatrixDataSpace(smatrix),
|
|
hypre_StructMatrixDataSpace(smatrix),
|
|
hypre_StructMatrixNumValues(smatrix), NULL, 1,
|
|
hypre_StructMatrixComm(smatrix),
|
|
&comm_pkg);
|
|
hypre_InitializeCommunication(comm_pkg,
|
|
hypre_StructMatrixData(smatrix),
|
|
hypre_StructMatrixData(smatrix),
|
|
1, 0, &comm_handle);
|
|
hypre_FinalizeCommunication(comm_handle);
|
|
|
|
hypre_CommInfoDestroy(comm_info);
|
|
hypre_CommPkgDestroy(comm_pkg);
|
|
}
|
|
}
|
|
}
|
|
|
|
hypre_SStructPMatrixAccumulated(pmatrix) = 1;
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixAssemble( hypre_SStructPMatrix *pmatrix )
|
|
{
|
|
int nvars = hypre_SStructPMatrixNVars(pmatrix);
|
|
hypre_StructMatrix *smatrix;
|
|
int vi, vj;
|
|
|
|
hypre_SStructPMatrixAccumulate(pmatrix);
|
|
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
smatrix = hypre_SStructPMatrixSMatrix(pmatrix, vi, vj);
|
|
if (smatrix != NULL)
|
|
{
|
|
hypre_StructMatrixClearGhostValues(smatrix);
|
|
hypre_StructMatrixAssemble(smatrix);
|
|
}
|
|
}
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixSetSymmetric( hypre_SStructPMatrix *pmatrix,
|
|
int var,
|
|
int to_var,
|
|
int symmetric )
|
|
{
|
|
int **pmsymmetric = hypre_SStructPMatrixSymmetric(pmatrix);
|
|
|
|
int vstart = var;
|
|
int vsize = 1;
|
|
int tstart = to_var;
|
|
int tsize = 1;
|
|
int v, t;
|
|
|
|
if (var == -1)
|
|
{
|
|
vstart = 0;
|
|
vsize = hypre_SStructPMatrixNVars(pmatrix);
|
|
}
|
|
if (to_var == -1)
|
|
{
|
|
tstart = 0;
|
|
tsize = hypre_SStructPMatrixNVars(pmatrix);
|
|
}
|
|
|
|
for (v = vstart; v < vsize; v++)
|
|
{
|
|
for (t = tstart; t < tsize; t++)
|
|
{
|
|
pmsymmetric[v][t] = symmetric;
|
|
}
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructPMatrixPrint( const char *filename,
|
|
hypre_SStructPMatrix *pmatrix,
|
|
int all )
|
|
{
|
|
int nvars = hypre_SStructPMatrixNVars(pmatrix);
|
|
hypre_StructMatrix *smatrix;
|
|
int vi, vj;
|
|
char new_filename[255];
|
|
|
|
for (vi = 0; vi < nvars; vi++)
|
|
{
|
|
for (vj = 0; vj < nvars; vj++)
|
|
{
|
|
smatrix = hypre_SStructPMatrixSMatrix(pmatrix, vi, vj);
|
|
if (smatrix != NULL)
|
|
{
|
|
sprintf(new_filename, "%s.%02d.%02d", filename, vi, vj);
|
|
hypre_StructMatrixPrint(new_filename, smatrix, all);
|
|
}
|
|
}
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*==========================================================================
|
|
* SStructUMatrix routines
|
|
*==========================================================================*/
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructUMatrixInitialize( hypre_SStructMatrix *matrix )
|
|
{
|
|
HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix);
|
|
hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix);
|
|
hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph);
|
|
int nparts = hypre_SStructGraphNParts(graph);
|
|
hypre_SStructPGrid **pgrids = hypre_SStructGraphPGrids(graph);
|
|
hypre_SStructStencil ***stencils = hypre_SStructGraphStencils(graph);
|
|
int nUventries = hypre_SStructGraphNUVEntries(graph);
|
|
int *iUventries = hypre_SStructGraphIUVEntries(graph);
|
|
hypre_SStructUVEntry **Uventries = hypre_SStructGraphUVEntries(graph);
|
|
int **nvneighbors = hypre_SStructGridNVNeighbors(grid);
|
|
hypre_StructGrid *sgrid;
|
|
hypre_SStructStencil *stencil;
|
|
int *split;
|
|
int nvars;
|
|
int nrows, nnzs ;
|
|
int part, var, entry, i, j, k,m,b;
|
|
int *row_sizes;
|
|
int max_row_size;
|
|
|
|
int matrix_type = hypre_SStructMatrixObjectType(matrix);
|
|
|
|
hypre_Box *gridbox;
|
|
hypre_Box *loopbox;
|
|
hypre_Box *ghostbox;
|
|
hypre_BoxArray *boxes;
|
|
int *num_ghost;
|
|
|
|
|
|
HYPRE_IJMatrixSetObjectType(ijmatrix, HYPRE_PARCSR);
|
|
|
|
/* GEC1002 the ghlocalsize is used to set the number of rows */
|
|
|
|
if (matrix_type == HYPRE_PARCSR)
|
|
{
|
|
nrows = hypre_SStructGridLocalSize(grid);
|
|
}
|
|
if (matrix_type == HYPRE_SSTRUCT || matrix_type == HYPRE_STRUCT)
|
|
{
|
|
nrows = hypre_SStructGridGhlocalSize(grid) ;
|
|
}
|
|
|
|
/* set row sizes */
|
|
m = 0;
|
|
row_sizes = hypre_CTAlloc(int, nrows);
|
|
max_row_size = 0;
|
|
for (part = 0; part < nparts; part++)
|
|
{
|
|
nvars = hypre_SStructPGridNVars(pgrids[part]);
|
|
for (var = 0; var < nvars; var++)
|
|
{
|
|
sgrid = hypre_SStructPGridSGrid(pgrids[part], var);
|
|
|
|
stencil = stencils[part][var];
|
|
split = hypre_SStructMatrixSplit(matrix, part, var);
|
|
nnzs = 0;
|
|
for (entry = 0; entry < hypre_SStructStencilSize(stencil); entry++)
|
|
{
|
|
if (split[entry] == -1)
|
|
{
|
|
nnzs++;
|
|
}
|
|
}
|
|
#if 0
|
|
/* TODO: For now, assume stencil is full/complete */
|
|
if (hypre_SStructMatrixSymmetric(matrix))
|
|
{
|
|
nnzs = 2*nnzs - 1;
|
|
}
|
|
#endif
|
|
|
|
/**************/
|
|
|
|
boxes = hypre_StructGridBoxes(sgrid) ;
|
|
num_ghost = hypre_StructGridNumGhost(sgrid);
|
|
for (b = 0; b < hypre_BoxArraySize(boxes); b++)
|
|
{
|
|
gridbox = hypre_BoxArrayBox(boxes, b);
|
|
ghostbox = hypre_BoxCreate();
|
|
loopbox = hypre_BoxCreate();
|
|
hypre_CopyBox(gridbox,ghostbox);
|
|
hypre_BoxExpand(ghostbox,num_ghost);
|
|
|
|
if (matrix_type == HYPRE_SSTRUCT || matrix_type == HYPRE_STRUCT)
|
|
{
|
|
hypre_CopyBox(ghostbox,loopbox);
|
|
}
|
|
if (matrix_type == HYPRE_PARCSR)
|
|
{
|
|
hypre_CopyBox(gridbox,loopbox);
|
|
}
|
|
|
|
for (k = hypre_BoxIMinZ(loopbox); k <= hypre_BoxIMaxZ(loopbox); k++)
|
|
{
|
|
for (j = hypre_BoxIMinY(loopbox); j <= hypre_BoxIMaxY(loopbox); j++)
|
|
{
|
|
for (i = hypre_BoxIMinX(loopbox); i <= hypre_BoxIMaxX(loopbox); i++)
|
|
{
|
|
if ( ( ( i>=hypre_BoxIMinX(gridbox) )
|
|
&& ( j>=hypre_BoxIMinY(gridbox) ) )
|
|
&& ( k>=hypre_BoxIMinZ(gridbox) ) )
|
|
{
|
|
if ( ( ( i<=hypre_BoxIMaxX(gridbox) )
|
|
&& ( j<=hypre_BoxIMaxY(gridbox) ) )
|
|
&& ( k<=hypre_BoxIMaxZ(gridbox) ) )
|
|
{
|
|
row_sizes[m] = nnzs;
|
|
max_row_size = hypre_max(max_row_size, row_sizes[m]);
|
|
}
|
|
}
|
|
m++;
|
|
}
|
|
}
|
|
}
|
|
hypre_BoxDestroy(ghostbox);
|
|
hypre_BoxDestroy(loopbox);
|
|
}
|
|
|
|
|
|
if (nvneighbors[part][var])
|
|
{
|
|
max_row_size = hypre_max(max_row_size,
|
|
hypre_SStructStencilSize(stencil));
|
|
}
|
|
|
|
|
|
/*********************/
|
|
}
|
|
}
|
|
|
|
/* GEC0902 essentially for each UVentry we figure out how many extra columns
|
|
* we need to add to the rowsizes */
|
|
|
|
for (entry = 0; entry < nUventries; entry++)
|
|
{
|
|
i = iUventries[entry];
|
|
row_sizes[i] += hypre_SStructUVEntryNUEntries(Uventries[i]);
|
|
max_row_size = hypre_max(max_row_size, row_sizes[i]);
|
|
}
|
|
|
|
/* ZTODO: Update row_sizes based on neighbor off-part couplings */
|
|
HYPRE_IJMatrixSetRowSizes (ijmatrix, (const int *) row_sizes);
|
|
|
|
hypre_TFree(row_sizes);
|
|
hypre_SStructMatrixTmpColCoords(matrix) =
|
|
hypre_CTAlloc(int, max_row_size);
|
|
hypre_SStructMatrixTmpCoeffs(matrix) =
|
|
hypre_CTAlloc(double, max_row_size);
|
|
|
|
/* GEC1002 at this point the processor has the partitioning (creation of ij) */
|
|
|
|
HYPRE_IJMatrixInitialize(ijmatrix);
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* (action > 0): add-to values
|
|
* (action = 0): set values
|
|
* (action < 0): get values
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructUMatrixSetValues( hypre_SStructMatrix *matrix,
|
|
int part,
|
|
hypre_Index index,
|
|
int var,
|
|
int nentries,
|
|
int *entries,
|
|
double *values,
|
|
int action )
|
|
{
|
|
HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix);
|
|
hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix);
|
|
hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph);
|
|
hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var);
|
|
int *vars = hypre_SStructStencilVars(stencil);
|
|
hypre_Index *shape = hypre_SStructStencilShape(stencil);
|
|
int size = hypre_SStructStencilSize(stencil);
|
|
hypre_IndexRef offset;
|
|
hypre_Index to_index;
|
|
hypre_SStructUVEntry *Uventry;
|
|
hypre_BoxMapEntry *map_entry;
|
|
hypre_SStructMapInfo *entry_info;
|
|
int row_coord;
|
|
int *col_coords;
|
|
int ncoeffs;
|
|
double *coeffs;
|
|
int i, entry;
|
|
int proc, myproc;
|
|
/* GEC1002 the matrix type */
|
|
int matrix_type = hypre_SStructMatrixObjectType(matrix);
|
|
|
|
hypre_SStructGridFindMapEntry(grid, part, index, var, &map_entry);
|
|
if (map_entry == NULL)
|
|
{
|
|
hypre_error_in_arg(1);
|
|
hypre_error_in_arg(2);
|
|
hypre_error_in_arg(3);
|
|
/* RDF: This printing shouldn't be on by default */
|
|
printf("Warning: Attempt to set coeffs for point not in grid\n");
|
|
printf("hypre_SStructUMatrixSetValues call aborted for grid point\n");
|
|
printf(" part=%d, var=%d, index=(%d, %d, %d)\n", part, var,
|
|
hypre_IndexD(index,0),
|
|
hypre_IndexD(index,1),
|
|
hypre_IndexD(index,2) );
|
|
return hypre_error_flag;
|
|
}
|
|
else
|
|
{
|
|
hypre_BoxMapEntryGetInfo(map_entry, (void **) &entry_info);
|
|
}
|
|
|
|
/* Only Set values if I am the owner process; off-process AddTo and Get
|
|
* values are done by IJ */
|
|
if (!action)
|
|
{
|
|
hypre_SStructMapEntryGetProcess(map_entry, &proc);
|
|
MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc);
|
|
if (proc != myproc)
|
|
{
|
|
return hypre_error_flag;
|
|
}
|
|
}
|
|
|
|
/* GEC1002 get the rank using the function with the type=matrixtype*/
|
|
hypre_SStructMapEntryGetGlobalRank(map_entry, index, &row_coord, matrix_type);
|
|
|
|
|
|
col_coords = hypre_SStructMatrixTmpColCoords(matrix);
|
|
coeffs = hypre_SStructMatrixTmpCoeffs(matrix);
|
|
ncoeffs = 0;
|
|
for (i = 0; i < nentries; i++)
|
|
{
|
|
entry = entries[i];
|
|
|
|
if (entry < size)
|
|
{
|
|
/* stencil entries */
|
|
offset = shape[entry];
|
|
hypre_IndexX(to_index) = hypre_IndexX(index) + hypre_IndexX(offset);
|
|
hypre_IndexY(to_index) = hypre_IndexY(index) + hypre_IndexY(offset);
|
|
hypre_IndexZ(to_index) = hypre_IndexZ(index) + hypre_IndexZ(offset);
|
|
|
|
hypre_SStructGridFindMapEntry(grid, part, to_index, vars[entry],
|
|
&map_entry);
|
|
|
|
if (map_entry != NULL)
|
|
{
|
|
hypre_SStructMapEntryGetGlobalRank(map_entry, to_index,
|
|
&col_coords[ncoeffs],matrix_type);
|
|
|
|
coeffs[ncoeffs] = values[i];
|
|
ncoeffs++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* non-stencil entries */
|
|
entry -= size;
|
|
hypre_SStructGraphFindUVEntry(graph, part, index, var, &Uventry);
|
|
|
|
col_coords[ncoeffs] = hypre_SStructUVEntryRank(Uventry, entry);
|
|
coeffs[ncoeffs] = values[i];
|
|
ncoeffs++;
|
|
}
|
|
}
|
|
|
|
if (action > 0)
|
|
{
|
|
HYPRE_IJMatrixAddToValues(ijmatrix, 1, &ncoeffs, &row_coord,
|
|
(const int *) col_coords,
|
|
(const double *) coeffs);
|
|
}
|
|
else if (action > -1)
|
|
{
|
|
HYPRE_IJMatrixSetValues(ijmatrix, 1, &ncoeffs, &row_coord,
|
|
(const int *) col_coords,
|
|
(const double *) coeffs);
|
|
}
|
|
else
|
|
{
|
|
HYPRE_IJMatrixGetValues(ijmatrix, 1, &ncoeffs, &row_coord,
|
|
col_coords, values);
|
|
}
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
* Note: Entries must all be of type stencil or non-stencil, but not both.
|
|
*
|
|
* (action > 0): add-to values
|
|
* (action = 0): set values
|
|
* (action < 0): get values
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructUMatrixSetBoxValues( hypre_SStructMatrix *matrix,
|
|
int part,
|
|
hypre_Index ilower,
|
|
hypre_Index iupper,
|
|
int var,
|
|
int nentries,
|
|
int *entries,
|
|
double *values,
|
|
int action )
|
|
{
|
|
HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix);
|
|
hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix);
|
|
hypre_SStructGrid *grid = hypre_SStructGraphGrid(graph);
|
|
hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var);
|
|
int *vars = hypre_SStructStencilVars(stencil);
|
|
hypre_Index *shape = hypre_SStructStencilShape(stencil);
|
|
int size = hypre_SStructStencilSize(stencil);
|
|
hypre_IndexRef offset;
|
|
hypre_BoxMap *map;
|
|
hypre_BoxMapEntry **map_entries;
|
|
int nmap_entries;
|
|
hypre_BoxMapEntry **map_to_entries;
|
|
int nmap_to_entries;
|
|
int nrows;
|
|
int *ncols;
|
|
int *rows;
|
|
int *cols;
|
|
double *ijvalues;
|
|
hypre_Box *box;
|
|
hypre_Box *to_box;
|
|
hypre_Box *map_box;
|
|
hypre_Box *int_box;
|
|
hypre_Index index;
|
|
hypre_Index rs, cs;
|
|
int sy, sz;
|
|
int row_base, col_base, val_base;
|
|
int e, entry, ii, jj, i, j, k;
|
|
int proc, myproc;
|
|
/* GEC1002 the matrix type */
|
|
int matrix_type = hypre_SStructMatrixObjectType(matrix);
|
|
|
|
box = hypre_BoxCreate();
|
|
|
|
/*------------------------------------------
|
|
* all stencil entries
|
|
*------------------------------------------*/
|
|
|
|
if (entries[0] < size)
|
|
{
|
|
to_box = hypre_BoxCreate();
|
|
map_box = hypre_BoxCreate();
|
|
int_box = hypre_BoxCreate();
|
|
|
|
hypre_CopyIndex(ilower, hypre_BoxIMin(box));
|
|
hypre_CopyIndex(iupper, hypre_BoxIMax(box));
|
|
nrows = hypre_BoxVolume(box)*nentries;
|
|
ncols = hypre_CTAlloc(int, nrows);
|
|
for (i = 0; i < nrows; i++)
|
|
{
|
|
ncols[i] = 1;
|
|
}
|
|
rows = hypre_CTAlloc(int, nrows);
|
|
cols = hypre_CTAlloc(int, nrows);
|
|
ijvalues = hypre_CTAlloc(double, nrows);
|
|
|
|
sy = (hypre_IndexX(iupper) - hypre_IndexX(ilower) + 1);
|
|
sz = (hypre_IndexY(iupper) - hypre_IndexY(ilower) + 1) * sy;
|
|
|
|
map = hypre_SStructGridMap(grid, part, var);
|
|
hypre_BoxMapIntersect(map, ilower, iupper, &map_entries, &nmap_entries);
|
|
|
|
for (ii = 0; ii < nmap_entries; ii++)
|
|
{
|
|
/* Only Set values if I am the owner process; off-process AddTo and Get
|
|
* values are done by IJ */
|
|
if (!action)
|
|
{
|
|
hypre_SStructMapEntryGetProcess(map_entries[ii], &proc);
|
|
MPI_Comm_rank(hypre_SStructGridComm(grid), &myproc);
|
|
if (proc != myproc)
|
|
{
|
|
continue;
|
|
}
|
|
}
|
|
|
|
/* GEC1002 introducing the strides based on the type of the matrix */
|
|
hypre_SStructMapEntryGetStrides(map_entries[ii], rs, matrix_type);
|
|
|
|
hypre_CopyIndex(ilower, hypre_BoxIMin(box));
|
|
hypre_CopyIndex(iupper, hypre_BoxIMax(box));
|
|
hypre_BoxMapEntryGetExtents(map_entries[ii],
|
|
hypre_BoxIMin(map_box),
|
|
hypre_BoxIMax(map_box));
|
|
hypre_IntersectBoxes(box, map_box, int_box);
|
|
hypre_CopyBox(int_box, box);
|
|
|
|
nrows = 0;
|
|
for (e = 0; e < nentries; e++)
|
|
{
|
|
entry = entries[e];
|
|
|
|
hypre_CopyBox(box, to_box);
|
|
|
|
offset = shape[entry];
|
|
hypre_BoxIMinX(to_box) += hypre_IndexX(offset);
|
|
hypre_BoxIMinY(to_box) += hypre_IndexY(offset);
|
|
hypre_BoxIMinZ(to_box) += hypre_IndexZ(offset);
|
|
hypre_BoxIMaxX(to_box) += hypre_IndexX(offset);
|
|
hypre_BoxIMaxY(to_box) += hypre_IndexY(offset);
|
|
hypre_BoxIMaxZ(to_box) += hypre_IndexZ(offset);
|
|
|
|
map = hypre_SStructGridMap(grid, part, vars[entry]);
|
|
hypre_BoxMapIntersect(map, hypre_BoxIMin(to_box),
|
|
hypre_BoxIMax(to_box),
|
|
&map_to_entries, &nmap_to_entries );
|
|
|
|
for (jj = 0; jj < nmap_to_entries; jj++)
|
|
{
|
|
|
|
/* GEC1002 introducing the strides based on the type of the matrix */
|
|
|
|
hypre_SStructMapEntryGetStrides(map_to_entries[jj], cs, matrix_type);
|
|
|
|
hypre_BoxMapEntryGetExtents(map_to_entries[jj],
|
|
hypre_BoxIMin(map_box),
|
|
hypre_BoxIMax(map_box));
|
|
hypre_IntersectBoxes(to_box, map_box, int_box);
|
|
|
|
hypre_CopyIndex(hypre_BoxIMin(int_box), index);
|
|
|
|
/* GEC1002 introducing the rank based on the type of the matrix */
|
|
|
|
hypre_SStructMapEntryGetGlobalRank(map_to_entries[jj],
|
|
index, &col_base, matrix_type);
|
|
|
|
hypre_IndexX(index) -= hypre_IndexX(offset);
|
|
hypre_IndexY(index) -= hypre_IndexY(offset);
|
|
hypre_IndexZ(index) -= hypre_IndexZ(offset);
|
|
|
|
/* GEC1002 introducing the rank based on the type of the matrix */
|
|
|
|
hypre_SStructMapEntryGetGlobalRank(map_entries[ii],
|
|
index, &row_base, matrix_type);
|
|
|
|
hypre_IndexX(index) -= hypre_IndexX(ilower);
|
|
hypre_IndexY(index) -= hypre_IndexY(ilower);
|
|
hypre_IndexZ(index) -= hypre_IndexZ(ilower);
|
|
val_base = e + (hypre_IndexX(index) +
|
|
hypre_IndexY(index)*sy +
|
|
hypre_IndexZ(index)*sz) * nentries;
|
|
|
|
for (k = 0; k < hypre_BoxSizeZ(int_box); k++)
|
|
{
|
|
for (j = 0; j < hypre_BoxSizeY(int_box); j++)
|
|
{
|
|
for (i = 0; i < hypre_BoxSizeX(int_box); i++)
|
|
{
|
|
rows[nrows] = row_base + i*rs[0] + j*rs[1] + k*rs[2];
|
|
cols[nrows] = col_base + i*cs[0] + j*cs[1] + k*cs[2];
|
|
ijvalues[nrows] =
|
|
values[val_base + (i + j*sy + k*sz)*nentries];
|
|
nrows++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hypre_TFree(map_to_entries);
|
|
}
|
|
|
|
/*------------------------------------------
|
|
* set IJ values one stencil entry at a time
|
|
*------------------------------------------*/
|
|
|
|
if (action > 0)
|
|
{
|
|
HYPRE_IJMatrixAddToValues(ijmatrix, nrows, ncols,
|
|
(const int *) rows,
|
|
(const int *) cols,
|
|
(const double *) ijvalues);
|
|
}
|
|
else if (action > -1)
|
|
{
|
|
HYPRE_IJMatrixSetValues(ijmatrix, nrows, ncols,
|
|
(const int *) rows,
|
|
(const int *) cols,
|
|
(const double *) ijvalues);
|
|
}
|
|
else
|
|
{
|
|
HYPRE_IJMatrixGetValues(ijmatrix, nrows, ncols, rows, cols, values);
|
|
}
|
|
}
|
|
|
|
hypre_TFree(map_entries);
|
|
|
|
hypre_TFree(ncols);
|
|
hypre_TFree(rows);
|
|
hypre_TFree(cols);
|
|
hypre_TFree(ijvalues);
|
|
|
|
hypre_BoxDestroy(to_box);
|
|
hypre_BoxDestroy(map_box);
|
|
hypre_BoxDestroy(int_box);
|
|
}
|
|
|
|
/*------------------------------------------
|
|
* non-stencil entries
|
|
*------------------------------------------*/
|
|
|
|
else
|
|
{
|
|
hypre_CopyIndex(ilower, hypre_BoxIMin(box));
|
|
hypre_CopyIndex(iupper, hypre_BoxIMax(box));
|
|
|
|
for (k = hypre_BoxIMinZ(box); k <= hypre_BoxIMaxZ(box); k++)
|
|
{
|
|
for (j = hypre_BoxIMinY(box); j <= hypre_BoxIMaxY(box); j++)
|
|
{
|
|
for (i = hypre_BoxIMinX(box); i <= hypre_BoxIMaxX(box); i++)
|
|
{
|
|
hypre_SetIndex(index, i, j, k);
|
|
hypre_SStructUMatrixSetValues(matrix, part, index, var,
|
|
nentries, entries, values, action);
|
|
values += nentries;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hypre_BoxDestroy(box);
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructUMatrixAssemble( hypre_SStructMatrix *matrix )
|
|
{
|
|
HYPRE_IJMatrix ijmatrix = hypre_SStructMatrixIJMatrix(matrix);
|
|
|
|
HYPRE_IJMatrixAssemble(ijmatrix);
|
|
HYPRE_IJMatrixGetObject(ijmatrix,
|
|
(void **) &hypre_SStructMatrixParCSRMatrix(matrix));
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*==========================================================================
|
|
* SStructMatrix routines
|
|
*==========================================================================*/
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructMatrixRef( hypre_SStructMatrix *matrix,
|
|
hypre_SStructMatrix **matrix_ref )
|
|
{
|
|
hypre_SStructMatrixRefCount(matrix) ++;
|
|
*matrix_ref = matrix;
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|
|
/*--------------------------------------------------------------------------
|
|
*--------------------------------------------------------------------------*/
|
|
|
|
int
|
|
hypre_SStructMatrixSplitEntries( hypre_SStructMatrix *matrix,
|
|
int part,
|
|
int var,
|
|
int nentries,
|
|
int *entries,
|
|
int *nSentries_ptr,
|
|
int **Sentries_ptr,
|
|
int *nUentries_ptr,
|
|
int **Uentries_ptr )
|
|
{
|
|
hypre_SStructGraph *graph = hypre_SStructMatrixGraph(matrix);
|
|
int *split = hypre_SStructMatrixSplit(matrix, part, var);
|
|
hypre_SStructStencil *stencil = hypre_SStructGraphStencil(graph, part, var);
|
|
int entry;
|
|
int i;
|
|
|
|
int nSentries = 0;
|
|
int *Sentries = hypre_SStructMatrixSEntries(matrix);
|
|
int nUentries = 0;
|
|
int *Uentries = hypre_SStructMatrixUEntries(matrix);
|
|
|
|
for (i = 0; i < nentries; i++)
|
|
{
|
|
entry = entries[i];
|
|
if (entry < hypre_SStructStencilSize(stencil))
|
|
{
|
|
/* stencil entries */
|
|
if (split[entry] > -1)
|
|
{
|
|
Sentries[nSentries] = split[entry];
|
|
nSentries++;
|
|
}
|
|
else
|
|
{
|
|
Uentries[nUentries] = entry;
|
|
nUentries++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* non-stencil entries */
|
|
Uentries[nUentries] = entry;
|
|
nUentries++;
|
|
}
|
|
}
|
|
|
|
*nSentries_ptr = nSentries;
|
|
*Sentries_ptr = Sentries;
|
|
*nUentries_ptr = nUentries;
|
|
*Uentries_ptr = Uentries;
|
|
|
|
return hypre_error_flag;
|
|
}
|
|
|