hypre/parcsr_ls/par_schwarz.c
2006-09-22 22:06:21 +00:00

375 lines
11 KiB
C

/*BHEADER**********************************************************************
* Copyright (c) 2006 The Regents of the University of California.
* 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*/
/******************************************************************************
*
* Schwarz functions
*
*****************************************************************************/
#include "headers.h"
#include "schwarz.h"
/*--------------------------------------------------------------------------
* hypre_SchwarzCreate
*--------------------------------------------------------------------------*/
void *
hypre_SchwarzCreate()
{
hypre_SchwarzData *schwarz_data;
int variant;
int domain_type;
int overlap;
int num_functions;
double relax_weight;
/*-----------------------------------------------------------------------
* Setup default values for parameters
*-----------------------------------------------------------------------*/
/* setup params */
variant = 0; /* multiplicative Schwarz */
overlap = 1; /* minimal overlap */
domain_type = 2; /* domains generated by agglomeration */
num_functions = 1;
relax_weight = 1.0;
schwarz_data = hypre_CTAlloc(hypre_SchwarzData,1);
hypre_SchwarzSetVariant(schwarz_data, variant);
hypre_SchwarzSetDomainType(schwarz_data, domain_type);
hypre_SchwarzSetOverlap(schwarz_data, overlap);
hypre_SchwarzSetNumFunctions(schwarz_data, num_functions);
hypre_SchwarzSetRelaxWeight(schwarz_data, relax_weight);
hypre_SchwarzDataDomainStructure(schwarz_data) = NULL;
hypre_SchwarzDataABoundary(schwarz_data) = NULL;
hypre_SchwarzDataScale(schwarz_data) = NULL;
hypre_SchwarzDataVtemp(schwarz_data) = NULL;
hypre_SchwarzDataDofFunc(schwarz_data) = NULL;
return (void *) schwarz_data;
}
/*--------------------------------------------------------------------------
* hypre_SchwarzDestroy
*--------------------------------------------------------------------------*/
int
hypre_SchwarzDestroy( void *data )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
if (hypre_SchwarzDataScale(schwarz_data))
hypre_TFree (hypre_SchwarzDataScale(schwarz_data));
if (hypre_SchwarzDataDofFunc(schwarz_data))
hypre_TFree (hypre_SchwarzDataDofFunc(schwarz_data));
hypre_CSRMatrixDestroy(hypre_SchwarzDataDomainStructure(schwarz_data));
if (hypre_SchwarzDataVariant(schwarz_data) == 3);
hypre_CSRMatrixDestroy(hypre_SchwarzDataABoundary(schwarz_data));
hypre_ParVectorDestroy(hypre_SchwarzDataVtemp(schwarz_data));
hypre_TFree(schwarz_data);
return (ierr);
}
int
hypre_SchwarzSetup(void *schwarz_vdata,
hypre_ParCSRMatrix *A,
hypre_ParVector *f,
hypre_ParVector *u )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = schwarz_vdata;
int *dof_func;
double *scale;
hypre_CSRMatrix *domain_structure;
hypre_CSRMatrix *A_boundary;
hypre_ParVector *Vtemp;
int variant = hypre_SchwarzDataVariant(schwarz_data);
int domain_type = hypre_SchwarzDataDomainType(schwarz_data);
int overlap = hypre_SchwarzDataOverlap(schwarz_data);
int num_functions = hypre_SchwarzDataNumFunctions(schwarz_data);
double relax_weight = hypre_SchwarzDataRelaxWeight(schwarz_data);
dof_func = hypre_SchwarzDataDofFunc(schwarz_data);
Vtemp = hypre_ParVectorCreate(hypre_ParCSRMatrixComm(A),
hypre_ParCSRMatrixGlobalNumRows(A),
hypre_ParCSRMatrixRowStarts(A));
hypre_ParVectorSetPartitioningOwner(Vtemp,0);
hypre_ParVectorInitialize(Vtemp);
hypre_SchwarzDataVtemp(schwarz_data) = Vtemp;
if (variant > 1)
{
hypre_ParAMGCreateDomainDof(A,
domain_type, overlap,
num_functions, dof_func,
&domain_structure);
if (variant == 2)
{
hypre_ParGenerateScale(A, domain_structure, relax_weight,
&scale);
hypre_SchwarzDataScale(schwarz_data) = scale;
}
else
{
hypre_ParGenerateHybridScale(A, domain_structure, &A_boundary, &scale);
hypre_SchwarzDataScale(schwarz_data) = scale;
if (hypre_CSRMatrixNumCols(hypre_ParCSRMatrixOffd(A)))
hypre_SchwarzDataABoundary(schwarz_data) = A_boundary;
else
hypre_SchwarzDataABoundary(schwarz_data) = NULL;
}
}
else
{
hypre_AMGCreateDomainDof (hypre_ParCSRMatrixDiag(A),
domain_type, overlap,
num_functions, dof_func,
&domain_structure);
if (variant == 1)
{
hypre_GenerateScale(domain_structure,
hypre_CSRMatrixNumRows(hypre_ParCSRMatrixDiag(A)),
relax_weight, &scale);
hypre_SchwarzDataScale(schwarz_data) = scale;
}
}
hypre_SchwarzDataDomainStructure(schwarz_data) = domain_structure;
return ierr;
}
/*--------------------------------------------------------------------
* hypre_SchwarzSolve
*--------------------------------------------------------------------*/
int
hypre_SchwarzSolve(void *schwarz_vdata,
hypre_ParCSRMatrix *A,
hypre_ParVector *f,
hypre_ParVector *u )
{
hypre_SchwarzData *schwarz_data = schwarz_vdata;
int ierr = 0;
hypre_CSRMatrix *domain_structure =
hypre_SchwarzDataDomainStructure(schwarz_data);
hypre_CSRMatrix *A_boundary = hypre_SchwarzDataABoundary(schwarz_data);
double *scale = hypre_SchwarzDataScale(schwarz_data);
hypre_ParVector *Vtemp = hypre_SchwarzDataVtemp(schwarz_data);
int variant = hypre_SchwarzDataVariant(schwarz_data);
double relax_wt = hypre_SchwarzDataRelaxWeight(schwarz_data);
if (variant == 2)
{
ierr = hypre_ParAdSchwarzSolve(A, f, domain_structure, scale, u, Vtemp);
}
else if (variant == 3)
{
ierr = hypre_ParMPSchwarzSolve(A, A_boundary, f, domain_structure, u,
relax_wt, scale, Vtemp);
}
else if (variant == 1)
{
ierr = hypre_AdSchwarzSolve(A, f, domain_structure, scale, u, Vtemp);
}
else if (variant == 4)
{
ierr = hypre_MPSchwarzFWSolve(A, hypre_ParVectorLocalVector(f),
domain_structure, u, relax_wt,
hypre_ParVectorLocalVector(Vtemp));
}
else
{
ierr = hypre_MPSchwarzSolve(A, hypre_ParVectorLocalVector(f),
domain_structure, u, relax_wt,
hypre_ParVectorLocalVector(Vtemp));
}
return ierr;
}
/*--------------------------------------------------------------------
* hypre_SchwarzCFSolve
*--------------------------------------------------------------------*/
int
hypre_SchwarzCFSolve(void *schwarz_vdata,
hypre_ParCSRMatrix *A,
hypre_ParVector *f,
hypre_ParVector *u,
int *CF_marker,
int rlx_pt)
{
hypre_SchwarzData *schwarz_data = schwarz_vdata;
int ierr = 0;
hypre_CSRMatrix *domain_structure =
hypre_SchwarzDataDomainStructure(schwarz_data);
double *scale = hypre_SchwarzDataScale(schwarz_data);
hypre_ParVector *Vtemp = hypre_SchwarzDataVtemp(schwarz_data);
int variant = hypre_SchwarzDataVariant(schwarz_data);
double relax_wt = hypre_SchwarzDataRelaxWeight(schwarz_data);
if (variant == 1)
{
ierr = hypre_AdSchwarzCFSolve(A, f, domain_structure, scale, u, Vtemp,
CF_marker, rlx_pt);
}
else if (variant == 4)
{
ierr = hypre_MPSchwarzCFFWSolve(A, hypre_ParVectorLocalVector(f),
domain_structure, u, relax_wt,
hypre_ParVectorLocalVector(Vtemp),
CF_marker, rlx_pt);
}
else
{
ierr = hypre_MPSchwarzCFSolve(A, hypre_ParVectorLocalVector(f),
domain_structure, u, relax_wt,
hypre_ParVectorLocalVector(Vtemp),
CF_marker, rlx_pt);
}
return ierr;
}
/*--------------------------------------------------------------------------
* Routines to set various parameters
*--------------------------------------------------------------------------*/
int
hypre_SchwarzSetVariant( void *data, int variant )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataVariant(schwarz_data) = variant;
return (ierr);
}
int
hypre_SchwarzSetDomainType( void *data, int domain_type )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataDomainType(schwarz_data) = domain_type;
return (ierr);
}
int
hypre_SchwarzSetOverlap( void *data, int overlap )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataOverlap(schwarz_data) = overlap;
return (ierr);
}
int
hypre_SchwarzSetNumFunctions( void *data, int num_functions )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataNumFunctions(schwarz_data) = num_functions;
return (ierr);
}
int
hypre_SchwarzSetRelaxWeight( void *data, double relax_weight )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataRelaxWeight(schwarz_data) = relax_weight;
return (ierr);
}
int
hypre_SchwarzSetDomainStructure( void *data, hypre_CSRMatrix *domain_structure )
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataDomainStructure(schwarz_data) = domain_structure;
return (ierr);
}
int
hypre_SchwarzSetScale( void *data, double *scale)
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataScale(schwarz_data) = scale;
return (ierr);
}
int
hypre_SchwarzReScale( void *data, int size, double value)
{
int ierr = 0;
int i;
double *scale;
hypre_SchwarzData *schwarz_data = data;
scale = hypre_SchwarzDataScale(schwarz_data);
for (i=0; i < size; i++)
scale[i] *= value;
return (ierr);
}
int
hypre_SchwarzSetDofFunc( void *data, int *dof_func)
{
int ierr = 0;
hypre_SchwarzData *schwarz_data = data;
hypre_SchwarzDataDofFunc(schwarz_data) = dof_func;
return (ierr);
}