|
EpetraExt
Development
|
00001 //@HEADER 00002 // *********************************************************************** 00003 // 00004 // EpetraExt: Epetra Extended - Linear Algebra Services Package 00005 // Copyright (2011) Sandia Corporation 00006 // 00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, 00008 // the 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 Michael A. Heroux (maherou@sandia.gov) 00038 // 00039 // *********************************************************************** 00040 //@HEADER 00041 #include <EpetraExt_BTF_CrsMatrix.h> 00042 00043 #include <EpetraExt_Transpose_CrsGraph.h> 00044 00045 #include <Epetra_Import.h> 00046 #include <Epetra_CrsMatrix.h> 00047 #include <Epetra_CrsGraph.h> 00048 #include <Epetra_Map.h> 00049 00050 #include <vector> 00051 00052 using std::vector; 00053 00054 #define MATTRANS_F77 F77_FUNC(mattrans,MATTRANS) 00055 #define GENBTF_F77 F77_FUNC(genbtf,GENBTF) 00056 00057 extern "C" { 00058 extern void MATTRANS_F77( int*, int*, int*, int*, int*, int* ); 00059 extern void GENBTF_F77( int*, int*, int*, int*, int*, int*, int*, int*, int*, 00060 int*, int*, int*, int*, int*, int*, int*, int*, int*, 00061 int*, int*, int* ); 00062 } 00063 00064 namespace EpetraExt { 00065 00066 CrsMatrix_BTF:: 00067 ~CrsMatrix_BTF() 00068 { 00069 if( NewRowMap_ ) delete NewRowMap_; 00070 if( NewColMap_ ) delete NewColMap_; 00071 00072 if( Importer_ ) delete Importer_; 00073 00074 if( NewMatrix_ ) delete NewMatrix_; 00075 if( NewGraph_ ) delete NewGraph_; 00076 } 00077 00078 CrsMatrix_BTF::NewTypeRef 00079 CrsMatrix_BTF:: 00080 operator()( OriginalTypeRef orig ) 00081 { 00082 origObj_ = &orig; 00083 00084 if( orig.RowMap().DistributedGlobal() ) 00085 { cout << "FAIL for Global!\n"; abort(); } 00086 if( orig.IndicesAreGlobal() ) 00087 { cout << "FAIL for Global Indices!\n"; abort(); } 00088 00089 int n = orig.NumMyRows(); 00090 int nnz = orig.NumMyNonzeros(); 00091 00092 if( verbose_ ) 00093 { 00094 cout << "Orig Matrix:\n"; 00095 cout << orig << endl; 00096 } 00097 00098 //create std CRS format 00099 //also create graph without zero elements 00100 vector<int> ia(n+1,0); 00101 int maxEntries = orig.MaxNumEntries(); 00102 vector<int> ja_tmp(maxEntries); 00103 vector<double> jva_tmp(maxEntries); 00104 vector<int> ja(nnz); 00105 int cnt; 00106 00107 const Epetra_BlockMap & OldRowMap = orig.RowMap(); 00108 const Epetra_BlockMap & OldColMap = orig.ColMap(); 00109 Epetra_CrsGraph strippedGraph( Copy, OldRowMap, OldColMap, 0 ); 00110 00111 for( int i = 0; i < n; ++i ) 00112 { 00113 orig.ExtractMyRowCopy( i, maxEntries, cnt, &jva_tmp[0], &ja_tmp[0] ); 00114 ia[i+1] = ia[i]; 00115 for( int j = 0; j < cnt; ++j ) 00116 if( fabs(jva_tmp[j]) > threshold_ ) 00117 ja[ ia[i+1]++ ] = ja_tmp[j]; 00118 00119 int new_cnt = ia[i+1] - ia[i]; 00120 strippedGraph.InsertMyIndices( i, new_cnt, &ja[ ia[i] ] ); 00121 } 00122 nnz = ia[n]; 00123 strippedGraph.FillComplete(); 00124 00125 if( verbose_ ) 00126 { 00127 cout << "Stripped Graph\n"; 00128 cout << strippedGraph; 00129 } 00130 00131 vector<int> iat(n+1,0); 00132 vector<int> jat(nnz); 00133 for( int i = 0; i < n; ++i ) 00134 for( int j = ia[i]; j < ia[i+1]; ++j ) 00135 ++iat[ ja[j]+1 ]; 00136 for( int i = 0; i < n; ++i ) 00137 iat[i+1] += iat[i]; 00138 for( int i = 0; i < n; ++i ) 00139 for( int j = ia[i]; j < ia[i+1]; ++j ) 00140 jat[ iat[ ja[j] ]++ ] = i; 00141 for( int i = 0; i < n; ++i ) 00142 iat[n-i] = iat[n-i-1]; 00143 iat[0] = 0; 00144 00145 //convert to Fortran indexing 00146 for( int i = 0; i < n+1; ++i ) ++ia[i]; 00147 for( int i = 0; i < nnz; ++i ) ++ja[i]; 00148 for( int i = 0; i < n+1; ++i ) ++iat[i]; 00149 for( int i = 0; i < nnz; ++i ) ++jat[i]; 00150 00151 if( verbose_ ) 00152 { 00153 cout << "-----------------------------------------\n"; 00154 cout << "CRS Format Graph\n"; 00155 cout << "-----------------------------------------\n"; 00156 for( int i = 0; i < n; ++i ) 00157 { 00158 cout << i+1 << ": " << ia[i+1] << ": "; 00159 for( int j = ia[i]-1; j<ia[i+1]-1; ++j ) 00160 cout << " " << ja[j]; 00161 cout << endl; 00162 } 00163 cout << "-----------------------------------------\n"; 00164 } 00165 00166 /* 00167 vector<int> iat(n+1); 00168 vector<int> jat(nnz); 00169 int * jaf = &ja[0]; 00170 int * iaf = &ia[0]; 00171 int * jatf = &jat[0]; 00172 int * iatf = &iat[0]; 00173 MATTRANS_F77( &n, &n, &ja[0], &ia[0], &jat[0], &iat[0] ); 00174 */ 00175 00176 if( verbose_ ) 00177 { 00178 cout << "-----------------------------------------\n"; 00179 cout << "CCS Format Graph\n"; 00180 cout << "-----------------------------------------\n"; 00181 for( int i = 0; i < n; ++i ) 00182 { 00183 cout << i+1 << ": " << iat[i+1] << ": "; 00184 for( int j = iat[i]-1; j<iat[i+1]-1; ++j ) 00185 cout << " " << jat[j]; 00186 cout << endl; 00187 } 00188 cout << "-----------------------------------------\n"; 00189 } 00190 00191 vector<int> w(10*n); 00192 00193 vector<int> rowperm(n); 00194 vector<int> colperm(n); 00195 00196 //horizontal block 00197 int nhrows, nhcols, hrzcmp; 00198 //square block 00199 int nsrows, sqcmpn; 00200 //vertial block 00201 int nvrows, nvcols, vrtcmp; 00202 00203 vector<int> rcmstr(n+1); 00204 vector<int> ccmstr(n+1); 00205 00206 int msglvl = 0; 00207 int output = 6; 00208 00209 GENBTF_F77( &n, &n, &iat[0], &jat[0], &ia[0], &ja[0], &w[0], 00210 &rowperm[0], &colperm[0], &nhrows, &nhcols, 00211 &hrzcmp, &nsrows, &sqcmpn, &nvrows, &nvcols, &vrtcmp, 00212 &rcmstr[0], &ccmstr[0], &msglvl, &output ); 00213 00214 //convert back to C indexing 00215 for( int i = 0; i < n; ++i ) 00216 { 00217 --rowperm[i]; 00218 --colperm[i]; 00219 } 00220 for( int i = 0; (i<n+1) && (rcmstr[i]!=n+1); ++i ) 00221 { 00222 --rcmstr[i]; 00223 --ccmstr[i]; 00224 } 00225 00226 if( verbose_ ) 00227 { 00228 cout << "-----------------------------------------\n"; 00229 cout << "BTF Output\n"; 00230 cout << "-----------------------------------------\n"; 00231 cout << "RowPerm and ColPerm\n"; 00232 for( int i = 0; i<n; ++i ) 00233 cout << rowperm[i] << "\t" << colperm[i] << endl; 00234 if( hrzcmp ) 00235 { 00236 cout << "Num Horizontal: Rows, Cols, Comps\n"; 00237 cout << nhrows << "\t" << nhcols << "\t" << hrzcmp << endl; 00238 } 00239 cout << "Num Square: Rows, Comps\n"; 00240 cout << nsrows << "\t" << sqcmpn << endl; 00241 if( vrtcmp ) 00242 { 00243 cout << "Num Vertical: Rows, Cols, Comps\n"; 00244 cout << nvrows << "\t" << nvcols << "\t" << vrtcmp << endl; 00245 } 00246 cout << "Row, Col of upper left pt in blocks\n"; 00247 for( int i = 0; (i<n+1) && (rcmstr[i]!=n+1); ++i ) 00248 cout << i << " " << rcmstr[i] << " " << ccmstr[i] << endl; 00249 cout << "-----------------------------------------\n"; 00250 } 00251 00252 if( hrzcmp || vrtcmp ) 00253 { 00254 cout << "FAILED! hrz cmp's:" << hrzcmp << " vrtcmp: " << vrtcmp << endl; 00255 exit(0); 00256 } 00257 00258 //convert rowperm to OLD->NEW 00259 //reverse ordering of permutation to get upper triangular 00260 vector<int> rowperm_t( n ); 00261 vector<int> colperm_t( n ); 00262 for( int i = 0; i < n; ++i ) 00263 { 00264 // rowperm_t[ rowperm[i] ] = i; 00265 rowperm_t[i] = rowperm[i]; 00266 colperm_t[i] = colperm[i]; 00267 } 00268 00269 //Generate New Domain and Range Maps 00270 //for now, assume they start out as identical 00271 vector<int> myElements( n ); 00272 OldRowMap.MyGlobalElements( &myElements[0] ); 00273 00274 vector<int> newDomainElements( n ); 00275 vector<int> newRangeElements( n ); 00276 for( int i = 0; i < n; ++i ) 00277 { 00278 newDomainElements[ i ] = myElements[ rowperm_t[i] ]; 00279 newRangeElements[ i ] = myElements[ colperm_t[i] ]; 00280 } 00281 00282 NewRowMap_ = new Epetra_Map( n, n, &newDomainElements[0], OldRowMap.IndexBase(), OldRowMap.Comm() ); 00283 NewColMap_ = new Epetra_Map( n, n, &newRangeElements[0], OldColMap.IndexBase(), OldColMap.Comm() ); 00284 00285 if( verbose_ ) 00286 { 00287 cout << "New Row Map\n"; 00288 cout << *NewRowMap_ << endl; 00289 cout << "New ColMap\n"; 00290 cout << *NewColMap_ << endl; 00291 } 00292 00293 //Generate New Graph 00294 NewGraph_ = new Epetra_CrsGraph( Copy, *NewRowMap_, *NewColMap_, 0 ); 00295 Importer_ = new Epetra_Import( *NewRowMap_, OldRowMap ); 00296 NewGraph_->Import( strippedGraph, *Importer_, Insert ); 00297 NewGraph_->FillComplete(); 00298 if( verbose_ ) 00299 { 00300 cout << "NewGraph\n"; 00301 cout << *NewGraph_; 00302 } 00303 00304 NewMatrix_ = new Epetra_CrsMatrix( Copy, *NewGraph_ ); 00305 NewMatrix_->Import( orig, *Importer_, Insert ); 00306 NewMatrix_->FillComplete(); 00307 00308 if( verbose_ ) 00309 { 00310 cout << "New CrsMatrix\n"; 00311 cout << *NewMatrix_ << endl; 00312 } 00313 00314 newObj_ = NewMatrix_; 00315 00316 return *NewMatrix_; 00317 } 00318 00319 bool 00320 CrsMatrix_BTF:: 00321 fwd() 00322 { 00323 int ret = NewMatrix_->Import( *origObj_, *Importer_, Insert ); 00324 if (ret<0) return false; 00325 return true; 00326 } 00327 00328 bool 00329 CrsMatrix_BTF:: 00330 rvs() 00331 { 00332 int ret = origObj_->Export( *NewMatrix_, *Importer_, Insert ); 00333 if (ret<0) return false; 00334 return true; 00335 } 00336 00337 } //namespace EpetraExt
1.7.6.1