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;
00158 
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     }
00182 
00184     //Next we'll loop over the connectivity-lists in this block,
00185     //making a call to FiniteElementData::setConnectivity for each one.
00186 
00187     std::map<int,int>& elemIDs = cblock->getConnectivityIDs();
00188     int numElems = elemIDs.size();
00189     fei::Record<int>** nodes = &(cblock->getRowConnectivities()[0]);
00190 
00191     int offset = 0;
00192     for(int elem=0; elem<numElems; ++elem) {
00193       for(int n=0; n<numConnectedNodes; ++n) {
00194         fei::Record<int>* node = nodes[offset++];
00195         nodeNumPtr[n] = node->getNumber();
00196       }
00197 
00198       CHK_ERR( feData_->setConnectivity(elemBlockIDs[i], elem,
00199                 numConnectedNodes,
00200                 nodeNumPtr, numDofPtr));
00201     }//end for(...numElems...)
00202   }//end for(...numElemBlocks...)
00203 
00204   delete [] intData;
00205 
00206   setStructure_ = true;
00207   return(0);
00208       }
00209 
00210     fei::SharedPtr<FiniteElementData> feData_;
00211     fei::SharedPtr<fei::MatrixGraph> matrixGraph_;
00212 
00213     int nodeIDType_;
00214     bool setStructure_;
00215     bool setMatrixMatrixGraph_;
00216 
00217     fei::Lookup_Impl* lookup_;
00218   };//class Broker_FEData
00219 }//namespace snl_fei
00220 
00221 
00222 #endif // _snl_fei_Broker_FEData_hpp_

Generated on Tue Jul 13 09:27:46 2010 for FEI by  doxygen 1.4.7