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 nodeType = 0;
00124       snl_fei::RecordCollection* nodeRecords = NULL;
00125       vspace->getRecordCollection(nodeType, nodeRecords);
00126 
00127       int* intData = new int[numElemBlocks*3];
00128       int* numElemsPerBlock =       intData;
00129       int* numNodesPerElem =        intData+numElemBlocks;
00130       int* elemMatrixSizePerBlock = intData+2*numElemBlocks;
00131       int i;
00132 
00133       std::vector<int> elemBlockIDs;
00134       CHK_ERR( matrixGraph_->getConnectivityBlockIDs( elemBlockIDs) );
00135 
00136       for(i=0; i<numElemBlocks; ++i) {
00137         const fei::ConnectivityBlock* cblock =
00138           matrixGraph_->getConnectivityBlock(elemBlockIDs[i]);
00139         if (cblock==NULL) return(-1);
00140         numElemsPerBlock[i] = cblock->getConnectivityIDs().size();
00141         numNodesPerElem[i] = cblock->getRowPattern()->getNumIDs();
00142         elemMatrixSizePerBlock[i] = cblock->getRowPattern()->getNumIndices();
00143       }
00144 
00145       int numSharedNodes = 0;
00146       CHK_ERR( vspace->getNumSharedIDs(nodeIDType_, numSharedNodes) );
00147 
00148       int numLagrangeConstraints = matrixGraph_->getLocalNumLagrangeConstraints();
00149 
00150       CHK_ERR( feData_->describeStructure(numElemBlocks,
00151             numElemsPerBlock,
00152             numNodesPerElem,
00153             elemMatrixSizePerBlock,
00154             numLocalNodes,
00155             numSharedNodes,
00156             numLagrangeConstraints) );
00157 
00158       std::map<int,fei::ConnectivityBlock*>::const_iterator
00159         cdb_iter = matrixGraph_->getConnectivityBlocks().begin();
00160 
00161       std::vector<int> nodeNumbers, numDofPerNode, dof_ids;
00162       int total_num_dof = 0;
00163       for(i=0; i<numElemBlocks; ++i, ++cdb_iter) {
00164         fei::ConnectivityBlock* cblock = (*cdb_iter).second;
00165         fei::Pattern* pattern = cblock->getRowPattern();
00166 
00167         int numConnectedNodes = pattern->getNumIDs();
00168         nodeNumbers.resize(numConnectedNodes);
00169         numDofPerNode.resize(numConnectedNodes);
00170         int* nodeNumPtr = &nodeNumbers[0];
00171         int* numDofPtr = &numDofPerNode[0];
00172 
00173         //For the calls to FiniteElementData::setConnectivity, we're going to
00174         //need a list of num-dof-per-node. So construct that now.
00175         const int* numFieldsPerID = pattern->getNumFieldsPerID();
00176         const int* fieldIDs = pattern->getFieldIDs();
00177 
00178         int foffset = 0;
00179         for(int ii=0; ii<numConnectedNodes; ++ii) {
00180           int dof = 0;
00181           for(int f=0; f<numFieldsPerID[ii]; ++f) {
00182             dof += vspace->getFieldSize(fieldIDs[foffset++]);
00183           }
00184           numDofPtr[ii] = dof;
00185           total_num_dof += dof;
00186         }
00187 
00188         dof_ids.resize(total_num_dof, 0);
00189         int* dof_ids_ptr = &dof_ids[0];
00190 
00192         //Next we'll loop over the connectivity-lists in this block,
00193         //making a call to FiniteElementData::setConnectivity for each one.
00194 
00195         std::map<int,int>& elemIDs = cblock->getConnectivityIDs();
00196         int numElems = elemIDs.size();
00197         int* nodes = &(cblock->getRowConnectivities()[0]);
00198 
00199         int offset = 0;
00200         for(int elem=0; elem<numElems; ++elem) {
00201           for(int n=0; n<numConnectedNodes; ++n) {
00202             fei::Record<int>* node = nodeRecords->getRecordWithLocalID(nodes[offset++]);
00203             nodeNumPtr[n] = node->getNumber();
00204           }
00205 
00206           CHK_ERR( feData_->setConnectivity(elemBlockIDs[i], elem,
00207                 numConnectedNodes,
00208                 nodeNumPtr, numDofPtr, dof_ids_ptr));
00209         }//end for(...numElems...)
00210       }//end for(...numElemBlocks...)
00211 
00212       delete [] intData;
00213 
00214       setStructure_ = true;
00215       return(0);
00216     }
00217 
00218     fei::SharedPtr<FiniteElementData> feData_;
00219     fei::SharedPtr<fei::MatrixGraph> matrixGraph_;
00220 
00221     int nodeIDType_;
00222     bool setStructure_;
00223     bool setMatrixMatrixGraph_;
00224 
00225     fei::Lookup_Impl* lookup_;
00226   };//class Broker_FEData
00227 }//namespace snl_fei
00228 
00229 
00230 #endif // _snl_fei_Broker_FEData_hpp_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends