Add stuff to support AMS preconditioning.

This commit is contained in:
chtong 2006-12-04 17:28:46 +00:00
parent 5ff4dc0775
commit 2a52c03b03
2 changed files with 136 additions and 38 deletions

View File

@ -327,9 +327,14 @@ HYPRE_LinSysCore::HYPRE_LinSysCore(MPI_Comm comm) :
MLI_Hybrid_MaxIter_ = 100;
MLI_Hybrid_ConvRate_ = 0.95;
MLI_Hybrid_NTrials_ = 5;
amsX_ = NULL;
amsY_ = NULL;
amsZ_ = NULL;
AMSData_.numNodes_ = 0;
AMSData_.numLocalNodes_ = 0;
AMSData_.EdgeNodeList_ = NULL;
AMSData_.NodeNumbers_ = NULL;
AMSData_.NodalCoord_ = NULL;
amsX_ = NULL;
amsY_ = NULL;
amsZ_ = NULL;
//-------------------------------------------------------------------
// parameters ML Maxwell solver
@ -556,6 +561,9 @@ HYPRE_LinSysCore::~HYPRE_LinSysCore()
// HYPRE_ParCSRMatrixDestroy(maxwellGEN_);
// maxwellGEN_ = NULL;
//}
if (AMSData_.EdgeNodeList_ != NULL) delete [] AMSData_.EdgeNodeList_;
if (AMSData_.NodeNumbers_ != NULL) delete [] AMSData_.NodeNumbers_;
if (AMSData_.NodalCoord_ != NULL) delete [] AMSData_.NodalCoord_;
//-------------------------------------------------------------------
// diagnostic message
@ -2131,10 +2139,10 @@ int HYPRE_LinSysCore::matrixLoadComplete()
int HYPRE_LinSysCore::putNodalFieldData(int fieldID, int fieldSize,
int* nodeNumbers, int numNodes, const double* data)
{
int i, j, **nodeFieldIDs, nodeFieldID, *procNRows, nRows;
int blockID, *blockIDs, *eqnNumbers, *iTempArray;
int i, j, **nodeFieldIDs, nodeFieldID, *procNRows, nRows, errCnt;
int blockID, *blockIDs, *eqnNumbers, *iArray, newNumEdges;
//int checkFieldSize;
int *aleNodeNumbers, index, newNumNodes;
int *aleNodeNumbers, index, newNumNodes, numEdges;
double *newData;
if ( (HYOutputLevel_ & HYFEI_SPECIALMASK) >= 3 )
@ -2225,31 +2233,111 @@ This should ultimately be taken out even for newer ale3d implementation
}
//-------------------------------------------------------------------
// This part is for loading the nodal coordinate information for
// use with the AMS preconditioner.
// This part is for loading the edge to (hypre-compatible) node list
// for AMS (the node list is ordered with the edge equation numbers
// and the node numbers are true node equation numbers passed in by
// the application which obtains the true node eqn numbers via the
// nodal FEI) ===> EdgeNodeList
//-------------------------------------------------------------------
else if ( fieldID == -4 )
if (fieldID == -4)
{
if (numNodes <= 0 || fieldSize <= 0) return 1;
if ( (HYOutputLevel_ & HYFEI_SPECIALMASK) >= 5 )
if ((HYOutputLevel_ & HYFEI_SPECIALMASK) >= 5)
{
for ( i = 0; i < numNodes; i++ )
for ( j = 0; j < fieldSize; j++ )
for (i = 0; i < numNodes; i++)
for (j = 0; j < fieldSize; j++)
printf("putNodalFieldData : %4d %2d = %e\n",i,j,
data[i*fieldSize+j]);
}
if ( MLI_EqnNumbers_ != NULL ) delete [] MLI_EqnNumbers_;
if ( MLI_NodalCoord_ != NULL ) delete [] MLI_NodalCoord_;
MLI_FieldSize_ = fieldSize;
MLI_NumNodes_ = numNodes;
MLI_EqnNumbers_ = new int[numNodes+1];
MLI_NodalCoord_ = new double[fieldSize*numNodes+1];
for (i = 0; i < numNodes; i++) MLI_EqnNumbers_[i] = nodeNumbers[i];
MLI_EqnNumbers_[numNodes] = -1;
for (i = 0; i < numNodes*fieldSize; i++) MLI_NodalCoord_[i] = data[i];
MLI_NodalCoord_[numNodes*fieldSize] = -99999.0;
if (HYPreconID_ == HYAMS && lookup_ != NULL && fieldSize == 2 &&
numNodes > 0)
{
blockIDs = (int *) lookup_->getElemBlockIDs();
blockID = blockIDs[0];
nodeFieldIDs = (int **) lookup_->getFieldIDsTable(blockID);
nodeFieldID = nodeFieldIDs[0][0];
numEdges = numNodes;
eqnNumbers = new int[numEdges];
iArray = new int[numEdges*fieldSize];
newNumEdges = 0;
for (i = 0; i < numEdges; i++)
{
index = lookup_->getEqnNumber(nodeNumbers[i],nodeFieldID);
if (index >= localStartRow_-1 && index < localEndRow_)
{
for (j = 0; j < fieldSize; j++)
iArray[newNumEdges*fieldSize+j] = (int) data[i*fieldSize+j];
eqnNumbers[newNumEdges++] = index;
}
}
nRows = localEndRow_ - localStartRow_ + 1;
if (AMSData_.EdgeNodeList_ != NULL) delete [] AMSData_.EdgeNodeList_;
AMSData_.EdgeNodeList_ = NULL;
if (newNumEdges > 0)
{
AMSData_.numEdges_ = nRows;
AMSData_.EdgeNodeList_ = new int[nRows*fieldSize];
for (i = 0; i < nRows*fieldSize; i++)
AMSData_.EdgeNodeList_[i] = -99999;
for (i = 0; i < newNumNodes; i++)
{
index = eqnNumbers[i] - localStartRow_ + 1;
for (j = 0; j < fieldSize; j++ )
AMSData_.EdgeNodeList_[index+j] = iArray[i*fieldSize+j];
}
errCnt = 0;
for (i = 0; i < nRows*fieldSize; i++)
if (AMSData_.EdgeNodeList_[i] == -99999) errCnt++;
if (errCnt > 0)
printf("putNodalFieldData ERROR:incomplete AMS edge vertex list\n");
}
delete [] eqnNumbers;
delete [] iArray;
}
}
//-------------------------------------------------------------------
// This part is for converting node numbers to equations as well as
// for loading the nodal coordinate information
// (stored in NodeNumbers, NodalCoord, numNodes, numLocalNodes)
//-------------------------------------------------------------------
if (fieldID == -5)
{
if ((HYOutputLevel_ & HYFEI_SPECIALMASK) >= 5)
{
for (i = 0; i < numNodes; i++)
for (j = 0; j < fieldSize; j++)
printf("putNodalFieldData : %4d %2d = %e\n",i,j,
data[i*fieldSize+j]);
}
if (lookup_ != NULL && fieldSize == 1)
{
blockIDs = (int *) lookup_->getElemBlockIDs();
blockID = blockIDs[0];
nodeFieldIDs = (int **) lookup_->getFieldIDsTable(blockID);
nodeFieldID = nodeFieldIDs[0][0];
if (AMSData_.NodeNumbers_ != NULL) delete [] AMSData_.NodeNumbers_;
if (AMSData_.NodalCoord_ != NULL) delete [] AMSData_.NodalCoord_;
AMSData_.NodeNumbers_ = NULL;
AMSData_.NodalCoord_ = NULL;
AMSData_.numNodes_ = 0;
AMSData_.numLocalNodes_ = localEndRow_ - localStartRow_ + 1;
if (numNodes > 0)
{
AMSData_.numNodes_ = numNodes;
AMSData_.numLocalNodes_ = localEndRow_ - localStartRow_ + 1;
AMSData_.NodeNumbers_ = new int[numNodes];
AMSData_.NodalCoord_ = new double[fieldSize*numNodes];
for (i = 0; i < numNodes; i++)
{
index = lookup_->getEqnNumber(nodeNumbers[i],nodeFieldID);
AMSData_.NodeNumbers_[i] = index;
for (j = 0; j < fieldSize; j++)
AMSData_.NodalCoord_[i*fieldSize+j] = data[i*fieldSize+j];
}
}
}
}
//-------------------------------------------------------------------
@ -2279,12 +2367,11 @@ This should ultimately be taken out even for newer ale3d implementation
procNRows = new int[numProcs_];
for ( i = 0; i < numProcs_; i++ ) procNRows[i] = 0;
procNRows[mypid_] = localEndRow_;
iTempArray = procNRows;
iArray = procNRows;
procNRows = new int[numProcs_+1];
for ( i = 0; i <= numProcs_; i++ ) procNRows[i] = 0;
MPI_Allreduce(iTempArray,&(procNRows[1]),numProcs_,MPI_INT,MPI_SUM,
comm_);
delete [] iTempArray;
MPI_Allreduce(iArray,&(procNRows[1]),numProcs_,MPI_INT,MPI_SUM,comm_);
delete [] iArray;
HYPRE_LSI_MLICreateNodeEqnMap(HYPrecon_, numNodes, aleNodeNumbers,
eqnNumbers, procNRows);
delete [] procNRows;
@ -2305,7 +2392,7 @@ int HYPRE_LinSysCore::putNodalFieldData(int fieldID, int fieldSize,
int* nodeNumbers, int numNodes, const double* data)
{
int i, **nodeFieldIDs, nodeFieldID, numFields, *procNRows;
int blockID, *blockIDs, *eqnNumbers, *iTempArray, checkFieldSize;
int blockID, *blockIDs, *eqnNumbers, *iArray, checkFieldSize;
int *aleNodeNumbers;
if ( (HYOutputLevel_ & HYFEI_SPECIALMASK) >= 2 )
@ -2378,12 +2465,12 @@ int HYPRE_LinSysCore::putNodalFieldData(int fieldID, int fieldSize,
procNRows = new int[numProcs_];
for ( i = 0; i < numProcs_; i++ ) procNRows[i] = 0;
procNRows[mypid_] = localEndRow_;
iTempArray = procNRows;
iArray = procNRows;
procNRows = new int[numProcs_+1];
for ( i = 0; i <= numProcs_; i++ ) procNRows[i] = 0;
MPI_Allreduce(iTempArray,&(procNRows[1]),numProcs_,MPI_INT,MPI_SUM,
MPI_Allreduce(iArray,&(procNRows[1]),numProcs_,MPI_INT,MPI_SUM,
comm_);
delete [] iTempArray;
delete [] iArray;
HYPRE_LSI_MLICreateNodeEqnMap(HYPrecon_, numNodes, aleNodeNumbers,
eqnNumbers, procNRows);
delete [] procNRows;
@ -2728,13 +2815,9 @@ int HYPRE_LinSysCore::copyOutMatrix(double scalar, Data& data)
{
data.setDataPtr((void *) HYA_);
}
else if (!strcmp(name, "NodeNumbers"))
else if (!strcmp(name, "AMSData"))
{
data.setDataPtr((void *) MLI_EqnNumbers_);
}
else if (!strcmp(name, "NodalCoord"))
{
data.setDataPtr((void *) MLI_NodalCoord_);
data.setDataPtr((void *) &AMSData_);
}
else
{

View File

@ -85,6 +85,20 @@ enum HYpreconID {HYIDENTITY,HYDIAGONAL,HYPILUT,HYPARASAILS,HYBOOMERAMG,HYML,
#define HYFEI_PRINTPARCSRMAT 2097152
#define HYFEI_IMPOSENOBC 4194304
// *************************************************************************
// substructure definition
// -------------------------------------------------------------------------
typedef struct
{
int *EdgeNodeList_;
int *NodeNumbers_;
int numEdges_;
int numLocalNodes_;
int numNodes_;
double *NodalCoord_;
} HYPRE_AMSData;
// *************************************************************************
// class definition
// -------------------------------------------------------------------------
@ -696,6 +710,7 @@ class HYPRE_LinSysCore
int MLI_Hybrid_MaxIter_;
double MLI_Hybrid_ConvRate_;
int MLI_Hybrid_NTrials_;
HYPRE_AMSData AMSData_;
// ----------------------------------------------------------------------
// ML Maxwell variables