hypre/struct_ls/sparse_msg_interp.c
2008-07-18 01:34:48 +00:00

316 lines
11 KiB
C

/*BHEADER**********************************************************************
* Copyright (c) 2008, Lawrence Livermore National Security, LLC.
* Produced at the Lawrence Livermore National Laboratory.
* This file is part of HYPRE. See file COPYRIGHT for details.
*
* HYPRE is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License (as published by the Free
* Software Foundation) version 2.1 dated February 1999.
*
* $Revision$
***********************************************************************EHEADER*/
/******************************************************************************
*
*
*****************************************************************************/
#include "headers.h"
/*--------------------------------------------------------------------------
* hypre_SparseMSGInterpData data structure
*--------------------------------------------------------------------------*/
typedef struct
{
hypre_StructMatrix *P;
hypre_ComputePkg *compute_pkg;
hypre_Index cindex;
hypre_Index findex;
hypre_Index stride;
hypre_Index strideP;
int time_index;
} hypre_SparseMSGInterpData;
/*--------------------------------------------------------------------------
* hypre_SparseMSGInterpCreate
*--------------------------------------------------------------------------*/
void *
hypre_SparseMSGInterpCreate( )
{
hypre_SparseMSGInterpData *interp_data;
interp_data = hypre_CTAlloc(hypre_SparseMSGInterpData, 1);
(interp_data -> time_index) = hypre_InitializeTiming("SparseMSGInterp");
return (void *) interp_data;
}
/*--------------------------------------------------------------------------
* hypre_SparseMSGInterpSetup
*--------------------------------------------------------------------------*/
int
hypre_SparseMSGInterpSetup( void *interp_vdata,
hypre_StructMatrix *P,
hypre_StructVector *xc,
hypre_StructVector *e,
hypre_Index cindex,
hypre_Index findex,
hypre_Index stride,
hypre_Index strideP )
{
hypre_SparseMSGInterpData *interp_data = interp_vdata;
hypre_StructGrid *grid;
hypre_StructStencil *stencil;
hypre_ComputeInfo *compute_info;
hypre_ComputePkg *compute_pkg;
int ierr = 0;
/*----------------------------------------------------------
* Set up the compute package
*----------------------------------------------------------*/
grid = hypre_StructVectorGrid(e);
stencil = hypre_StructMatrixStencil(P);
hypre_CreateComputeInfo(grid, stencil, &compute_info);
hypre_ComputeInfoProjectSend(compute_info, cindex, stride);
hypre_ComputeInfoProjectRecv(compute_info, cindex, stride);
hypre_ComputeInfoProjectComp(compute_info, findex, stride);
hypre_ComputePkgCreate(compute_info, hypre_StructVectorDataSpace(e), 1,
grid, &compute_pkg);
/*----------------------------------------------------------
* Set up the interp data structure
*----------------------------------------------------------*/
(interp_data -> P) = hypre_StructMatrixRef(P);
(interp_data -> compute_pkg) = compute_pkg;
hypre_CopyIndex(cindex, (interp_data -> cindex));
hypre_CopyIndex(findex, (interp_data -> findex));
hypre_CopyIndex(stride, (interp_data -> stride));
hypre_CopyIndex(strideP, (interp_data -> strideP));
return ierr;
}
/*--------------------------------------------------------------------------
* hypre_SparseMSGInterp:
*--------------------------------------------------------------------------*/
int
hypre_SparseMSGInterp( void *interp_vdata,
hypre_StructMatrix *P,
hypre_StructVector *xc,
hypre_StructVector *e )
{
int ierr = 0;
hypre_SparseMSGInterpData *interp_data = interp_vdata;
hypre_ComputePkg *compute_pkg;
hypre_IndexRef cindex;
hypre_IndexRef findex;
hypre_IndexRef stride;
hypre_IndexRef strideP;
hypre_StructGrid *fgrid;
int *fgrid_ids;
hypre_StructGrid *cgrid;
hypre_BoxArray *cgrid_boxes;
int *cgrid_ids;
hypre_CommHandle *comm_handle;
hypre_BoxArrayArray *compute_box_aa;
hypre_BoxArray *compute_box_a;
hypre_Box *compute_box;
hypre_Box *P_dbox;
hypre_Box *xc_dbox;
hypre_Box *e_dbox;
int Pi;
int xci;
int ei;
double *Pp0, *Pp1;
double *xcp;
double *ep, *ep0, *ep1;
hypre_Index loop_size;
hypre_Index start;
hypre_Index startc;
hypre_Index startP;
hypre_Index stridec;
hypre_StructStencil *stencil;
hypre_Index *stencil_shape;
int compute_i, fi, ci, j;
int loopi, loopj, loopk;
/*-----------------------------------------------------------------------
* Initialize some things
*-----------------------------------------------------------------------*/
hypre_BeginTiming(interp_data -> time_index);
compute_pkg = (interp_data -> compute_pkg);
cindex = (interp_data -> cindex);
findex = (interp_data -> findex);
stride = (interp_data -> stride);
strideP = (interp_data -> strideP);
stencil = hypre_StructMatrixStencil(P);
stencil_shape = hypre_StructStencilShape(stencil);
hypre_SetIndex(stridec, 1, 1, 1);
/*-----------------------------------------------------------------------
* Compute e at coarse points (injection)
*-----------------------------------------------------------------------*/
fgrid = hypre_StructVectorGrid(e);
fgrid_ids = hypre_StructGridIDs(fgrid);
cgrid = hypre_StructVectorGrid(xc);
cgrid_boxes = hypre_StructGridBoxes(cgrid);
cgrid_ids = hypre_StructGridIDs(cgrid);
fi = 0;
hypre_ForBoxI(ci, cgrid_boxes)
{
while (fgrid_ids[fi] != cgrid_ids[ci])
{
fi++;
}
compute_box = hypre_BoxArrayBox(cgrid_boxes, ci);
hypre_CopyIndex(hypre_BoxIMin(compute_box), startc);
hypre_StructMapCoarseToFine(startc, cindex, stride, start);
e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi);
xc_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(xc), ci);
ep = hypre_StructVectorBoxData(e, fi);
xcp = hypre_StructVectorBoxData(xc, ci);
hypre_BoxGetSize(compute_box, loop_size);
hypre_BoxLoop2Begin(loop_size,
e_dbox, start, stride, ei,
xc_dbox, startc, stridec, xci);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,ei,xci
#include "hypre_box_smp_forloop.h"
hypre_BoxLoop2For(loopi, loopj, loopk, ei, xci)
{
ep[ei] = xcp[xci];
}
hypre_BoxLoop2End(ei, xci);
}
/*-----------------------------------------------------------------------
* Compute e at fine points
*-----------------------------------------------------------------------*/
for (compute_i = 0; compute_i < 2; compute_i++)
{
switch(compute_i)
{
case 0:
{
ep = hypre_StructVectorData(e);
hypre_InitializeIndtComputations(compute_pkg, ep, &comm_handle);
compute_box_aa = hypre_ComputePkgIndtBoxes(compute_pkg);
}
break;
case 1:
{
hypre_FinalizeIndtComputations(comm_handle);
compute_box_aa = hypre_ComputePkgDeptBoxes(compute_pkg);
}
break;
}
hypre_ForBoxArrayI(fi, compute_box_aa)
{
compute_box_a = hypre_BoxArrayArrayBoxArray(compute_box_aa, fi);
P_dbox = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(P), fi);
e_dbox = hypre_BoxArrayBox(hypre_StructVectorDataSpace(e), fi);
Pp0 = hypre_StructMatrixBoxData(P, fi, 0);
Pp1 = hypre_StructMatrixBoxData(P, fi, 1);
ep = hypre_StructVectorBoxData(e, fi);
ep0 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[0]);
ep1 = ep + hypre_BoxOffsetDistance(e_dbox, stencil_shape[1]);
hypre_ForBoxI(j, compute_box_a)
{
compute_box = hypre_BoxArrayBox(compute_box_a, j);
hypre_CopyIndex(hypre_BoxIMin(compute_box), start);
hypre_StructMapFineToCoarse(start, findex, stride, startc);
hypre_StructMapCoarseToFine(startc, cindex, strideP, startP);
hypre_BoxGetStrideSize(compute_box, stride, loop_size);
hypre_BoxLoop2Begin(loop_size,
P_dbox, startP, strideP, Pi,
e_dbox, start, stride, ei);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,Pi,ei
#include "hypre_box_smp_forloop.h"
hypre_BoxLoop2For(loopi, loopj, loopk, Pi, ei)
{
ep[ei] = (Pp0[Pi] * ep0[ei] +
Pp1[Pi] * ep1[ei]);
}
hypre_BoxLoop2End(Pi, ei);
}
}
}
/*-----------------------------------------------------------------------
* Return
*-----------------------------------------------------------------------*/
hypre_IncFLOPCount(3*hypre_StructVectorGlobalSize(xc));
hypre_EndTiming(interp_data -> time_index);
return ierr;
}
/*--------------------------------------------------------------------------
* hypre_SparseMSGInterpDestroy
*--------------------------------------------------------------------------*/
int
hypre_SparseMSGInterpDestroy( void *interp_vdata )
{
int ierr = 0;
hypre_SparseMSGInterpData *interp_data = interp_vdata;
if (interp_data)
{
hypre_StructMatrixDestroy(interp_data -> P);
hypre_ComputePkgDestroy(interp_data -> compute_pkg);
hypre_FinalizeTiming(interp_data -> time_index);
hypre_TFree(interp_data);
}
return ierr;
}