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
00029 #include <EpetraExt_Zoltan_CrsGraph.h>
00030
00031 #include <EpetraExt_Transpose_CrsGraph.h>
00032
00033 #include <EpetraExt_ZoltanQuery.h>
00034 #include <Zoltan_LoadBalance.h>
00035
00036 #include <Epetra_CrsGraph.h>
00037 #include <Epetra_Map.h>
00038 #include <Epetra_Import.h>
00039
00040 #include <Epetra_MpiComm.h>
00041
00042 #include <vector>
00043 #include <set>
00044
00045 using std::vector;
00046 using std::set;
00047
00048 namespace EpetraExt {
00049
00050 Zoltan_CrsGraph::
00051 ~Zoltan_CrsGraph()
00052 {
00053 if( newObj_ ) delete newObj_;
00054
00055 if( NewRowMap_ ) delete NewRowMap_;
00056 }
00057
00058 Zoltan_CrsGraph::NewTypeRef
00059 Zoltan_CrsGraph::
00060 operator()( OriginalTypeRef orig )
00061 {
00062 origObj_ = &orig;
00063
00064 int err;
00065
00066
00067 float version;
00068 char * dummy = 0;
00069 Zoltan::LoadBalance LB( 0, &dummy, &version );
00070 err = LB.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() );
00071 if( err == ZOLTAN_OK ) err = LB.Set_Param( "LB_METHOD", "PARMETIS" );
00072 if( err == ZOLTAN_OK ) err = LB.Set_Param( "PARMETIS_METHOD", partitionMethod_ );
00073
00074
00075 CrsGraph_Transpose transposeTransform;
00076 Epetra_CrsGraph & TransGraph = transposeTransform( orig );
00077 ZoltanQuery Query( orig, &TransGraph );
00078 if( err == ZOLTAN_OK ) err = LB.Set_QueryObject( &Query );
00079
00080 if( err != ZOLTAN_OK )
00081 { cout << "Setup of Zoltan Load Balancing Objects FAILED!\n"; exit(0); }
00082
00083
00084 int changes;
00085 int num_gid_entries, num_lid_entries;
00086 int num_import;
00087 ZOLTAN_ID_PTR import_global_ids, import_local_ids;
00088 int * import_procs;
00089 int num_export;
00090 ZOLTAN_ID_PTR export_global_ids, export_local_ids;
00091 int * export_procs;
00092
00093
00094
00095 orig.Comm().Barrier();
00096 err = LB.Balance( &changes,
00097 &num_gid_entries, &num_lid_entries,
00098 &num_import, &import_global_ids, &import_local_ids, &import_procs,
00099 &num_export, &export_global_ids, &export_local_ids, &export_procs );
00100 LB.Evaluate( 1, 0, 0, 0, 0, 0, 0 );
00101 orig.Comm().Barrier();
00102
00103
00104 int numMyElements = orig.RowMap().NumMyElements();
00105 vector<int> elementList( numMyElements );
00106 orig.RowMap().MyGlobalElements( &elementList[0] );
00107
00108 int newNumMyElements = numMyElements - num_export + num_import;
00109 vector<int> newElementList( newNumMyElements );
00110
00111 set<int> gidSet;
00112 for( int i = 0; i < num_export; ++i )
00113 gidSet.insert( export_global_ids[i] );
00114
00115
00116 int loc = 0;
00117 for( int i = 0; i < numMyElements; ++i )
00118 if( !gidSet.count( elementList[i] ) )
00119 newElementList[loc++] = elementList[i];
00120
00121
00122 for( int i = 0; i < num_import; ++i )
00123 newElementList[loc+i] = import_global_ids[i];
00124
00125
00126 if( err == ZOLTAN_OK )
00127 err = LB.Free_Data( &import_global_ids, &import_local_ids, &import_procs,
00128 &export_global_ids, &export_local_ids, &export_procs );
00129
00130
00131 NewRowMap_ = new Epetra_Map( orig.RowMap().NumGlobalElements(),
00132 newNumMyElements,
00133 &newElementList[0],
00134 orig.RowMap().IndexBase(),
00135 orig.RowMap().Comm() );
00136
00137
00138 Epetra_Import Importer( *NewRowMap_, orig.RowMap() );
00139
00140
00141 Epetra_CrsGraph * NewGraph = new Epetra_CrsGraph( Copy, *NewRowMap_, 0 );
00142 NewGraph->Import( orig, Importer, Insert );
00143 NewGraph->FillComplete();
00144
00145 Zoltan::LoadBalance LB2( 0, &dummy, &version );
00146 err = LB2.Create( dynamic_cast<const Epetra_MpiComm&>(orig.Comm()).Comm() );
00147 if( err == ZOLTAN_OK ) err = LB2.Set_Param( "LB_METHOD", "PARMETIS" );
00148 if( err == ZOLTAN_OK ) err = LB2.Set_Param( "PARMETIS_METHOD", partitionMethod_ );
00149 CrsGraph_Transpose transTrans;
00150 Epetra_CrsGraph & trans2 = transTrans( *NewGraph );
00151 ZoltanQuery query( *NewGraph, &trans2 );
00152 if( err == ZOLTAN_OK ) err = LB2.Set_QueryObject( &query );
00153 err = LB2.Balance( &changes,
00154 &num_gid_entries, &num_lid_entries,
00155 &num_import, &import_global_ids, &import_local_ids, &import_procs,
00156 &num_export, &export_global_ids, &export_local_ids, &export_procs );
00157 LB2.Evaluate( 1, 0, 0, 0, 0, 0, 0 );
00158
00159 newObj_ = NewGraph;
00160
00161 return *NewGraph;
00162 }
00163
00164 }
00165