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       bool zeroSharedRows = false;
00079       fei::SharedPtr<fei::Matrix> matptr;
00080       matptr.reset(new fei::Matrix_Impl<FiniteElementData>(feData_,
00081             matrixGraph_, localsize, zeroSharedRows));
00082       return(matptr);
00083     }
00084 
00087     virtual fei::SharedPtr<fei::LinearSystem> createLinearSystem()
00088       {
00089   fei::SharedPtr<fei::LinearSystem> lsptr;
00090   if (matrixGraph_.get() == NULL) return(lsptr);
00091 
00092   if (setStructure() != 0) return(lsptr);
00093 
00094   snl_fei::LinearSystem_FEData*
00095     linsysfed = new LinearSystem_FEData(feData_,
00096                 matrixGraph_);
00097   linsysfed->setLookup(lookup_);
00098   fei::SharedPtr<fei::LinearSystem> linsysptr(linsysfed);
00099   return(linsysptr);
00100       }
00101 
00103     virtual void setMatrixGraph(fei::SharedPtr<fei::MatrixGraph> matrixGraph)
00104     {
00105       matrixGraph_ = matrixGraph;
00106     }
00107 
00108   private:
00109     int setStructure()
00110     {
00111       if (matrixGraph_.get() == NULL) ERReturn(-1);
00112       if (setStructure_ == true) return(0);
00113 
00114       lookup_ = new fei::Lookup_Impl(matrixGraph_, nodeIDType_);
00115 
00116       CHK_ERR( feData_->setLookup(*lookup_) );
00117 
00118       fei::SharedPtr<fei::VectorSpace> vspace = matrixGraph_->getRowSpace();
00119 
00120       int numLocalNodes = vspace->getNumOwnedAndSharedIDs(nodeIDType_);
00121 
00122       int numElemBlocks = matrixGraph_->getNumConnectivityBlocks();
00123 
00124       int nodeType = 0;
00125       snl_fei::RecordCollection* nodeRecords = NULL;
00126       vspace->getRecordCollection(nodeType, nodeRecords);
00127 
00128       int* intData = new int[numElemBlocks*3];
00129       int* numElemsPerBlock =       intData;
00130       int* numNodesPerElem =        intData+numElemBlocks;
00131       int* elemMatrixSizePerBlock = intData+2*numElemBlocks;
00132       int i;
00133 
00134       std::vector<int> elemBlockIDs;
00135       CHK_ERR( matrixGraph_->getConnectivityBlockIDs( elemBlockIDs) );
00136 
00137       for(i=0; i<numElemBlocks; ++i) {
00138         const fei::ConnectivityBlock* cblock =
00139           matrixGraph_->getConnectivityBlock(elemBlockIDs[i]);
00140         if (cblock==NULL) return(-1);
00141         numElemsPerBlock[i] = cblock->getConnectivityIDs().size();
00142         numNodesPerElem[i] = cblock->getRowPattern()->getNumIDs();
00143         elemMatrixSizePerBlock[i] = cblock->getRowPattern()->getNumIndices();
00144       }
00145 
00146       int numSharedNodes = 0;
00147       CHK_ERR( vspace->getNumSharedIDs(nodeIDType_, numSharedNodes) );
00148 
00149       int numLagrangeConstraints = matrixGraph_->getLocalNumLagrangeConstraints();
00150 
00151       CHK_ERR( feData_->describeStructure(numElemBlocks,
00152             numElemsPerBlock,
00153             numNodesPerElem,
00154             elemMatrixSizePerBlock,
00155             numLocalNodes,
00156             numSharedNodes,
00157             numLagrangeConstraints) );
00158 
00159       std::map<int,fei::ConnectivityBlock*>::const_iterator
00160         cdb_iter = matrixGraph_->getConnectivityBlocks().begin();
00161 
00162       std::vector<int> nodeNumbers, numDofPerNode, dof_ids;
00163       int total_num_dof = 0;
00164       for(i=0; i<numElemBlocks; ++i, ++cdb_iter) {
00165         fei::ConnectivityBlock* cblock = (*cdb_iter).second;
00166         fei::Pattern* pattern = cblock->getRowPattern();
00167 
00168         int numConnectedNodes = pattern->getNumIDs();
00169         nodeNumbers.resize(numConnectedNodes);
00170         numDofPerNode.resize(numConnectedNodes);
00171         int* nodeNumPtr = &nodeNumbers[0];
00172         int* numDofPtr = &numDofPerNode[0];
00173 
00174         //For the calls to FiniteElementData::setConnectivity, we're going to
00175         //need a list of num-dof-per-node. So construct that now.
00176         const int* numFieldsPerID = pattern->getNumFieldsPerID();
00177         const int* fieldIDs = pattern->getFieldIDs();
00178 
00179         int foffset = 0;
00180         for(int ii=0; ii<numConnectedNodes; ++ii) {
00181           int dof = 0;
00182           for(int f=0; f<numFieldsPerID[ii]; ++f) {
00183             dof += vspace->getFieldSize(fieldIDs[foffset++]);
00184           }
00185           numDofPtr[ii] = dof;
00186           total_num_dof += dof;
00187         }
00188 
00189         dof_ids.resize(total_num_dof, 0);
00190         int* dof_ids_ptr = &dof_ids[0];
00191 
00193         //Next we'll loop over the connectivity-lists in this block,
00194         //making a call to FiniteElementData::setConnectivity for each one.
00195 
00196         std::map<int,int>& elemIDs = cblock->getConnectivityIDs();
00197         int numElems = elemIDs.size();
00198         int* nodes = &(cblock->getRowConnectivities()[0]);
00199 
00200         int offset = 0;
00201         for(int elem=0; elem<numElems; ++elem) {
00202           for(int n=0; n<numConnectedNodes; ++n) {
00203             fei::Record<int>* node = nodeRecords->getRecordWithLocalID(nodes[offset++]);
00204             nodeNumPtr[n] = node->getNumber();
00205           }
00206 
00207           CHK_ERR( feData_->setConnectivity(elemBlockIDs[i], elem,
00208                 numConnectedNodes,
00209                 nodeNumPtr, numDofPtr, dof_ids_ptr));
00210         }//end for(...numElems...)
00211       }//end for(...numElemBlocks...)
00212 
00213       delete [] intData;
00214 
00215       setStructure_ = true;
00216       return(0);
00217     }
00218 
00219     fei::SharedPtr<FiniteElementData> feData_;
00220     fei::SharedPtr<fei::MatrixGraph> matrixGraph_;
00221 
00222     int nodeIDType_;
00223     bool setStructure_;
00224     bool setMatrixMatrixGraph_;
00225 
00226     fei::Lookup_Impl* lookup_;
00227   };//class Broker_FEData
00228 }//namespace snl_fei
00229 
00230 
00231 #endif // _snl_fei_Broker_FEData_hpp_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends