blob: 44b429af50df91f909a8b7e0d2d91aba300cfbce [file] [log] [blame]
/*BHEADER**********************************************************************
* (c) 1998 The Regents of the University of California
*
* See the file COPYRIGHT_and_DISCLAIMER for a complete copyright
* notice, contact person, and disclaimer.
*
* $Revision$
*********************************************************************EHEADER*/
#include "headers.h"
/*==========================================================================*/
/** Creates a new PCG solver object.
{\bf Input files:}
headers.h
@return Error code.
@param comm [IN]
MPI communicator
@param solver [OUT]
solver structure
@see HYPRE_StructPCGDestroy */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGCreate( MPI_Comm comm, HYPRE_StructSolver *solver )
{
/* The function names with a PCG in them are in
struct_ls/pcg_struct.c . These functions do rather little -
e.g., cast to the correct type - before calling something else.
These names should be called, e.g., hypre_struct_Free, to reduce the
chance of name conflicts. */
hypre_PCGFunctions * pcg_functions =
hypre_PCGFunctionsCreate(
hypre_CAlloc, hypre_StructKrylovFree, hypre_StructKrylovCreateVector,
hypre_StructKrylovDestroyVector, hypre_StructKrylovMatvecCreate,
hypre_StructKrylovMatvec, hypre_StructKrylovMatvecDestroy,
hypre_StructKrylovInnerProd, hypre_StructKrylovCopyVector,
hypre_StructKrylovClearVector,
hypre_StructKrylovScaleVector, hypre_StructKrylovAxpy,
hypre_StructKrylovIdentitySetup, hypre_StructKrylovIdentity );
*solver = ( (HYPRE_StructSolver) hypre_PCGCreate( pcg_functions ) );
return 0;
}
/*==========================================================================*/
/*==========================================================================*/
/** Destroys a PCG solver object.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@see HYPRE_StructPCGCreate */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGDestroy( HYPRE_StructSolver solver )
{
return( hypre_PCGDestroy( (void *) solver ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** Precomputes tasks necessary for doing the solve. This routine
ensures that the setup for the preconditioner is also called.
NOTE: This is supposed to be an optional call, but currently is required.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param A [IN]
coefficient matrix
@param b [IN]
right-hand-side vector
@param x [IN]
unknown vector
@see HYPRE_StructPCGSolve */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSetup( HYPRE_StructSolver solver,
HYPRE_StructMatrix A,
HYPRE_StructVector b,
HYPRE_StructVector x )
{
return( HYPRE_PCGSetup( (HYPRE_Solver) solver,
(HYPRE_Matrix) A,
(HYPRE_Vector) b,
(HYPRE_Vector) x ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** Performs the PCG linear solve.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param A [IN]
coefficient matrix
@param b [IN]
right-hand-side vector
@param x [IN]
unknown vector
@see HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSolve( HYPRE_StructSolver solver,
HYPRE_StructMatrix A,
HYPRE_StructVector b,
HYPRE_StructVector x )
{
return( HYPRE_PCGSolve( (HYPRE_Solver) solver,
(HYPRE_Matrix) A,
(HYPRE_Vector) b,
(HYPRE_Vector) x ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Set the stopping tolerance.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param tol [IN]
PCG solver tolerance
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSetTol( HYPRE_StructSolver solver,
double tol )
{
return( HYPRE_PCGSetTol( (HYPRE_Solver) solver, tol ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Set the maximum number of iterations.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param max_iter [IN]
PCG solver maximum number of iterations
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSetMaxIter( HYPRE_StructSolver solver,
int max_iter )
{
return( HYPRE_PCGSetMaxIter( (HYPRE_Solver) solver, max_iter ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Set the type of norm to use in the stopping criteria.
If parameter two\_norm is set to 0, the preconditioner norm is used.
If set to 1, the two-norm is used.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param two_norm [IN]
boolean indicating whether or not to use the two-norm
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSetTwoNorm( HYPRE_StructSolver solver,
int two_norm )
{
return( HYPRE_PCGSetTwoNorm( (HYPRE_Solver) solver, two_norm ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Set whether or not to do an additional relative change
stopping test. If parameter rel\_change is set to 0, no additional
stopping test is done. If set to 1, the additional test is done.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param rel_change [IN]
boolean indicating whether or not to do relative change test
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSetRelChange( HYPRE_StructSolver solver,
int rel_change )
{
return( HYPRE_PCGSetRelChange( (HYPRE_Solver) solver, rel_change ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Sets the precondioner to use in PCG. The Default is no
preconditioner, i.e. the solver is just conjugate gradients (CG).
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param precond [IN]
pointer to the preconditioner solve function
@param precond_setup [IN]
pointer to the preconditioner setup function
@param precond_solver [IN/OUT]
preconditioner solver structure
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup*/
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSetPrecond( HYPRE_StructSolver solver,
HYPRE_PtrToStructSolverFcn precond,
HYPRE_PtrToStructSolverFcn precond_setup,
HYPRE_StructSolver precond_solver )
{
return( HYPRE_PCGSetPrecond( (HYPRE_Solver) solver,
(HYPRE_PtrToSolverFcn) precond,
(HYPRE_PtrToSolverFcn) precond_setup,
(HYPRE_Solver) precond_solver ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Set the type of logging to do. Currently, if parameter
logging is set to 0, no logging is done. If set to 1, the norms and
relative norms for each iteration are saved.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param logging [IN]
integer indicating what type of logging to do
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGSetLogging( HYPRE_StructSolver solver,
int logging )
{
return( HYPRE_PCGSetLogging( (HYPRE_Solver) solver, logging ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Gets the number of iterations done in the solve.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN]
solver structure
@param num_iterations [OUT]
number of iterations
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGGetNumIterations( HYPRE_StructSolver solver,
int *num_iterations )
{
return( HYPRE_PCGGetNumIterations( (HYPRE_Solver) solver, num_iterations ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** (Optional) Gets the final relative residual norm for the solve.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN]
solver structure
@param norm [OUT]
final relative residual norm
@see HYPRE_StructPCGSolve, HYPRE_StructPCGSetup */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructPCGGetFinalRelativeResidualNorm( HYPRE_StructSolver solver,
double *norm )
{
return( HYPRE_PCGGetFinalRelativeResidualNorm( (HYPRE_Solver) solver, norm ) );
}
/*==========================================================================*/
/*==========================================================================*/
/** Setup routine for diagonally scaling a vector.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param A [IN]
coefficient matrix
@param b [IN]
right-hand-side vector
@param x [IN]
unknown vector
@see HYPRE_StructDiagScale */
/*--------------------------------------------------------------------------*/
int
HYPRE_StructDiagScaleSetup( HYPRE_StructSolver solver,
HYPRE_StructMatrix A,
HYPRE_StructVector y,
HYPRE_StructVector x )
{
return 0;
}
/*==========================================================================*/
/*==========================================================================*/
/** Diagonally scale a vector.
{\bf Input files:}
headers.h
@return Error code.
@param solver [IN/OUT]
solver structure
@param A [IN]
coefficient matrix
@param b [IN]
right-hand-side vector
@param x [IN]
unknown vector
@see HYPRE_StructDiagScaleSetup */
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------
* HYPRE_StructDiagScale
*--------------------------------------------------------------------------*/
int
HYPRE_StructDiagScale( HYPRE_StructSolver solver,
HYPRE_StructMatrix HA,
HYPRE_StructVector Hy,
HYPRE_StructVector Hx )
{
hypre_StructMatrix *A = (hypre_StructMatrix *) HA;
hypre_StructVector *y = (hypre_StructVector *) Hy;
hypre_StructVector *x = (hypre_StructVector *) Hx;
hypre_BoxArray *boxes;
hypre_Box *box;
hypre_Box *A_data_box;
hypre_Box *y_data_box;
hypre_Box *x_data_box;
double *Ap;
double *yp;
double *xp;
int Ai;
int yi;
int xi;
hypre_Index index;
hypre_IndexRef start;
hypre_Index stride;
hypre_Index loop_size;
int i;
int loopi, loopj, loopk;
int ierr = 0;
/* x = D^{-1} y */
hypre_SetIndex(stride, 1, 1, 1);
boxes = hypre_StructGridBoxes(hypre_StructMatrixGrid(A));
hypre_ForBoxI(i, boxes)
{
box = hypre_BoxArrayBox(boxes, i);
A_data_box = hypre_BoxArrayBox(hypre_StructMatrixDataSpace(A), i);
x_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(x), i);
y_data_box = hypre_BoxArrayBox(hypre_StructVectorDataSpace(y), i);
hypre_SetIndex(index, 0, 0, 0);
Ap = hypre_StructMatrixExtractPointerByIndex(A, i, index);
xp = hypre_StructVectorBoxData(x, i);
yp = hypre_StructVectorBoxData(y, i);
start = hypre_BoxIMin(box);
hypre_BoxGetSize(box, loop_size);
hypre_BoxLoop3Begin(loop_size,
A_data_box, start, stride, Ai,
x_data_box, start, stride, xi,
y_data_box, start, stride, yi);
#define HYPRE_BOX_SMP_PRIVATE loopk,loopi,loopj,yi,xi,Ai
#include "hypre_box_smp_forloop.h"
hypre_BoxLoop3For(loopi, loopj, loopk, Ai, xi, yi)
{
xp[xi] = yp[yi] / Ap[Ai];
}
hypre_BoxLoop3End(Ai, xi, yi);
}
return ierr;
}