FEI Version of the Day
fei_FEI_Impl.hpp
00001 /*
00002 // @HEADER
00003 // ************************************************************************
00004 //             FEI: Finite Element Interface to Linear Solvers
00005 //                  Copyright (2005) Sandia Corporation.
00006 //
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, the
00008 // U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Alan Williams (william@sandia.gov) 
00038 //
00039 // ************************************************************************
00040 // @HEADER
00041 */
00042 
00043 
00044 #ifndef _fei_FEI_Impl_hpp_
00045 #define _fei_FEI_Impl_hpp_
00046 
00047 #include <fei_macros.hpp>
00048 #include <fei_mpi.h>
00049 #include <FEI.hpp>
00050 #include <fei_Factory.hpp>
00051 
00052 #include <set>
00053 #include <vector>
00054 #include <map>
00055 
00056 namespace fei {
00057 
00068   class FEI_Impl : public FEI, private fei::Logger {
00069   public:
00072     FEI_Impl(fei::SharedPtr<LibraryWrapper> wrapper,
00073           MPI_Comm comm,
00074           int masterRank=0);
00075 
00078     FEI_Impl(const fei::Factory* factory,
00079           MPI_Comm comm,
00080           int masterRank=0);
00081 
00084     virtual ~FEI_Impl();
00085 
00090    fei::SharedPtr<fei::LinearSystem> getLinearSystem();
00091 
00092     int parameters(int numParams, 
00093                    const char *const* paramStrings);
00094 
00095    int setIDLists(int numMatrices,
00096                   const int* matrixIDs,
00097                   int numRHSs,
00098                   const int* rhsIDs);
00099 
00100    int setSolveType(int solveType);
00101 
00102    int initFields(int numFields, 
00103                   const int *fieldSizes, 
00104                   const int *fieldIDs,
00105                   const int *fieldTypes=NULL);
00106 
00107    int initElemBlock(GlobalID elemBlockID,
00108                      int numElements,
00109                      int numNodesPerElement,
00110                      const int* numFieldsPerNode,
00111                      const int* const* nodalFieldIDs,
00112                      int numElemDofFieldsPerElement,
00113                      const int* elemDOFFieldIDs,
00114                      int interleaveStrategy);
00115 
00116    int initElem(GlobalID elemBlockID,
00117                 GlobalID elemID,
00118                 const GlobalID* elemConn);
00119 
00120    int initSlaveVariable(GlobalID slaveNodeID, 
00121                          int slaveFieldID,
00122                          int offsetIntoSlaveField,
00123                          int numMasterNodes,
00124                          const GlobalID* masterNodeIDs,
00125                          const int* masterFieldIDs,
00126                          const double* weights,
00127                          double rhsValue);
00128 
00129    int deleteMultCRs();
00130 
00131    int initSharedNodes(int numSharedNodes,
00132                        const GlobalID *sharedNodeIDs,  
00133                        const int* numProcsPerNode, 
00134                        const int *const *sharingProcIDs);
00135 
00136    int initCRMult(int numCRNodes,
00137                   const GlobalID* CRNodeIDs,
00138                   const int *CRFieldIDs,
00139                   int& CRID); 
00140 
00141    int initCRPen(int numCRNodes,
00142                  const GlobalID* CRNodeIDs, 
00143                  const int *CRFieldIDs,
00144                  int& CRID); 
00145 
00147    int initComplete();
00148 
00149    int setCurrentMatrix(int matrixID);
00150 
00151    int setCurrentRHS(int rhsID);
00152 
00153    int resetSystem(double s=0.0);
00154 
00155    int resetMatrix(double s=0.0);
00156 
00157    int resetRHSVector(double s=0.0);
00158 
00159   int resetInitialGuess(double s=0.0);
00160 
00161     int loadNodeBCs(int numNodes,
00162                     const GlobalID *nodeIDs,
00163                     int fieldID,
00164                     const int* offsetsIntoField,
00165                     const double* prescribedValues);
00166 
00167     int loadElemBCs(int numElems,
00168                     const GlobalID* elemIDs,  
00169                     int fieldID,
00170                     const double *const *alpha,  
00171                     const double *const *beta,  
00172                     const double *const *gamma);
00173 
00174    int sumInElem(GlobalID elemBlockID,
00175                  GlobalID elemID,
00176                  const GlobalID* elemConn,
00177                  const double* const* elemStiffness,
00178                  const double* elemLoad,
00179                  int elemFormat);
00180 
00181    int sumInElemMatrix(GlobalID elemBlockID,
00182                        GlobalID elemID,
00183                        const GlobalID* elemConn,
00184                        const double* const* elemStiffness,
00185                        int elemFormat);
00186 
00187    int sumInElemRHS(GlobalID elemBlockID,
00188                     GlobalID elemID,
00189                     const GlobalID* elemConn,
00190                     const double* elemLoad);
00191 
00192    int loadCRMult(int CRMultID,
00193                   int numCRNodes,
00194                   const GlobalID* CRNodeIDs,
00195                   const int* CRFieldIDs,
00196                   const double* CRWeights,
00197                   double CRValue);
00198 
00199    int loadCRPen(int CRPenID,
00200                  int numCRNodes,
00201                  const GlobalID* CRNodeIDs,
00202                  const int* CRFieldIDs,
00203                  const double* CRWeights,
00204                  double CRValue,
00205                  double penValue);
00206 
00209    int putIntoRHS(int IDType,
00210                   int fieldID,
00211                   int numIDs,
00212                   const GlobalID* IDs,
00213                   const double* coefficients);
00214 
00217    int sumIntoRHS(int IDType,
00218                   int fieldID,
00219                   int numIDs,
00220                   const GlobalID* IDs,
00221                   const double* coefficients);
00222 
00223    int setMatScalars(int numScalars,
00224                      const int* IDs, 
00225                      const double* scalars);
00226 
00227    int setRHSScalars(int numScalars,
00228                      const int* IDs,
00229                      const double* scalars);
00230 
00231    int loadComplete(bool applyBCs=true,
00232                     bool globalAssemble=true);
00233 
00235    int residualNorm(int whichNorm,
00236                     int numFields,
00237                     int* fieldIDs,
00238                     double* norms);
00239 
00241    int solve(int& status);
00242 
00246    int iterations(int& itersTaken) const;
00247 
00248    int version(const char*& versionString);
00249 
00251    int cumulative_cpu_times(double& initTime,
00252                             double& loadTime,
00253                             double& solveTime,
00254                             double& solnReturnTime);
00255 
00257     int getBlockNodeSolution(GlobalID elemBlockID,  
00258                              int numNodes, 
00259                              const GlobalID *nodeIDs, 
00260                              int *offsets,
00261                              double *results);
00262 
00264     int getNodalSolution(int numNodes,
00265                          const GlobalID* nodeIDs,
00266                          int* offsets,
00267                          double* results);
00268 
00270     int getBlockFieldNodeSolution(GlobalID elemBlockID,
00271                                   int fieldID,
00272                                   int numNodes, 
00273                                   const GlobalID *nodeIDs, 
00274                                   double *results);
00275          
00277     int getBlockElemSolution(GlobalID elemBlockID,  
00278                              int numElems, 
00279                              const GlobalID *elemIDs,
00280                              int& numElemDOFPerElement,
00281                              double *results);
00282 
00284    int getNumCRMultipliers(int& numMultCRs);
00285 
00287    int getCRMultIDList(int numMultCRs, int* multIDs);
00288 
00290    int getCRMultipliers(int numCRs,
00291                         const int* CRIDs,
00292                         double *multipliers);
00293 
00294 // associated "puts" paralleling the solution return services.
00295 // 
00296 // the int sizing parameters are passed for error-checking purposes, so
00297 // that the interface implementation can tell if the passed estimate
00298 // vectors make sense -before- an attempt is made to utilize them as
00299 // initial guesses by unpacking them into the solver's native solution
00300 // vector format (these parameters include lenNodeIDList, lenElemIDList,
00301 // numElemDOF, and numMultCRs -- all other passed params are either 
00302 // vectors or block/constraint-set IDs)
00303 
00305     int putBlockNodeSolution(GlobalID elemBlockID, 
00306                              int numNodes, 
00307                              const GlobalID *nodeIDs, 
00308                              const int *offsets,
00309                              const double *estimates);
00310 
00312     int putBlockFieldNodeSolution(GlobalID elemBlockID, 
00313                                   int fieldID, 
00314                                   int numNodes, 
00315                                   const GlobalID *nodeIDs, 
00316                                   const double *estimates);
00317          
00319     int putBlockElemSolution(GlobalID elemBlockID,  
00320                              int numElems, 
00321                              const GlobalID *elemIDs, 
00322                              int dofPerElem,
00323                              const double *estimates);
00324 
00326     int putCRMultipliers(int numMultCRs, 
00327                          const int* CRIDs,
00328                          const double* multEstimates);
00329 
00330 // utility functions that aid in integrating the FEI calls..............
00331 
00332 // support methods for the "gets" and "puts" of the soln services.
00333 
00334 
00336     int getBlockNodeIDList(GlobalID elemBlockID,
00337                            int numNodes,
00338                            GlobalID *nodeIDs);
00339 
00341    int getBlockElemIDList(GlobalID elemBlockID, 
00342                           int numElems, 
00343                           GlobalID* elemIDs);
00344  
00345 // miscellaneous self-explanatory "read-only" query functions............ 
00346  
00348     int getNumSolnParams(GlobalID nodeID, int& numSolnParams) const;
00349 
00351     int getNumElemBlocks(int& numElemBlocks) const;
00352 
00354     int getNumBlockActNodes(GlobalID blockID, int& numNodes) const;
00355 
00357     int getNumBlockActEqns(GlobalID blockID, int& numEqns) const;
00358 
00361     int getNumNodesPerElement(GlobalID blockID, int& nodesPerElem) const;
00362     
00365     int getNumEqnsPerElement(GlobalID blockID, int& numEqns) const;
00366 
00368     int getNumBlockElements(GlobalID blockID, int& numElems) const;
00369 
00371     int getNumBlockElemDOF(GlobalID blockID, int& DOFPerElem) const;
00372 
00373 
00377     int getParameters(int& numParams, char**& paramStrings);
00378 
00379     //And now a couple of non-FEI query functions that Sandia applications
00380     //need to augment the matrix-access functions. I (Alan Williams) will
00381     //argue to have these included in the FEI 2.1 specification update.
00382 
00387     int getFieldSize(int fieldID, int& numScalars);
00388 
00401     int getEqnNumbers(GlobalID ID,
00402                       int idType, 
00403                       int fieldID,
00404                       int& numEqns,
00405                       int* eqnNumbers);
00406 
00420     int getNodalFieldSolution(int fieldID,
00421                               int numNodes,
00422                               const GlobalID* nodeIDs,
00423                               double* results);
00424 
00430     int getNumLocalNodes(int& numNodes);
00431 
00443     int getLocalNodeIDList(int& numNodes,
00444                            GlobalID* nodeIDs,
00445                            int lenNodeIDs);
00446 
00463     int putNodalFieldData(int fieldID,
00464                           int numNodes,
00465                           const GlobalID* nodeIDs,
00466                           const double* nodeData);
00467 
00468   private: //methods
00469     void basic_initializations();
00470 
00471     int inputRHS(int IDType,
00472                  int fieldID,
00473                  int numIDs,
00474                  const GlobalID* IDs,
00475                  const double* rhsEntries,
00476                  bool sumInto);
00477 
00478     int fillNodeset(int blockID) const;
00479 
00480     int aggregateSystem();
00481 
00482     int aggregateSystem_LinSysCore();
00483 
00484   private: //attributes
00485 
00486     std::vector<fei::SharedPtr<LibraryWrapper> > wrapper_;
00487 
00488     int nodeIDType_;
00489     int elemIDType_;
00490     int constraintIDType_;
00491 
00492     std::vector<fei::SharedPtr<fei::Factory> > factory_;
00493     bool createdFactory_;
00494     fei::SharedPtr<fei::VectorSpace> rowSpace_;
00495     fei::SharedPtr<fei::MatrixGraph> matGraph_;
00496 
00497     fei::SharedPtr<fei::Vector> x_;
00498     std::vector<fei::SharedPtr<fei::Vector> > b_;
00499     std::vector<fei::SharedPtr<fei::Matrix> > A_;
00500     fei::SharedPtr<fei::LinearSystem> linSys_;
00501 
00502     bool newData_;
00503 
00504     Data *soln_fei_matrix_;
00505     Data *soln_fei_vector_;
00506 
00507     MPI_Comm comm_;
00508     int masterRank_;
00509     int localProc_;
00510     int numProcs_;
00511 
00512     int numParams_;
00513     char** paramStrings_;
00514 
00515     std::vector<int> matrixIDs_;
00516     std::vector<int> rhsIDs_;
00517 
00518     std::vector<double> matScalars_;
00519     bool matScalarsSet_;
00520     std::vector<double> rhsScalars_;
00521     bool rhsScalarsSet_;
00522 
00523     int constraintID_;
00524 
00525     int index_soln_;
00526     int index_current_;
00527     int index_current_rhs_row_;
00528 
00529     int solveType_;
00530     int iterations_;
00531 
00532     bool setSolveTypeCalled_;
00533     bool initPhaseIsComplete_;
00534 
00535     bool aggregateSystemFormed_;
00536     int newMatrixDataLoaded_;
00537 
00538     int solveCounter_;
00539 
00540     double initTime_, loadTime_, solveTime_, solnReturnTime_;
00541 
00542     std::vector<int> iwork_;
00543 
00544     mutable std::set<int> nodeset_;
00545     mutable bool nodeset_filled_;
00546     mutable int nodeset_blockid_;
00547 
00548     mutable std::map<int,int> block_dof_per_elem_;
00549     bool any_blocks_have_elem_dof_;
00550   };//class FEI_Impl
00551 
00552 }//namespace fei
00553 
00554 #endif
00555 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends