hypre/struct_ls/pfmg_relax.c

295 lines
9.0 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 "_hypre_struct_ls.h"
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
typedef struct
{
void *relax_data;
void *rb_relax_data;
HYPRE_Int relax_type;
double jacobi_weight;
} hypre_PFMGRelaxData;
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
void *
hypre_PFMGRelaxCreate( MPI_Comm comm )
{
hypre_PFMGRelaxData *pfmg_relax_data;
pfmg_relax_data = hypre_CTAlloc(hypre_PFMGRelaxData, 1);
(pfmg_relax_data -> relax_data) = hypre_PointRelaxCreate(comm);
(pfmg_relax_data -> rb_relax_data) = hypre_RedBlackGSCreate(comm);
(pfmg_relax_data -> relax_type) = 0; /* Weighted Jacobi */
(pfmg_relax_data -> jacobi_weight) = 0.0;
return (void *) pfmg_relax_data;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxDestroy( void *pfmg_relax_vdata )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
if (pfmg_relax_data)
{
hypre_PointRelaxDestroy(pfmg_relax_data -> relax_data);
hypre_RedBlackGSDestroy(pfmg_relax_data -> rb_relax_data);
hypre_TFree(pfmg_relax_data);
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelax( void *pfmg_relax_vdata,
hypre_StructMatrix *A,
hypre_StructVector *b,
hypre_StructVector *x )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
HYPRE_Int relax_type = (pfmg_relax_data -> relax_type);
HYPRE_Int constant_coefficient= hypre_StructMatrixConstantCoefficient(A);
switch(relax_type)
{
case 0:
case 1:
hypre_PointRelax((pfmg_relax_data -> relax_data), A, b, x);
break;
case 2:
case 3:
if (constant_coefficient)
{
hypre_RedBlackConstantCoefGS((pfmg_relax_data -> rb_relax_data),
A, b, x);
}
else
{
hypre_RedBlackGS((pfmg_relax_data -> rb_relax_data), A, b, x);
}
break;
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetup( void *pfmg_relax_vdata,
hypre_StructMatrix *A,
hypre_StructVector *b,
hypre_StructVector *x )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
HYPRE_Int relax_type = (pfmg_relax_data -> relax_type);
double jacobi_weight = (pfmg_relax_data -> jacobi_weight);
switch(relax_type)
{
case 0:
case 1:
hypre_PointRelaxSetup((pfmg_relax_data -> relax_data), A, b, x);
break;
case 2:
case 3:
hypre_RedBlackGSSetup((pfmg_relax_data -> rb_relax_data), A, b, x);
break;
}
if (relax_type==1)
{
hypre_PointRelaxSetWeight(pfmg_relax_data -> relax_data, jacobi_weight);
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetType( void *pfmg_relax_vdata,
HYPRE_Int relax_type )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
void *relax_data = (pfmg_relax_data -> relax_data);
(pfmg_relax_data -> relax_type) = relax_type;
switch(relax_type)
{
case 0: /* Jacobi */
{
hypre_Index stride;
hypre_Index indices[1];
hypre_PointRelaxSetWeight(relax_data, 1.0);
hypre_PointRelaxSetNumPointsets(relax_data, 1);
hypre_SetIndex(stride, 1, 1, 1);
hypre_SetIndex(indices[0], 0, 0, 0);
hypre_PointRelaxSetPointset(relax_data, 0, 1, stride, indices);
}
break;
case 2: /* Red-Black Gauss-Seidel */
case 3: /* Red-Black Gauss-Seidel (non-symmetric) */
break;
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetJacobiWeight(void *pfmg_relax_vdata,
double weight)
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
(pfmg_relax_data -> jacobi_weight) = weight;
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetPreRelax( void *pfmg_relax_vdata )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
HYPRE_Int relax_type = (pfmg_relax_data -> relax_type);
switch(relax_type)
{
case 1: /* Weighted Jacobi */
case 0: /* Jacobi */
break;
case 2: /* Red-Black Gauss-Seidel */
hypre_RedBlackGSSetStartRed((pfmg_relax_data -> rb_relax_data));
break;
case 3: /* Red-Black Gauss-Seidel (non-symmetric) */
hypre_RedBlackGSSetStartRed((pfmg_relax_data -> rb_relax_data));
break;
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetPostRelax( void *pfmg_relax_vdata )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
HYPRE_Int relax_type = (pfmg_relax_data -> relax_type);
switch(relax_type)
{
case 1: /* Weighted Jacobi */
case 0: /* Jacobi */
break;
case 2: /* Red-Black Gauss-Seidel */
hypre_RedBlackGSSetStartBlack((pfmg_relax_data -> rb_relax_data));
break;
case 3: /* Red-Black Gauss-Seidel (non-symmetric) */
hypre_RedBlackGSSetStartRed((pfmg_relax_data -> rb_relax_data));
break;
}
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetTol( void *pfmg_relax_vdata,
double tol )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
hypre_PointRelaxSetTol((pfmg_relax_data -> relax_data), tol);
hypre_RedBlackGSSetTol((pfmg_relax_data -> rb_relax_data), tol);
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetMaxIter( void *pfmg_relax_vdata,
HYPRE_Int max_iter )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
hypre_PointRelaxSetMaxIter((pfmg_relax_data -> relax_data), max_iter);
hypre_RedBlackGSSetMaxIter((pfmg_relax_data -> rb_relax_data), max_iter);
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetZeroGuess( void *pfmg_relax_vdata,
HYPRE_Int zero_guess )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
hypre_PointRelaxSetZeroGuess((pfmg_relax_data -> relax_data), zero_guess);
hypre_RedBlackGSSetZeroGuess((pfmg_relax_data -> rb_relax_data), zero_guess);
return hypre_error_flag;
}
/*--------------------------------------------------------------------------
*--------------------------------------------------------------------------*/
HYPRE_Int
hypre_PFMGRelaxSetTempVec( void *pfmg_relax_vdata,
hypre_StructVector *t )
{
hypre_PFMGRelaxData *pfmg_relax_data = pfmg_relax_vdata;
hypre_PointRelaxSetTempVec((pfmg_relax_data -> relax_data), t);
return hypre_error_flag;
}