FEI Version of the Day
fei_Vector_Local.cpp
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 #include "fei_Vector_Local.hpp"
00045 #include "fei_sstream.hpp"
00046 #include "fei_fstream.hpp"
00047 #include <fei_ErrMacros.hpp>
00048 
00049 #include <algorithm>
00050 
00051 #undef fei_file
00052 #define fei_file "fei_Vector_Local.cpp"
00053 
00054 namespace fei {
00055 
00056 Vector_Local::Vector_Local(fei::SharedPtr<fei::VectorSpace> vecSpace)
00057  : vecSpace_(vecSpace),
00058    coefs_(),
00059    global_to_local_(),
00060    work_indices_()
00061 {
00062   int numCoefs = vecSpace_->getNumIndices_SharedAndOwned();
00063   coefs_.resize(numCoefs);
00064 
00065   std::vector<int> indices;
00066   vecSpace_->getIndices_SharedAndOwned(indices);
00067 
00068   std::sort(indices.begin(), indices.end());
00069 
00070   for(int i=0; i<numCoefs; ++i) {
00071     global_to_local_.insert(std::make_pair(indices[i], i));
00072   }
00073 }
00074 
00075 Vector_Local::~Vector_Local()
00076 {
00077 }
00078 
00079 int
00080 Vector_Local::update(double a,
00081                const fei::Vector* x,
00082                double b)
00083 {
00084   fei::console_out() << "Vector_Local::update NOT IMPLEMENTED."<<FEI_ENDL;
00085   return(-1);
00086 }
00087 
00088 int
00089 Vector_Local::scatterToOverlap()
00090 { return(0); }
00091 
00092 void
00093 Vector_Local::setCommSizes()
00094 {
00095 }
00096 
00097 int
00098 Vector_Local::gatherFromOverlap(bool accumulate)
00099 { (void)accumulate; return(0); }
00100 
00101 int
00102 Vector_Local::putScalar(double scalar)
00103 {
00104   for(size_t i=0; i<coefs_.size(); ++i) coefs_[i] = scalar;
00105   return(0);
00106 }
00107 
00108 int
00109 Vector_Local::giveToVector(int numValues, const int* indices,
00110                            const double* values,
00111                            bool sumInto, int vectorIndex)
00112 {
00113   if (vectorIndex != 0) {
00114     fei::console_out() << "fei::Vector_Local ERROR, vectorIndex!=0. Report to Alan Williams."<<FEI_ENDL;
00115     return(-1);
00116   }
00117 
00118   for(int i=0; i<numValues; ++i) {
00119     std::map<int,int>::iterator
00120      iter = global_to_local_.find(indices[i]);
00121     if (iter == global_to_local_.end()) {
00122       fei::console_out() << "fei::Vector_Local ERROR, eqn "<<indices[i]<<" not found "
00123          << "locally."<<FEI_ENDL;
00124       return(-1);
00125     }
00126 
00127     if (sumInto) {
00128       coefs_[iter->second] += values[i];
00129     }
00130     else {
00131       coefs_[iter->second] = values[i];
00132     }
00133   }
00134 
00135   return(0);
00136 }
00137 
00138 int
00139 Vector_Local::sumIn(int numValues, const int* indices, const double* values,
00140               int vectorIndex)
00141 {
00142   return( giveToVector(numValues, indices, values, true, vectorIndex) );
00143 }
00144 
00145 int
00146 Vector_Local::copyIn(int numValues, const int* indices, const double* values,
00147                int vectorIndex)
00148 {
00149   return( giveToVector(numValues, indices, values, false, vectorIndex) );
00150 }
00151 
00152 fei::SharedPtr<fei::VectorSpace>
00153 Vector_Local::getVectorSpace() const
00154 { return( vecSpace_ ); }
00155 
00156 void
00157 Vector_Local::setVectorSpace(fei::SharedPtr<fei::VectorSpace> vecSpace)
00158 { vecSpace_ = vecSpace; }
00159 
00160 int
00161 Vector_Local::assembleFieldData(int fieldID,
00162                        int idType,
00163                        int numIDs,
00164                        const int* IDs,
00165                        const double* data,
00166                        bool sumInto,
00167                        int vectorIndex)
00168 {
00169   int fieldSize = vecSpace_->getFieldSize(fieldID);
00170 
00171   work_indices_.resize(numIDs*fieldSize);
00172   int* indicesPtr = &work_indices_[0];
00173 
00174   CHK_ERR( vecSpace_->getGlobalIndices(numIDs, IDs, idType, fieldID,
00175                                         indicesPtr) );
00176 
00177   CHK_ERR( giveToVector(numIDs*fieldSize, indicesPtr, data, sumInto, vectorIndex) );
00178 
00179   return(0);
00180 }
00181 
00182 int
00183 Vector_Local::assembleFieldDataLocalIDs(int fieldID,
00184                        int idType,
00185                        int numIDs,
00186                        const int* localIDs,
00187                        const double* data,
00188                        bool sumInto,
00189                        int vectorIndex)
00190 {
00191   int fieldSize = vecSpace_->getFieldSize(fieldID);
00192 
00193   work_indices_.resize(numIDs*fieldSize);
00194   int* indicesPtr = &work_indices_[0];
00195 
00196   CHK_ERR( vecSpace_->getGlobalIndicesLocalIDs(numIDs, localIDs, idType, fieldID,
00197                                         indicesPtr) );
00198 
00199   CHK_ERR( giveToVector(numIDs*fieldSize, indicesPtr, data, sumInto, vectorIndex) );
00200 
00201   return(0);
00202 }
00203 
00204 int
00205 Vector_Local::sumInFieldData(int fieldID,
00206                        int idType,
00207                        int numIDs,
00208                        const int* IDs,
00209                        const double* data,
00210                        int vectorIndex)
00211 {
00212   return(assembleFieldData(fieldID, idType, numIDs, IDs,
00213                            data, true, vectorIndex));
00214 }
00215 
00216 int
00217 Vector_Local::copyInFieldData(int fieldID,
00218                         int idType,
00219                         int numIDs,
00220                         const int* IDs,
00221                         const double* data,
00222                         int vectorIndex)
00223 {
00224   return(assembleFieldData(fieldID, idType, numIDs, IDs,
00225                            data, false, vectorIndex));
00226 }
00227 
00228 int
00229 Vector_Local::copyInFieldDataLocalIDs(int fieldID,
00230                         int idType,
00231                         int numIDs,
00232                         const int* localIDs,
00233                         const double* data,
00234                         int vectorIndex)
00235 {
00236   return(assembleFieldDataLocalIDs(fieldID, idType, numIDs, localIDs,
00237                            data, false, vectorIndex));
00238 }
00239 
00240 int
00241 Vector_Local::copyOutFieldData(int fieldID,
00242                          int idType,
00243                          int numIDs,
00244                          const int* IDs,
00245                          double* data,
00246                          int vectorIndex)
00247 {
00248   int fieldSize = vecSpace_->getFieldSize(fieldID);
00249 
00250   work_indices_.resize(numIDs*fieldSize);
00251   int* indicesPtr = &work_indices_[0];
00252 
00253   CHK_ERR( vecSpace_->getGlobalIndices(numIDs, IDs, idType, fieldID,
00254                                         indicesPtr) );
00255 
00256   for(int i=0; i<(int)work_indices_.size(); ++i) {
00257     std::map<int,int>::iterator
00258       iter = global_to_local_.find(work_indices_[i]);
00259     if (iter == global_to_local_.end()) {
00260       fei::console_out() << "fei::Vector_Local::copyOut ERROR, eqn "<<work_indices_[i]<<" not found "
00261          << "locally."<<FEI_ENDL;
00262       return(-1);
00263     }
00264 
00265     data[i] = coefs_[iter->second];
00266   }
00267 
00268   return(0);
00269 }
00270 
00271 int
00272 Vector_Local::copyOut(int numValues, const int* indices,
00273                       double* values, int vectorIndex) const
00274 {
00275   if (vectorIndex != 0) {
00276     fei::console_out() << "fei::Vector_Local ERROR, vectorIndex!=0. Report to Alan Williams."<<FEI_ENDL;
00277     return(-1);
00278   }
00279 
00280   for(int i=0; i<numValues; ++i) {
00281     std::map<int,int>::const_iterator
00282      iter = global_to_local_.find(indices[i]);
00283     if (iter == global_to_local_.end()) {
00284       fei::console_out() << "fei::Vector_Local::copyOut ERROR, eqn "<<indices[i]<<" not found "
00285          << "locally."<<FEI_ENDL;
00286       return(-1);
00287     }
00288 
00289     values[i] = coefs_[iter->second];
00290   }
00291 
00292   return(0);
00293 }
00294 
00295 std::vector<double>&
00296 Vector_Local::getCoefs()
00297 {
00298   return(coefs_);
00299 }
00300 
00301 int
00302 Vector_Local::writeToFile(const char* filename,
00303                     bool matrixMarketFormat)
00304 {
00305   int local_proc = fei::localProc(vecSpace_->getCommunicator());
00306   FEI_OSTRINGSTREAM osstr;
00307   osstr << filename << "." << local_proc;
00308   std::string fullname = osstr.str();
00309   FEI_OFSTREAM ofstr(fullname.c_str(), IOS_OUT);
00310 
00311   return( writeToStream(ofstr, matrixMarketFormat) );
00312 }
00313 
00314 int
00315 Vector_Local::writeToStream(FEI_OSTREAM& ostrm,
00316                       bool matrixMarketFormat)
00317 {
00318   static char mmbanner[] = "%%MatrixMarket matrix array real general";
00319 
00320   if (matrixMarketFormat) {
00321     ostrm << mmbanner << FEI_ENDL;
00322     ostrm << coefs_.size() << " 1" << FEI_ENDL;
00323   }
00324   else {
00325     ostrm << coefs_.size() << FEI_ENDL;
00326   }
00327 
00328   ostrm.setf(IOS_SCIENTIFIC, IOS_FLOATFIELD);
00329   ostrm.precision(13);
00330 
00331   std::map<int,int>::iterator
00332     iter = global_to_local_.begin();
00333 
00334   for(unsigned i=0; i<coefs_.size(); ++i) {
00335     if (matrixMarketFormat) {
00336       ostrm << coefs_[i] << FEI_ENDL;
00337     }
00338     else {
00339       ostrm << iter->first << " " << coefs_[i] << FEI_ENDL;
00340       ++iter;
00341     }
00342   }
00343 
00344   return(0);
00345 }
00346 
00347 }//namespace fei
00348 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends