FEI Version of the Day
snl_fei_Broker_FEData.hpp
00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #ifndef _snl_fei_Broker_FEData_hpp_
00010 #define _snl_fei_Broker_FEData_hpp_
00011 
00012 #include <fei_macros.hpp>
00013 #include <fei_mpi.h>
00014 #include <snl_fei_Broker.hpp>
00015 #include <fei_FiniteElementData.hpp>
00016 #include <fei_VectorSpace.hpp>
00017 #include <fei_MatrixGraph.hpp>
00018 #include <fei_Matrix_Impl.hpp>
00019 #include <fei_Pattern.hpp>
00020 #include <fei_Vector_Impl.hpp>
00021 #include <fei_ConnectivityBlock.hpp>
00022 #include <snl_fei_LinearSystem_FEData.hpp>
00023 #include <fei_Lookup_Impl.hpp>
00024 
00025 #undef fei_file
00026 #define fei_file "snl_fei_Broker_FEData.hpp"
00027 #include <fei_ErrMacros.hpp>
00028 
00029 namespace snl_fei {
00030 
00034   class Broker_FEData : public snl_fei::Broker {
00035   public:
00037     Broker_FEData(fei::SharedPtr<FiniteElementData> feData,
00038       fei::SharedPtr<fei::MatrixGraph> matrixGraph,
00039       int nodeIDType);
00040 
00042     virtual ~Broker_FEData();
00043 
00053     virtual fei::SharedPtr<fei::Vector> createVector(bool isSolutionVector=false)
00054       {
00055   fei::SharedPtr<fei::Vector> vptr;
00056   if (matrixGraph_.get() == NULL) return(vptr);
00057 
00058   if (setStructure() != 0) return(vptr);
00059 
00060         int localsize = matrixGraph_->getRowSpace()->getNumIndices_Owned();
00061   fei::SharedPtr<fei::Vector> vecptr;
00062         vecptr.reset(new fei::Vector_Impl<FiniteElementData>(matrixGraph_->getRowSpace(),
00063                                                    feData_.get(), localsize,
00064                                                     isSolutionVector));
00065   return(vecptr);
00066       }
00067 
00070     virtual fei::SharedPtr<fei::Matrix> createMatrix()
00071       {
00072   fei::SharedPtr<fei::Matrix> mptr;
00073   if (matrixGraph_.get() == NULL) return(mptr);
00074 
00075   if (setStructure() != 0) return(mptr);
00076         int localsize = matrixGraph_->getRowSpace()->getNumIndices_Owned();
00077 
00078   fei::SharedPtr<fei::Matrix> matptr;
00079         matptr.reset(new fei::Matrix_Impl<FiniteElementData>(feData_,
00080                  matrixGraph_, localsize));
00081   return(matptr);
00082       }
00083 
00086     virtual fei::SharedPtr<fei::LinearSystem> createLinearSystem()
00087       {
00088   fei::SharedPtr<fei::LinearSystem> lsptr;
00089   if (matrixGraph_.get() == NULL) return(lsptr);
00090 
00091   if (setStructure() != 0) return(lsptr);
00092 
00093   snl_fei::LinearSystem_FEData*
00094     linsysfed = new LinearSystem_FEData(feData_,
00095                 matrixGraph_);
00096   linsysfed->setLookup(lookup_);
00097   fei::SharedPtr<fei::LinearSystem> linsysptr(linsysfed);
00098   return(linsysptr);
00099       }
00100 
00102     virtual void setMatrixGraph(fei::SharedPtr<fei::MatrixGraph> matrixGraph)
00103     {
00104       matrixGraph_ = matrixGraph;
00105     }
00106 
00107   private:
00108     int setStructure()
00109     {
00110       if (matrixGraph_.get() == NULL) ERReturn(-1);
00111       if (setStructure_ == true) return(0);
00112 
00113       lookup_ = new fei::Lookup_Impl(matrixGraph_, nodeIDType_);
00114 
00115       CHK_ERR( feData_->setLookup(*lookup_) );
00116 
00117       fei::SharedPtr<fei::VectorSpace> vspace = matrixGraph_->getRowSpace();
00118 
00119       int numLocalNodes = vspace->getNumOwnedAndSharedIDs(nodeIDType_);
00120 
00121       int numElemBlocks = matrixGraph_->getNumConnectivityBlocks();
00122 
00123       int* intData = new int[numElemBlocks*3];
00124       int* numElemsPerBlock =       intData;
00125       int* numNodesPerElem =        intData+numElemBlocks;
00126       int* elemMatrixSizePerBlock = intData+2*numElemBlocks;
00127       int i;
00128 
00129       std::vector<int> elemBlockIDs;
00130       CHK_ERR( matrixGraph_->getConnectivityBlockIDs( elemBlockIDs) );
00131 
00132       for(i=0; i<numElemBlocks; ++i) {
00133         const fei::ConnectivityBlock* cblock =
00134           matrixGraph_->getConnectivityBlock(elemBlockIDs[i]);
00135         if (cblock==NULL) return(-1);
00136         numElemsPerBlock[i] = cblock->getConnectivityIDs().size();
00137         numNodesPerElem[i] = cblock->getRowPattern()->getNumIDs();
00138         elemMatrixSizePerBlock[i] = cblock->getRowPattern()->getNumIndices();
00139       }
00140 
00141       int numSharedNodes = 0;
00142       CHK_ERR( vspace->getNumSharedIDs(nodeIDType_, numSharedNodes) );
00143 
00144       int numLagrangeConstraints = matrixGraph_->getLocalNumLagrangeConstraints();
00145 
00146       CHK_ERR( feData_->describeStructure(numElemBlocks,
00147             numElemsPerBlock,
00148             numNodesPerElem,
00149             elemMatrixSizePerBlock,
00150             numLocalNodes,
00151             numSharedNodes,
00152             numLagrangeConstraints) );
00153 
00154       std::map<int,fei::ConnectivityBlock*>::const_iterator
00155         cdb_iter = matrixGraph_->getConnectivityBlocks().begin();
00156 
00157       std::vector<int> nodeNumbers, numDofPerNode, dof_ids;
00158       int total_num_dof = 0;
00159       for(i=0; i<numElemBlocks; ++i, ++cdb_iter) {
00160         fei::ConnectivityBlock* cblock = (*cdb_iter).second;
00161         fei::Pattern* pattern = cblock->getRowPattern();
00162 
00163         int numConnectedNodes = pattern->getNumIDs();
00164         nodeNumbers.resize(numConnectedNodes);
00165         numDofPerNode.resize(numConnectedNodes);
00166         int* nodeNumPtr = &nodeNumbers[0];
00167         int* numDofPtr = &numDofPerNode[0];
00168 
00169         //For the calls to FiniteElementData::setConnectivity, we're going to
00170         //need a list of num-dof-per-node. So construct that now.
00171         const int* numFieldsPerID = pattern->getNumFieldsPerID();
00172         const int* fieldIDs = pattern->getFieldIDs();
00173 
00174         int foffset = 0;
00175         for(int ii=0; ii<numConnectedNodes; ++ii) {
00176           int dof = 0;
00177           for(int f=0; f<numFieldsPerID[ii]; ++f) {
00178             dof += vspace->getFieldSize(fieldIDs[foffset++]);
00179           }
00180           numDofPtr[ii] = dof;
00181           total_num_dof += dof;
00182         }
00183 
00184         dof_ids.resize(total_num_dof, 0);
00185         int* dof_ids_ptr = &dof_ids[0];
00186 
00188         //Next we'll loop over the connectivity-lists in this block,
00189         //making a call to FiniteElementData::setConnectivity for each one.
00190 
00191         std::map<int,int>& elemIDs = cblock->getConnectivityIDs();
00192         int numElems = elemIDs.size();
00193         fei::Record<int>** nodes = &(cblock->getRowConnectivities()[0]);
00194 
00195         int offset = 0;
00196         for(int elem=0; elem<numElems; ++elem) {
00197           for(int n=0; n<numConnectedNodes; ++n) {
00198             fei::Record<int>* node = nodes[offset++];
00199             nodeNumPtr[n] = node->getNumber();
00200           }
00201 
00202           CHK_ERR( feData_->setConnectivity(elemBlockIDs[i], elem,
00203                 numConnectedNodes,
00204                 nodeNumPtr, numDofPtr, dof_ids_ptr));
00205         }//end for(...numElems...)
00206       }//end for(...numElemBlocks...)
00207 
00208       delete [] intData;
00209 
00210       setStructure_ = true;
00211       return(0);
00212     }
00213 
00214     fei::SharedPtr<FiniteElementData> feData_;
00215     fei::SharedPtr<fei::MatrixGraph> matrixGraph_;
00216 
00217     int nodeIDType_;
00218     bool setStructure_;
00219     bool setMatrixMatrixGraph_;
00220 
00221     fei::Lookup_Impl* lookup_;
00222   };//class Broker_FEData
00223 }//namespace snl_fei
00224 
00225 
00226 #endif // _snl_fei_Broker_FEData_hpp_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends