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 int
00093 Vector_Local::gatherFromOverlap(bool accumulate)
00094 { (void)accumulate; return(0); }
00095 
00096 int
00097 Vector_Local::putScalar(double scalar)
00098 {
00099   for(size_t i=0; i<coefs_.size(); ++i) coefs_[i] = scalar;
00100   return(0);
00101 }
00102 
00103 int
00104 Vector_Local::giveToVector(int numValues, const int* indices,
00105                            const double* values,
00106                            bool sumInto, int vectorIndex)
00107 {
00108   if (vectorIndex != 0) {
00109     fei::console_out() << "fei::Vector_Local ERROR, vectorIndex!=0. Report to Alan Williams."<<FEI_ENDL;
00110     return(-1);
00111   }
00112 
00113   for(int i=0; i<numValues; ++i) {
00114     std::map<int,int>::iterator
00115      iter = global_to_local_.find(indices[i]);
00116     if (iter == global_to_local_.end()) {
00117       fei::console_out() << "fei::Vector_Local ERROR, eqn "<<indices[i]<<" not found "
00118          << "locally."<<FEI_ENDL;
00119       return(-1);
00120     }
00121 
00122     if (sumInto) {
00123       coefs_[iter->second] += values[i];
00124     }
00125     else {
00126       coefs_[iter->second] = values[i];
00127     }
00128   }
00129 
00130   return(0);
00131 }
00132 
00133 int
00134 Vector_Local::sumIn(int numValues, const int* indices, const double* values,
00135               int vectorIndex)
00136 {
00137   return( giveToVector(numValues, indices, values, true, vectorIndex) );
00138 }
00139 
00140 int
00141 Vector_Local::copyIn(int numValues, const int* indices, const double* values,
00142                int vectorIndex)
00143 {
00144   return( giveToVector(numValues, indices, values, false, vectorIndex) );
00145 }
00146 
00147 fei::SharedPtr<fei::VectorSpace>
00148 Vector_Local::getVectorSpace() const
00149 { return( vecSpace_ ); }
00150 
00151 void
00152 Vector_Local::setVectorSpace(fei::SharedPtr<fei::VectorSpace> vecSpace)
00153 { vecSpace_ = vecSpace; }
00154 
00155 int
00156 Vector_Local::assembleFieldData(int fieldID,
00157                        int idType,
00158                        int numIDs,
00159                        const int* IDs,
00160                        const double* data,
00161                        bool sumInto,
00162                        int vectorIndex)
00163 {
00164   int fieldSize = vecSpace_->getFieldSize(fieldID);
00165 
00166   work_indices_.resize(numIDs*fieldSize);
00167   int* indicesPtr = &work_indices_[0];
00168 
00169   CHK_ERR( vecSpace_->getGlobalIndices(numIDs, IDs, idType, fieldID,
00170                                         indicesPtr) );
00171 
00172   CHK_ERR( giveToVector(numIDs*fieldSize, indicesPtr, data, sumInto, vectorIndex) );
00173 
00174   return(0);
00175 }
00176 
00177 int
00178 Vector_Local::sumInFieldData(int fieldID,
00179                        int idType,
00180                        int numIDs,
00181                        const int* IDs,
00182                        const double* data,
00183                        int vectorIndex)
00184 {
00185   return(assembleFieldData(fieldID, idType, numIDs, IDs,
00186                            data, true, vectorIndex));
00187 }
00188 
00189 int
00190 Vector_Local::copyInFieldData(int fieldID,
00191                         int idType,
00192                         int numIDs,
00193                         const int* IDs,
00194                         const double* data,
00195                         int vectorIndex)
00196 {
00197   return(assembleFieldData(fieldID, idType, numIDs, IDs,
00198                            data, false, vectorIndex));
00199 }
00200 
00201 int
00202 Vector_Local::copyOutFieldData(int fieldID,
00203                          int idType,
00204                          int numIDs,
00205                          const int* IDs,
00206                          double* data,
00207                          int vectorIndex)
00208 {
00209   int fieldSize = vecSpace_->getFieldSize(fieldID);
00210 
00211   work_indices_.resize(numIDs*fieldSize);
00212   int* indicesPtr = &work_indices_[0];
00213 
00214   CHK_ERR( vecSpace_->getGlobalIndices(numIDs, IDs, idType, fieldID,
00215                                         indicesPtr) );
00216 
00217   for(int i=0; i<(int)work_indices_.size(); ++i) {
00218     std::map<int,int>::iterator
00219       iter = global_to_local_.find(work_indices_[i]);
00220     if (iter == global_to_local_.end()) {
00221       fei::console_out() << "fei::Vector_Local::copyOut ERROR, eqn "<<work_indices_[i]<<" not found "
00222          << "locally."<<FEI_ENDL;
00223       return(-1);
00224     }
00225 
00226     data[i] = coefs_[iter->second];
00227   }
00228 
00229   return(0);
00230 }
00231 
00232 int
00233 Vector_Local::copyOut(int numValues, const int* indices,
00234                       double* values, int vectorIndex) const
00235 {
00236   if (vectorIndex != 0) {
00237     fei::console_out() << "fei::Vector_Local ERROR, vectorIndex!=0. Report to Alan Williams."<<FEI_ENDL;
00238     return(-1);
00239   }
00240 
00241   for(int i=0; i<numValues; ++i) {
00242     std::map<int,int>::const_iterator
00243      iter = global_to_local_.find(indices[i]);
00244     if (iter == global_to_local_.end()) {
00245       fei::console_out() << "fei::Vector_Local::copyOut ERROR, eqn "<<indices[i]<<" not found "
00246          << "locally."<<FEI_ENDL;
00247       return(-1);
00248     }
00249 
00250     values[i] = coefs_[iter->second];
00251   }
00252 
00253   return(0);
00254 }
00255 
00256 std::vector<double>&
00257 Vector_Local::getCoefs()
00258 {
00259   return(coefs_);
00260 }
00261 
00262 int
00263 Vector_Local::writeToFile(const char* filename,
00264                     bool matrixMarketFormat)
00265 {
00266   int local_proc = fei::localProc(vecSpace_->getCommunicator());
00267   FEI_OSTRINGSTREAM osstr;
00268   osstr << filename << "." << local_proc;
00269   std::string fullname = osstr.str();
00270   FEI_OFSTREAM ofstr(fullname.c_str(), IOS_OUT);
00271 
00272   return( writeToStream(ofstr, matrixMarketFormat) );
00273 }
00274 
00275 int
00276 Vector_Local::writeToStream(FEI_OSTREAM& ostrm,
00277                       bool matrixMarketFormat)
00278 {
00279   static char mmbanner[] = "%%MatrixMarket matrix array real general";
00280 
00281   if (matrixMarketFormat) {
00282     ostrm << mmbanner << FEI_ENDL;
00283     ostrm << coefs_.size() << " 1" << FEI_ENDL;
00284   }
00285   else {
00286     ostrm << coefs_.size() << FEI_ENDL;
00287   }
00288 
00289   ostrm.setf(IOS_SCIENTIFIC, IOS_FLOATFIELD);
00290   ostrm.precision(13);
00291 
00292   std::map<int,int>::iterator
00293     iter = global_to_local_.begin();
00294 
00295   for(unsigned i=0; i<coefs_.size(); ++i) {
00296     if (matrixMarketFormat) {
00297       ostrm << coefs_[i] << FEI_ENDL;
00298     }
00299     else {
00300       ostrm << iter->first << " " << coefs_[i] << FEI_ENDL;
00301       ++iter;
00302     }
00303   }
00304 
00305   return(0);
00306 }
00307 
00308 }//namespace fei
00309 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends