Use new fei files.

This commit is contained in:
chtong 2002-03-27 17:10:40 +00:00
parent ad4edaf15f
commit cbc0e592d6
6 changed files with 481 additions and 53 deletions

View File

@ -5,11 +5,11 @@
#include <stdlib.h>
/**
This is a very simple class for passing stuff in and out of LinearSystemCore
This is a very simple class for passing stuff around
in a void pointer. It has the ability to store and query
a type name, so at least there can be user-enforced
type safety.
When setTypeName is called, a char* is created and a copy
of the input argument is taken. This char* is later destroyed
by the Data destructor. The void* dataPtr_ member is not

View File

@ -1,19 +1,60 @@
#ifndef _FEI_Implementation_h_
#define _FEI_Implementation_h_
class ESI_Broker;
class Data;
class LinearSystemCore;
class SNL_FEI_Structure;
class Filter;
class CommUtils;
#include "base/FEI_SNL.h"
#include "base/fei_mpi.h"
#include "base/feiArray.h"
/**
This is the (C++) user's point of interaction with the FEI implementation. The
user will declare an instance of this class in their code, and call the public
FEI functions on that instance. The functions implemented by this class are
those in the abstract FEI declaration, plus possibly others. i.e., the functions
provided by this class are a superset of those in the FEI specification.
<p>
This class takes, as a constructor argument, an ESI_Broker implementation which
may be either
a "genuine" factory for ESI interface instances, or it may be a shell containing
only an instance of a LinearSystemCore implementation or a FiniteElementData
implementation. These are the abstract interfaces through which solver libraries
may be coupled to this FEI implementation.<p>
As of August 2001, the following solver implementations of these interfaces
exist:<p>
<ul>
<li>LinearSystemCore:
<ul>
<li>Aztec
<li>HYPRE
<li>ISIS++
<li>PETSc
<li>Prometheus
<li>SPOOLES
</ul>
<li>ESI_Broker (actual ESI implementations):
<ul>
<li>ISIS_ESI
<li>Trilinos
</ul>
<li>FiniteElementData:
<ul>
<li>FETI
</ul>
</ul>
*/
class FEI_Implementation : public FEI {
class FEI_Implementation : public FEI_SNL {
public:
/** Constructor.
@param lsMgr an instance of an ESI_LSManager. (LSC_LSMgr can be used here,
/** constructor.
@param broker an instance of an ESI_Broker. (LSC_Broker can be used here,
it is a wrapper for the old LinearSystemCore.)
@param comm MPI_Comm communicator
@param masterRank The "master" mpi rank. Defaults to 0 if not supplied.
@ -21,7 +62,7 @@ class FEI_Implementation : public FEI {
will produce screen output if the parameter "outputLevel" is set to a
value greater than 0 via a call to the parameters function.
*/
FEI_Implementation(ESI_LSManager* lsMgr, MPI_Comm comm,
FEI_Implementation(ESI_Broker* broker, MPI_Comm comm,
int masterRank=0);
/** Destructor. */
@ -59,6 +100,17 @@ class FEI_Implementation : public FEI {
GlobalID elemID,
const GlobalID* elemConn);
int initSlaveVariable(GlobalID slaveNodeID,
int slaveFieldID,
int offsetIntoSlaveField,
int numMasterNodes,
const GlobalID* masterNodeIDs,
const int* masterFieldIDs,
const double* weights,
double rhsValue);
int deleteMultCRs();
// identify sets of shared nodes
int initSharedNodes(int numSharedNodes,
const GlobalID *sharedNodeIDs,
@ -115,6 +167,7 @@ class FEI_Implementation : public FEI {
// separately
int resetMatrix(double s=0.0);
int resetRHSVector(double s=0.0);
int resetInitialGuess(double s=0.0);
int loadNodeBCs(int numNodes,
const GlobalID *nodeIDs,
@ -222,7 +275,12 @@ class FEI_Implementation : public FEI {
int setRHSScalars(int numScalars,
const int* IDs,
const double* scalars);
//indicate that the matrix/vectors can be finalized now. e.g., boundary-
//conditions enforced, etc., etc.
int loadComplete();
//get residual norms
int residualNorm(int whichNorm,
int numFields,
@ -234,10 +292,7 @@ class FEI_Implementation : public FEI {
// query iterations performed.
int iterations(int& itersTaken) const {
itersTaken = fei_[index_soln_fei_]->iterations();
return(0);
};
int iterations(int& itersTaken) const;
int version(char*& versionString);
@ -391,6 +446,10 @@ class FEI_Implementation : public FEI {
int getNumBlockElemDOF(GlobalID blockID, int& DOFPerElem) const;
// return the parameters that have been set so far. The caller should
// NOT delete the paramStrings pointer.
int getParameters(int& numParams, char**& paramStrings);
//And now a couple of non-FEI query functions that Sandia applications
//need to augment the matrix-access functions. I (Alan Williams) will
//argue to have these included in the FEI 2.1 specification update.
@ -418,12 +477,43 @@ class FEI_Implementation : public FEI {
int& numEqns,
int* eqnNumbers);
/**Get the solution data for a particular field, on an arbitrary set of
nodes.
@param fieldID Input. field identifier for which solution data is being
requested.
@param numNodes Input. Length of the nodeIDs list.
@param nodeIDs Input. List specifying the nodes on which solution
data is being requested.
@param results Allocated by caller, but contents are output.
Solution data for the i-th node/element starts in position i*fieldSize,
where fieldSize is the number of scalar components that make up
'fieldID'.
@return error-code 0 if successful
*/
int getNodalFieldSolution(int fieldID,
int numNodes,
const GlobalID* nodeIDs,
double* results);
int getNumLocalNodes(int& numNodes);
int getLocalNodeIDList(int& numNodes,
GlobalID* nodeIDs,
int lenNodeIDs);
int putNodalFieldData(int fieldID,
int numNodes,
const GlobalID* nodeIDs,
const double* nodeData);
//============================================================================
private: //functions
void deleteIDs();
void deleteRHSScalars();
int allocateInternalFEIs();
int allocateInternalFEIs(int numMatrices, int* matrixIDs,
int* numRHSs, int** rhsIDs);
void debugOut(const char* msg);
void debugOut(const char* msg, int whichFEI);
@ -440,16 +530,22 @@ class FEI_Implementation : public FEI {
//============================================================================
private: //member variables
ESI_LSManager* constructorLsMgr_;
ESI_LSManager** lsMgr_;
LinearSystemCore** linSysCore_;
ESI_Broker* broker_;
LinearSystemCore* linSysCore_;
feiArray<LinearSystemCore*> lscArray_;
bool haveESI_;
BASE_FEI** fei_;
bool haveLinSysCore_;
bool haveFEData_;
SNL_FEI_Structure* problemStructure_;
Filter** filter_;
CommUtils* commUtils_;
int numInternalFEIs_;
bool internalFEIsAllocated_;
feiArray<int> feiIDs_;
feiArray<int> matrixIDs_;
feiArray<int> numRHSIDs_;
int** rhsIDs_;
@ -460,8 +556,8 @@ class FEI_Implementation : public FEI {
double** rhsScalars_;
bool rhsScalarsSet_;
int index_soln_fei_;
int index_current_fei_;
int index_soln_filter_;
int index_current_filter_;
int index_current_rhs_row_;
int solveType_;
@ -471,12 +567,12 @@ class FEI_Implementation : public FEI {
bool aggregateSystemFormed_;
int newMatrixDataLoaded_;
bool linearSystemFinalized_;
Data *soln_fei_matrix_;
Data *soln_fei_vector_;
MPI_Comm comm_;
int masterRank_;
int localRank_;
int numProcs_;
@ -487,7 +583,9 @@ class FEI_Implementation : public FEI {
char* debugFileName_;
int solveCounter_;
int debugOutput_;
FILE *debugFile_;
ostream* dbgOStreamPtr_;
bool dbgFileOpened_;
ofstream* dbgFStreamPtr_;
double initTime_, loadTime_, solveTime_, solnReturnTime_;

View File

@ -1,32 +1,49 @@
#ifndef _LinearSystemCore_h_
#define _LinearSystemCore_h_
//Files that should to be included before the compiler
//reaches this header:
//
//#include "src/Data.h" //for the declaration of the 'Data' class.
//#include "base/basicTypes.h" //for the definition of the 'GlobalID' type.
//
#ifdef min
#undef min
#endif
#ifdef max
#undef max
#endif
#include <iostream.h>
class Data;
class Lookup;
#include "fei_defs.h"
/**
This is the 'generic' interface (to be replaced by ESI_LSManager) to a
solver-library -- the destination for the data being assembled into a linear
system by the FEI implementation.
This is the original internal FEI interface to solver-libraries --
the destination for the data being assembled into a linear system by the FEI
implementation.
When creating a specific FEI implementation, i.e., a version that
supports a specific underlying linear solver library, the main
task that must be performed is the implementation of this interface,
LinearSystemCore (Note: the LinearSystemCore interface will ultimately be
replaced by the ESI_LSManager interface.).
This is the class that holds and manipulates all solver-library-specific
stuff, such as matrices/vectors, solvers/preconditioners, etc. An
instance of this class is owned and used by the class that implements
the public FEI spec. i.e., when element contributions, etc., are received
from the finite-element application, the data is ultimately passed to this
LinearSystemCore (Note: the LinearSystemCore interface is being
replaced by the ESI_Broker interface.).
To date (as of August 2001), implementations of this interface exist for
coupling the following solver libraries to the FEI implementation:
<ul>
<li>Aztec
<li>HYPRE
<li>ISIS++
<li>PETSc
<li>Prometheus
<li>SPOOLES
</ul>
An implementation of LinearSystemCore holds and manipulates all
solver-library-specific stuff, such as matrices/vectors,
solvers/preconditioners, etc. An instance of this class is owned and used by
the class that implements the public FEI spec. i.e., when element
contributions, etc., are received from the finite-element application, the
data is ultimately passed to this
class for assembly into the sparse matrix and associated vectors. This class
will also be asked to launch any underlying solver, and finally to
return the solution.
@ -152,6 +169,21 @@ class LinearSystemCore {
virtual int setLookup(Lookup& lookup) = 0;
/** Query a named property (such as timing statistics, etc.) from the solver
library.
@param name Input. Name of the property for which a value is being
requested.
@pararm value Output. Requested property's value.
@return error-code 0 if successful. -1 probably indicates that the
named property is not recognized.
*/
virtual int getProperty(const char* name, double& value)
{
cerr << "LinearSystemCore::getProperty not implemented by derived class."
<< endl;
return(-1);
}
/** Supply LinearSystemCore with global offset information for the problem
being assembled.
@param len Length of the following list arguments. This will be numProcs+1

View File

@ -1,18 +1,20 @@
#ifndef _Lookup_h_
#define _Lookup_h_
#include "fei_defs.h"
/**
This interface is intended to be used by a LinearSystemCore implementation
(or a ESI_LSManager implementation) to look up various information about the
structure of the finite-element problem that the linear system being
assembled into LinearSystemCore by a FEI implementation, arises from.
(or a ESI_Broker or FiniteElementData implementation) to look up various
information about the structure of the finite-element problem being assembled
into LinearSystemCore by a FEI implementation.
Lookup basically provides the query functions from the FEI implementation's
ProblemStructure class. However, unlike the ProblemStructure header, this
SNL_FEI_Structure class. However, unlike the SNL_FEI_Structure header, this
header can be included without also including a bunch of other non-public
FEI implementation headers. ProblemStructure also provides a lot of
FEI implementation headers. SNL_FEI_Structure also provides a lot of
functions for *setting* the structural information, which the
LinearSystemCore object shouldn't get access to.
LinearSystemCore object doesn't need access to.
Background:
The finite element problem consists of a set of element-blocks, each of
@ -23,7 +25,10 @@
solution-fields. This is indicated by a negative fieldID. There are no
equations corresponding to fields with negative fieldIDs. Data that is
passed in associated with negative fieldIDs is probably coordinate or
nullspace data, or other data passed from the application to the solver.
nullspace data, or other data passed from the application to the solver
(note that this non-solution-field data won't appear in element-matrices,
it will be passed separately through a special function for supplying
nodal data).
elem-block IDs and field IDs are application-provided numbers, and no
assumption may be made regarding their order, contiguousness, etc.
@ -36,13 +41,11 @@
NOTES: 1. functions that return an equation number, or a size (e.g.,
num-equations, num-fields, etc.) may indicate an error or 'not-found'
condition by returning a negative number. Functions that return a
pointer, may indicate an error by returning NULL.
pointer may indicate an error by returning NULL.
*/
class Lookup {
public:
/** Constructor */
Lookup(){};
/** Destructor, Don't call this. The FEI implementation will destroy this
object. */
virtual ~Lookup(){};
@ -118,7 +121,6 @@ class Lookup {
/** Given a nodeNumber/fieldID pair, this function returns the first global
(0-based) equation number associated with that nodeNumber/fieldID pair.
!!!!! not yet implemented !!!!!
@param nodeNumber
@param fieldID
*/
@ -137,6 +139,38 @@ class Lookup {
virtual int getAssociatedFieldID(int eqnNumber) = 0;
/** Given a nodeNumber, determine whether that node is connected to a local
element.
@param nodeNumber
@return true if nodeNumber is connected to a local element, false
otherwise.
*/
virtual bool isInLocalElement(int nodeNumber) = 0;
/** Given a nodeNumber, return the number of subdomains that contain this
node. subdomains correspond to processors. The number of subdomains that
contain a node does not always equal the number of processors that share
a node. There are two kinds of "sharing" -- the "normal" kind, where a
node is shared because it is connected to elements that reside on more
than one processor, and the "wierd" kind where nodes are considered
shared simply because of being in cross-processor constraints. This
function describes how many processors share this node in the "normal"
sense. Thus, in general, this relationship holds:
getNumSubdomains(nodeNum) <= getNumSharingProcs(nodeNum)
@param nodeNumber
@return numSubdomains
*/
virtual int getNumSubdomains(int nodeNumber) = 0;
/** Given a nodeNumber, return a list of the subdomains that contain this
node. This is the list of subdomains that's counted by the method
'getNumSubdomains' above.
@param nodeNumber
@return pointer to list of subdomains (processor ranks). NULL if the
specified nodeNumber is not found.
*/
virtual int* getSubdomainList(int nodeNumber) = 0;
/** Return the number of local nodes that are shared by multiple processors
*/
virtual int getNumSharedNodes() = 0;

View File

@ -1,6 +1,212 @@
#ifndef _Utils_h_
#define _Utils_h_
#include "base/feiArray.h"
template<class T>
int Utils_binary_search(T item, const T* list, int len, int& insertPoint)
{
if (len == 0) {
insertPoint = 0;
return(-1);
}
if (len == 1) {
if (list[0] == item) return(0);
else {
if (list[0] < item) insertPoint = 1;
else insertPoint = 0;
return(-1);
}
}
unsigned start = 0, end = len - 1;
while(end - start > 1) {
unsigned mid = (start + end) >> 1;
if (list[mid] < item) start = mid;
else end = mid;
}
if (list[start] == item) return((int)start);
if (list[end] == item) return((int)end);
if (list[end] < item) insertPoint = (int)end+1;
else if (list[start] < item) insertPoint = (int)end;
else insertPoint = (int)start;
return(-1);
}
template<class T>
int Utils_binary_search(T item, const T** list, int len, int& insertPoint)
{
if (len == 0) {
insertPoint = 0;
return(-1);
}
if (len == 1) {
if (*(list[0]) == item) return(0);
else {
if (*(list[0]) < item) insertPoint = 1;
else insertPoint = 0;
return(-1);
}
}
unsigned start = 0, end = len - 1;
while(end - start > 1) {
unsigned mid = (start + end) >> 1;
if (*(list[mid]) < item) start = mid;
else end = mid;
}
if (*(list[start]) == item) return((int)start);
if (*(list[end]) == item) return((int)end);
if ((*list[end]) < item) insertPoint = (int)end+1;
else if (*(list[start]) < item) insertPoint = (int)end;
else insertPoint = (int)start;
return(-1);
}
template<class T>
int Utils_binary_search(T item, const T* list, int len)
{
if (len == 0) return(-1);
if (len == 1) {
if (list[0] == item) return(0);
else return(-1);
}
unsigned start = 0, end = len - 1;
while(end - start > 1) {
unsigned mid = (start + end) >> 1;
if (list[mid] < item) start = mid;
else end = mid;
}
if (list[start] == item) return((int)start);
if (list[end] == item) return((int)end);
return(-1);
}
template<class T>
class Utils_binary_search_object {
public:
virtual ~Utils_binary_search_object() {}
int operator() (T item, const T* list, int len)
{
return( Utils_binary_search(item, list, len) );
}
int operator() (T item, const T* list, int len, int& insertPoint)
{
return( Utils_binary_search(item, list, len, insertPoint) );
}
};
template<class T, class binary_searcher>
int Utils_insert_sorted(T item, feiArray<T>& list, binary_searcher bin_search)
{
int insertPoint = -1;
int position = bin_search(item, list.dataPtr(), list.length(), insertPoint);
if (position >= 0) return(-1);
else {
int err = list.insert(item, insertPoint);
if (err) return(err);
else return(insertPoint);
}
}
template<class T>
int Utils_merge_sorted_arrays(feiArray<T>& input, feiArray<T>& dest,
T* workSpace=NULL)
{
//This function merges the array 'input' into the array 'dest', maintaining
//sortedness in the dest array.
//Important assumption: both arrays are assumed to be sorted on entry.
//
int input_len = input.length();
if (input_len == 0) return(0);
int old_dest_len = dest.length();
if (old_dest_len == 0) {
dest = input;
return(0);
}
T* input_ptr = input.dataPtr();
T* work_ptr = workSpace==NULL ? input_ptr : workSpace;
int dest_offset = -1;
//first let's count how many items in input don't already reside in dest.
int numNotThere = 0;
int insertPoint = -1;
T* old_dest_ptr = dest.dataPtr();
int i, offset = 0, end = old_dest_len;
int search_offset = 0;
for(i=0; i<input_len; i++) {
T next_value = input_ptr[i];
dest_offset = Utils_binary_search(next_value, old_dest_ptr+search_offset,
end-search_offset, insertPoint);
if (dest_offset < 0) {
work_ptr[numNotThere++] = next_value;
search_offset += insertPoint;
offset = search_offset;
}
else {
search_offset += dest_offset;
}
if (search_offset >= end) {
for(int j=i+1; j<input_len; j++) work_ptr[numNotThere++] = input_ptr[j];
break;
}
}
if (numNotThere == 0) return(0);
//now we can resize the dest array
int new_dest_len = old_dest_len+numNotThere;
int err = dest.resize(new_dest_len);
if (err != 0) return(err);
//now march down the dest and input arrays from the top, putting values in
T* dest_ptr = dest.dataPtr();
int new_offset = new_dest_len-1;
for(i=numNotThere-1; i>=0; i--) {
for(int j=end-1; j>=offset; j--) {
dest_ptr[new_offset--] = dest_ptr[j];
}
dest_ptr[new_offset--] = work_ptr[i];
end = offset;
if (i > 0) {
Utils_binary_search(work_ptr[i-1], dest_ptr, end, offset);
}
}
return(0);
}
class Utils {
public:
static void appendToCharArrayList(char**& strings, int& numStrings,
@ -30,10 +236,6 @@ class Utils {
static void GlobalIDListInsert(GlobalID item, int index, GlobalID*& list,
int& len, int& allocatedLength);
static void doubleArrayListInsert(int index, feiArray<double>**& daList, int& len);
static void intArrayListInsert(int index, feiArray<int>**& iaList, int& len);
static void intTableInsertRow(int* newRow, int whichRow,
int**& table, int& numRows);
@ -42,6 +244,8 @@ class Utils {
static void appendIntList(int newItem, int*& list, int& lenList);
static void appendDoubleList(double newItem, double*& list, int& lenList);
static bool inList(int* list, int lenList, int item);
};

View File

@ -0,0 +1,60 @@
#ifndef _fei_defs_h_
#define _fei_defs_h_
/*
In this file we set some #defines to use as parameters to
some fei functions, and also some error-code returns.
We also provide the typedef for 'GlobalID' which appears in
many FEI function prototypes. Note that the default case is
for GlobalID to simply be an int.
This file is included by both C and C++ versions of the fei.
*/
#ifdef EIGHT_BYTE_GLOBAL_ID
typedef long long GlobalID;
#define GlobalID_MAX LLONG_MAX
#define GlobalID_MIN LLONG_MIN
#else
typedef int GlobalID;
#endif
/* solveType (used in 'setSolveType'): */
#define FEI_SINGLE_SYSTEM 0
#define FEI_EIGEN_SOLVE 1
#define FEI_AGGREGATE_SUM 2
#define FEI_AGGREGATE_PRODUCT 3
/* IDType (used in coefficient-access functions) */
#define FEI_NODE 0
#define FEI_ELEMENT 1
#define FEI_ONLY_NODES 2
#define FEI_ONLY_ELEMENTS 3
/* elemFormat (used in 'sumInElem' and 'sumInElemMatrix'): */
#define FEI_DENSE_ROW 0
#define FEI_UPPER_SYMM_ROW 1
#define FEI_LOWER_SYMM_ROW 2
#define FEI_DENSE_COL 3
#define FEI_UPPER_SYMM_COL 4
#define FEI_LOWER_SYMM_COL 5
#define FEI_DIAGONAL 6
/* interleaveStrategy (used in initElemBlock): */
#define FEI_NODE_MAJOR 0
#define FEI_FIELD_MAJOR 1
/* timingMode (used in cumulative_MPI_Wtimes): */
#define FEI_LOCAL_TIMES 0
#define FEI_MAX_TIMES 1
#define FEI_MIN_TIMES 2
/* FEI function return values */
#define FEI_SUCCESS 0
#define FEI_FATAL_ERROR -1
#define FEI_ID_NOT_FOUND -2
#endif