00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include <EpetraExt_BTF_CrsGraph.h>
00029
00030 #include <Epetra_Import.h>
00031 #include <Epetra_CrsGraph.h>
00032 #include <Epetra_Map.h>
00033
00034 #include <vector>
00035
00036 using std::vector;
00037
00038 #define MATTRANS_F77 F77_FUNC(mattrans,MATTRANS)
00039 #define GENBTF_F77 F77_FUNC(genbtf,GENBTF)
00040 extern "C" {
00041 extern void MATTRANS_F77( int*, int*, int*, int*, int*, int* );
00042 extern void GENBTF_F77( int*, int*, int*, int*, int*, int*, int*, int*, int*,
00043 int*, int*, int*, int*, int*, int*, int*, int*, int*,
00044 int*, int*, int* );
00045 }
00046
00047 namespace EpetraExt {
00048
00049 CrsGraph_BTF::
00050 ~CrsGraph_BTF()
00051 {
00052 if( NewRowMap_ ) delete NewRowMap_;
00053 if( NewDomainMap_ ) delete NewDomainMap_;
00054
00055 if( NewGraph_ ) delete NewGraph_;
00056 }
00057
00058 CrsGraph_BTF::NewTypeRef
00059 CrsGraph_BTF::
00060 operator()( OriginalTypeRef orig )
00061 {
00062 origObj_ = &orig;
00063
00064 if( orig.RowMap().DistributedGlobal() )
00065 { cout << "FAIL for Global!\n"; abort(); }
00066 if( orig.IndicesAreGlobal() )
00067 { cout << "FAIL for Global Indices!\n"; abort(); }
00068
00069 int n = orig.NumMyRows();
00070 int nnz = orig.NumMyNonzeros();
00071
00072
00073 vector<int> ia(n+1,0);
00074 vector<int> ja(nnz);
00075 int cnt;
00076 for( int i = 0; i < n; ++i )
00077 {
00078 int * tmpP = &ja[ia[i]];
00079 orig.ExtractMyRowCopy( i, nnz-ia[i], cnt, tmpP );
00080 ia[i+1] = ia[i] + cnt;
00081 }
00082
00083
00084 for( int i = 0; i < n+1; ++i ) ++ia[i];
00085 for( int i = 0; i < nnz; ++i ) ++ja[i];
00086
00087 #ifdef BTF_VERBOSE
00088 cout << "-----------------------------------------\n";
00089 cout << "CRS Format Graph\n";
00090 cout << "-----------------------------------------\n";
00091 for( int i = 0; i < n; ++i )
00092 {
00093 cout << i << ": " << ia[i+1] << ": ";
00094 for( int j = ia[i]-1; j<ia[i+1]-1; ++j )
00095 cout << " " << ja[j];
00096 cout << endl;
00097 }
00098 cout << "-----------------------------------------\n";
00099 #endif
00100
00101 vector<int> iat(n+1);
00102 vector<int> jat(nnz);
00103 int * jaf = &ja[0];
00104 int * iaf = &ia[0];
00105 int * jatf = &jat[0];
00106 int * iatf = &iat[0];
00107 MATTRANS_F77( &n, &n, jaf, iaf, jatf, iatf );
00108
00109 #ifdef BTF_VERBOSE
00110 cout << "-----------------------------------------\n";
00111 cout << "CCS Format Graph\n";
00112 cout << "-----------------------------------------\n";
00113 for( int i = 0; i < n; ++i )
00114 {
00115 cout << i << ": " << iat[i+1] << ": ";
00116 for( int j = iat[i]-1; j<iat[i+1]-1; ++j )
00117 cout << " " << jat[j];
00118 cout << endl;
00119 }
00120 cout << "-----------------------------------------\n";
00121 #endif
00122
00123 vector<int> w(10*n);
00124
00125 vector<int> rowperm(n);
00126 vector<int> colperm(n);
00127
00128
00129 int nhrows, nhcols, hrzcmp;
00130
00131 int nsrows, sqcmpn;
00132
00133 int nvrows, nvcols, vrtcmp;
00134
00135 vector<int> rcmstr(n+1);
00136 vector<int> ccmstr(n+1);
00137
00138 int msglvl = 0;
00139 int output = 6;
00140
00141 GENBTF_F77( &n, &n, &iat[0], &jat[0], &ia[0], &ja[0], &w[0],
00142 &rowperm[0], &colperm[0], &nhrows, &nhcols,
00143 &hrzcmp, &nsrows, &sqcmpn, &nvrows, &nvcols, &vrtcmp,
00144 &rcmstr[0], &ccmstr[0], &msglvl, &output );
00145
00146
00147 for( int i = 0; i < n; ++i )
00148 {
00149 --rowperm[i];
00150 --colperm[i];
00151 }
00152 for( int i = 0; (i<n+1) && (rcmstr[i]!=n+1); ++i )
00153 {
00154 --rcmstr[i];
00155 --ccmstr[i];
00156 }
00157
00158 #ifdef BTF_VERBOSE
00159 cout << "-----------------------------------------\n";
00160 cout << "BTF Output\n";
00161 cout << "-----------------------------------------\n";
00162 cout << "RowPerm and ColPerm\n";
00163 for( int i = 0; i<n; ++i )
00164 cout << rowperm[i] << "\t" << colperm[i] << endl;
00165 if( hrzcmp )
00166 {
00167 cout << "Num Horizontal: Rows, Cols, Comps\n";
00168 cout << nhrows << "\t" << nhcols << "\t" << hrzcmp << endl;
00169 }
00170 cout << "Num Square: Rows, Comps\n";
00171 cout << nsrows << "\t" << sqcmpn << endl;
00172 if( vrtcmp )
00173 {
00174 cout << "Num Vertical: Rows, Cols, Comps\n";
00175 cout << nvrows << "\t" << nvcols << "\t" << vrtcmp << endl;
00176 }
00177 cout << "Row, Col of upper left pt in blocks\n";
00178 for( int i = 0; (i<n+1) && (rcmstr[i]!=n+1); ++i )
00179 cout << i << " " << rcmstr[i] << " " << ccmstr[i] << endl;
00180 cout << "-----------------------------------------\n";
00181 #endif
00182
00183 if( hrzcmp || vrtcmp )
00184 { cout << "FAILED! hrz cmp's:" << hrzcmp << " vrtcmp: " << vrtcmp << endl;
00185 exit(0); }
00186
00187
00188
00189 vector<int> rowperm_t( n );
00190 vector<int> colperm_t( n );
00191 for( int i = 0; i < n; ++i )
00192 {
00193
00194
00195 rowperm_t[i] = rowperm[(n-1)-i];
00196 colperm_t[i] = colperm[(n-1)-i];
00197 }
00198
00199
00200
00201 const Epetra_BlockMap & OldMap = orig.RowMap();
00202 vector<int> myElements( n );
00203 OldMap.MyGlobalElements( &myElements[0] );
00204
00205 vector<int> newDomainElements( n );
00206 vector<int> newRangeElements( n );
00207 for( int i = 0; i < n; ++i )
00208 {
00209 newDomainElements[ i ] = myElements[ rowperm_t[i] ];
00210 newRangeElements[ i ] = myElements[ colperm_t[i] ];
00211 cout << i << "\t" << rowperm_t[i] << "\t" << colperm[i] << "\t" << myElements[i] << endl;
00212 }
00213
00214 NewRowMap_ = new Epetra_Map( n, n, &newDomainElements[0], OldMap.IndexBase(), OldMap.Comm() );
00215 NewDomainMap_ = new Epetra_Map( n, n, &newRangeElements[0], OldMap.IndexBase(), OldMap.Comm() );
00216
00217 #ifdef BTF_VERBOSE
00218 cout << "New Row Map\n";
00219 cout << *RowMap << endl;
00220 cout << "New Domain Map\n";
00221 cout << *DomainMap << endl;
00222 #endif
00223
00224
00225 NewGraph_ = new Epetra_CrsGraph( Copy, *NewRowMap_, 0 );
00226 Epetra_Import Importer( *NewRowMap_, OldMap );
00227 NewGraph_->Import( orig, Importer, Insert );
00228 NewGraph_->FillComplete( *NewDomainMap_, *NewRowMap_ );
00229
00230 #ifdef BTF_VERBOSE
00231 cout << "New CrsGraph\n";
00232 cout << *NewGraph_ << endl;
00233 #endif
00234
00235 newObj_ = NewGraph_;
00236
00237 return *NewGraph_;
00238 }
00239
00240 }