FEI Version of the Day
fei_Vector_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_Vector_Impl_hpp_
00045 #define _fei_Vector_Impl_hpp_
00046 
00047 #include <fei_macros.hpp>
00048 #include <fei_VectorTraits.hpp>
00049 
00050 #include <fei_VectorTraits_CSVec.hpp>
00051 #include <fei_VectorTraits_LinSysCore.hpp>
00052 #include <fei_VectorTraits_LinProbMgr.hpp>
00053 #include <fei_VectorTraits_FEData.hpp>
00054 #include <snl_fei_FEVectorTraits.hpp>
00055 #include <snl_fei_FEVectorTraits_FED.hpp>
00056 #include <fei_SharedIDs.hpp>
00057 #include <fei_VectorSpace.hpp>
00058 #include <fei_Reducer.hpp>
00059 #include <fei_Logger.hpp>
00060 #include <fei_Vector.hpp>
00061 #include <fei_Vector_core.hpp>
00062 #include <fei_iosfwd.hpp>
00063 
00064 #undef fei_file
00065 #define fei_file "fei_Vector_Impl.hpp"
00066 
00067 #include <fei_ErrMacros.hpp>
00068 
00069 namespace fei {
00070 
00091   template<typename T>
00092   class Vector_Impl : public fei::Vector, public fei::Vector_core {
00093   public:
00094 
00096     Vector_Impl(fei::SharedPtr<fei::VectorSpace> vecSpace,
00097      T* vector, int numLocalEqns,
00098      bool isSolutionVector=false,
00099            bool deleteVector=false);
00100 
00102     virtual ~Vector_Impl();
00103 
00107     const char* typeName() const { return(fei::VectorTraits<T>::typeName()); }
00108 
00111     int update(double a,
00112          const fei::Vector* x,
00113          double b);
00114 
00121     int scatterToOverlap();
00122 
00123     void setCommSizes();
00124 
00128     int gatherFromOverlap(bool accumulate = true);
00129 
00131     int putScalar(double scalar);
00132 
00136     int sumIn(int numValues, const int* indices, const double* values,
00137         int vectorIndex=0);
00138 
00142     int copyIn(int numValues, const int* indices, const double* values,
00143          int vectorIndex=0);
00144 
00147     fei::SharedPtr<fei::VectorSpace> getVectorSpace() const
00148       { return(get_vector_space()); }
00149 
00152     void setVectorSpace(fei::SharedPtr<fei::VectorSpace> vecSpace)
00153     {
00154       set_vector_space( vecSpace );
00155     }
00156 
00163     int sumInFieldData(int fieldID,
00164            int idType,
00165            int numIDs,
00166            const int* IDs,
00167            const double* data,
00168            int vectorIndex=0);
00169 
00176     int copyInFieldData(int fieldID,
00177       int idType,
00178       int numIDs,
00179       const int* IDs,
00180       const double* data,
00181       int vectorIndex=0);
00182 
00183     int copyInFieldDataLocalIDs(int fieldID,
00184       int idType,
00185       int numIDs,
00186       const int* localIDs,
00187       const double* data,
00188       int vectorIndex=0);
00189 
00196     int copyOutFieldData(int fieldID,
00197        int idType,
00198        int numIDs,
00199        const int* IDs,
00200        double* data,
00201        int vectorIndex=0);
00202 
00203     int writeToFile(const char* filename,
00204         bool matrixMarketFormat=true);
00205 
00206     int writeToStream(FEI_OSTREAM& ostrm,
00207           bool matrixMarketFormat=true);
00208 
00212     void setUnderlyingVector(T* vec)
00213       {
00214   vector_ = vec;
00215       }
00216 
00220     T* getUnderlyingVector() { return( vector_ ); }
00221     const T* getUnderlyingVector() const { return( vector_ ); }
00222 
00223     int copyOut(int numValues,
00224     const int* indices,
00225     double* values,
00226     int vectorIndex=0) const;
00227 
00230     int copyOut_FE(int nodeNumber, int dofOffset, double& value);
00231 
00232   private:
00233     int giveToUnderlyingVector(int numValues,
00234              const int* indices,
00235              const double* values,
00236              bool sumInto=true,
00237              int vectorIndex=0);
00238 
00239     int copyOutOfUnderlyingVector(int numValues,
00240           const int* indices,
00241           double* values,
00242           int vectorIndex=0) const;
00243 
00244     int sumIntoFEVector(int blockID,
00245       int connOffset,
00246       int numNodes,
00247       const int* nodeNumbers,
00248       const int* numIndicesPerNode,
00249       const int* dof_ids,
00250       const double* values);
00251 
00252     T* vector_;
00253     bool isSolution_;
00254     bool deleteVector_;
00255 
00256     int localProc_;
00257     int numProcs_;
00258     std::string dbgprefix_;
00259   };//class Vector_Impl
00260 
00261 } //namespace fei
00262 
00263 //----------------------------------------------------------------------------
00264 template<typename T>
00265 fei::Vector_Impl<T>::Vector_Impl(fei::SharedPtr<fei::VectorSpace> vecSpace,
00266          T* vector, int numLocalEqns,
00267          bool isSolutionVector,
00268                            bool deleteVector)
00269   : Vector_core(vecSpace, numLocalEqns),
00270     vector_(vector),
00271     isSolution_(isSolutionVector),
00272     deleteVector_(deleteVector),
00273     localProc_(0),
00274     numProcs_(1),
00275     dbgprefix_("VecImpl: ")
00276 {
00277   if (strcmp(snl_fei::FEVectorTraits<T>::typeName(), "unsupported")) {
00278     setFEVector(true);
00279   }
00280   else {
00281     setFEVector(false);
00282   }
00283 
00284   localProc_ = fei::localProc(vecSpace->getCommunicator());
00285   numProcs_ = fei::numProcs(vecSpace->getCommunicator());
00286 
00287   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00288     FEI_OSTREAM& os = *output_stream_;
00289     os << dbgprefix_<<" ctor, numLocalEqns="<<numLocalEqns
00290        <<", typeName: "<<typeName()<<FEI_ENDL;
00291   }
00292 
00293   std::vector<int> idTypes;
00294   vecSpace->getIDTypes(idTypes);
00295   std::vector<int> eqns;
00296   std::vector<double> zeros;
00297   for(size_t i=0; i<idTypes.size(); ++i) {
00298     int idType = idTypes[i];
00299     fei::SharedIDs<int>& sharedIDs = vecSpace->getSharedIDs(idType);
00300     const fei::SharedIDs<int>::map_type& idMap = sharedIDs.getSharedIDs();
00301     fei::SharedIDs<int>::map_type::const_iterator
00302       iter = idMap.begin(), iterEnd = idMap.end();
00303     for(; iter!=iterEnd; ++iter) {
00304       int ID = iter->first;
00305       int eqn;
00306       vecSpace->getGlobalIndex(idType, ID, eqn);
00307       int ndof = vecSpace->getNumDegreesOfFreedom(idType, ID);
00308       eqns.resize(ndof);
00309       zeros.resize(ndof, 0.0);
00310       for(int j=0; j<ndof; ++j) eqns[j] = eqn+j;
00311       if (!isSolutionVector) {
00312         sumIn(ndof, &eqns[0], &zeros[0]);
00313       }
00314       else {
00315         copyIn(ndof, &eqns[0], &zeros[0]);
00316       }
00317     }
00318   }
00319 
00320   setCommSizes();
00321   std::vector<CSVec*>& remoteVecs = remotelyOwned();
00322   for(size_t i=0; i<remoteVecs.size(); ++i) {
00323     remoteVecs[i]->clear();
00324   }
00325 }
00326 
00327 //----------------------------------------------------------------------------
00328 template<typename T>
00329 fei::Vector_Impl<T>::~Vector_Impl()
00330 {
00331   if (deleteVector_) delete vector_;
00332 }
00333 
00334 //----------------------------------------------------------------------------
00335 template<typename T>
00336 int fei::Vector_Impl<T>::putScalar(double scalar)
00337 {
00338   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00339     FEI_OSTREAM& os = *output_stream_;
00340     os << dbgprefix_<<"putScalar("<<scalar<<")"<<FEI_ENDL;
00341   }
00342 
00343   if (haveFEVector()) {
00344     if (scalar != 0.0) return(-1);
00345     CHK_ERR( snl_fei::FEVectorTraits<T>::reset(vector_) );
00346   }
00347   else {
00348     CHK_ERR( fei::VectorTraits<T>::setValues(vector_, firstLocalOffset(), scalar) );
00349   }
00350   for(unsigned p=0; p<remotelyOwned().size(); ++p) {
00351     fei::set_values(*(remotelyOwned()[p]), scalar);
00352   }
00353   return(0);
00354 }
00355 
00356 //----------------------------------------------------------------------------
00357 template<typename T>
00358 int fei::Vector_Impl<T>::update(double a,
00359              const fei::Vector* x,
00360              double b)
00361 {
00362   const fei::Vector_Impl<T>* sx = dynamic_cast<const fei::Vector_Impl<T>* >(x);
00363   if (sx != 0) {
00364     const T* tx = sx->getUnderlyingVector();
00365     return( fei::VectorTraits<T>::update(vector_, a, tx, b) );
00366   }
00367   else {
00368     return( -1 );
00369   }
00370 }
00371 
00372 //----------------------------------------------------------------------------
00373 template<typename T>
00374 int fei::Vector_Impl<T>::scatterToOverlap()
00375 {
00376   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00377     FEI_OSTREAM& os = *output_stream_;
00378     os << dbgprefix_<<"scatterToOverlap"<<FEI_ENDL;
00379   }
00380 
00381   return( Vector_core::scatterToOverlap() );
00382 }
00383 
00384 //----------------------------------------------------------------------------
00385 template<typename T>
00386 void fei::Vector_Impl<T>::setCommSizes()
00387 {
00388   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00389     FEI_OSTREAM& os = *output_stream_;
00390     os << dbgprefix_<<"setCommSizes"<<FEI_ENDL;
00391   }
00392 
00393   Vector_core::setCommSizes();
00394 }
00395 
00396 //----------------------------------------------------------------------------
00397 template<typename T>
00398 int fei::Vector_Impl<T>::gatherFromOverlap(bool accumulate)
00399 {
00400   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00401     FEI_OSTREAM& os = *output_stream_;
00402     os << dbgprefix_<<"gatherFromOverlap"<<FEI_ENDL;
00403   }
00404 
00405   return( Vector_core::gatherFromOverlap(accumulate) );
00406 }
00407 
00408 //----------------------------------------------------------------------------
00409 template<typename T>
00410 int fei::Vector_Impl<T>::sumIn(int numValues,
00411             const int* indices, const double* values,
00412             int vectorIndex)
00413 {
00414   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00415     FEI_OSTREAM& os = *output_stream_;
00416     os << dbgprefix_<<"sumIn(n="<<numValues<<")"<<FEI_ENDL;
00417   }
00418 
00419   return( giveToVector(numValues, indices, values, true, vectorIndex) );
00420 }
00421 
00422 //----------------------------------------------------------------------------
00423 template<typename T>
00424 int fei::Vector_Impl<T>::copyIn(int numValues,
00425              const int* indices, const double* values,
00426              int vectorIndex)
00427 {
00428   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00429     FEI_OSTREAM& os = *output_stream_;
00430     os << dbgprefix_<<"copyIn(n="<<numValues<<")"<<FEI_ENDL;
00431   }
00432 
00433   return( giveToVector(numValues, indices, values, false, vectorIndex) );
00434 }
00435 
00436 //----------------------------------------------------------------------------
00437 template<typename T>
00438 int fei::Vector_Impl<T>::giveToUnderlyingVector(int numValues,
00439                  const int* indices,
00440                  const double* values,
00441                  bool sumInto,
00442                  int vectorIndex)
00443 {
00444   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00445     FEI_OSTREAM& os = *output_stream_;
00446     os << dbgprefix_<<"giveToUnderlying(";
00447     for(int i=0; i<numValues; ++i) {
00448       os << "{"<<indices[i]<<","<<values[i]<<"} ";
00449     }
00450     os<<")"<<FEI_ENDL;
00451   }
00452 
00453   int err = fei::VectorTraits<T>::putValuesIn(vector_, firstLocalOffset(),
00454                numValues, indices, values,
00455                sumInto, isSolution_, vectorIndex);
00456   if (err < 0) {
00457     return(err);
00458   }
00459   return(0);
00460 }
00461 
00462 //----------------------------------------------------------------------------
00463 template<typename T>
00464 int fei::Vector_Impl<T>::copyOutOfUnderlyingVector(int numValues,
00465               const int* indices,
00466               double* values,
00467               int vectorIndex) const
00468 {
00469   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00470     FEI_OSTREAM& os = *output_stream_;
00471     os << dbgprefix_<<"copyOutOfUnderlying(n="<<numValues<<")"<<FEI_ENDL;
00472   }
00473 
00474   return( fei::VectorTraits<T>::copyOut(vector_, firstLocalOffset(),
00475                numValues, indices, values,
00476                isSolution_, vectorIndex) );
00477 }
00478 
00479 //----------------------------------------------------------------------------
00480 template<typename T>
00481 int fei::Vector_Impl<T>::sumInFieldData(int fieldID,
00482                int idType,
00483                int numIDs,
00484                const int* IDs,
00485                const double* data,
00486                int vectorIndex)
00487 {
00488   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00489     FEI_OSTREAM& os = *output_stream_;
00490     os << dbgprefix_<<"sumInFieldData(n="<<numIDs<<")"<<FEI_ENDL;
00491   }
00492 
00493   return( assembleFieldData(fieldID, idType, numIDs, IDs, data, true, vectorIndex));
00494 }
00495 
00496 //----------------------------------------------------------------------------
00497 template<typename T>
00498 int fei::Vector_Impl<T>::copyInFieldData(int fieldID,
00499           int idType,
00500           int numIDs,
00501           const int* IDs,
00502           const double* data,
00503           int vectorIndex)
00504 {
00505   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00506     FEI_OSTREAM& os = *output_stream_;
00507     os << dbgprefix_<<"copyInFieldData(n="<<numIDs<<")"<<FEI_ENDL;
00508   }
00509 
00510   return(assembleFieldData(fieldID, idType, numIDs, IDs, data, false, vectorIndex));
00511 }
00512 
00513 //----------------------------------------------------------------------------
00514 template<typename T>
00515 int fei::Vector_Impl<T>::copyInFieldDataLocalIDs(int fieldID,
00516           int idType,
00517           int numIDs,
00518           const int* localIDs,
00519           const double* data,
00520           int vectorIndex)
00521 {
00522   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00523     FEI_OSTREAM& os = *output_stream_;
00524     os << dbgprefix_<<"copyInFieldDataLocalIDs(n="<<numIDs<<")"<<FEI_ENDL;
00525   }
00526 
00527   return(assembleFieldDataLocalIDs(fieldID, idType, numIDs, localIDs, data, false, vectorIndex));
00528 }
00529 
00530 //----------------------------------------------------------------------------
00531 template<typename T>
00532 int fei::Vector_Impl<T>::copyOut_FE(int nodeNumber, int dofOffset, double& value)
00533 {
00534   return( snl_fei::FEVectorTraits<T>::copyOut(vector_, nodeNumber, dofOffset, value) );
00535 }
00536 
00537 //----------------------------------------------------------------------------
00538 template<typename T>
00539 int fei::Vector_Impl<T>::copyOutFieldData(int fieldID,
00540            int idType,
00541            int numIDs,
00542            const int* IDs,
00543            double* data,
00544            int vectorIndex)
00545 {
00546   return( Vector_core::copyOutFieldData(fieldID, idType, numIDs, IDs, data,
00547            vectorIndex));
00548 }
00549 
00550 //----------------------------------------------------------------------------
00551 template<typename T>
00552 int fei::Vector_Impl<T>::writeToFile(const char* filename,
00553             bool matrixMarketFormat)
00554 {
00555   return( Vector_core::writeToFile(filename, matrixMarketFormat) );
00556 }
00557 
00558 //----------------------------------------------------------------------------
00559 template<typename T>
00560 int fei::Vector_Impl<T>::writeToStream(FEI_OSTREAM& ostrm,
00561               bool matrixMarketFormat)
00562 {
00563   return( Vector_core::writeToStream(ostrm, matrixMarketFormat) );
00564 }
00565 
00566 //----------------------------------------------------------------------------
00567 template<typename T>
00568 int fei::Vector_Impl<T>::copyOut(int numValues,
00569         const int* indices,
00570         double* values,
00571         int vectorIndex) const
00572 {
00573   if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
00574     FEI_OSTREAM& os = *output_stream_;
00575     os << dbgprefix_<<"copyOut(n="<<numValues<<")"<<FEI_ENDL;
00576   }
00577 
00578   return( Vector_core::copyOut(numValues, indices, values, vectorIndex) );
00579 }
00580 
00581 //----------------------------------------------------------------------------
00582 template<typename T>
00583 int fei::Vector_Impl<T>::sumIntoFEVector(int blockID,
00584           int connOffset,
00585           int numNodes,
00586           const int* nodeNumbers,
00587           const int* numIndicesPerNode,
00588           const int* dof_ids,
00589           const double* values)
00590 {
00591   return( snl_fei::FEVectorTraits<T>::sumInElemVector(vector_, blockID, connOffset,
00592                 numNodes, nodeNumbers,
00593                 numIndicesPerNode, dof_ids, values) );
00594 }
00595 
00596 #undef fei_file
00597 #define fei_file "unknown_file"
00598 
00599 #endif // _fei_Vector_Impl_hpp_
00600 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends