45 #include "Epetra_MultiVector.h" 
   46 #include "Epetra_Comm.h" 
   47 #include "Epetra_LAPACK.h" 
   48 #include "Epetra_Distributor.h" 
   72   if(DataMap_) 
delete DataMap_;
 
   73   if(Pivots_) 
delete [] Pivots_;
 
   74   if(Values_) 
delete [] Values_;
 
   95 void EpetraExt_BlockDiagMatrix::Allocate(){
 
   99   int *ElementSize=
new int[NumBlocks];
 
  101   for(
int i=0;i<NumBlocks;i++) {
 
  103     dataSize+=ElementSize[i];
 
  106 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES 
  107   if(Map().GlobalIndicesInt()) {
 
  108     DataMap_=
new Epetra_BlockMap(-1,Map().NumMyElements(),Map().MyGlobalElements(),ElementSize,0,Map().
Comm());
 
  112 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES 
  113   if(Map().GlobalIndicesLongLong()) {
 
  114     DataMap_=
new Epetra_BlockMap((
long long) -1,Map().NumMyElements(),Map().MyGlobalElements64(),ElementSize,0,Map().
Comm());
 
  118     throw "EpetraExt_BlockDiagMatrix::Allocate: GlobalIndices type unknown";
 
  120   Values_=
new double[dataSize];
 
  121   delete [] ElementSize;
 
  131   std::string dummy(
"multiply");
 
  132   std::string ApplyMode=List_.get(
"apply mode",dummy);
 
  133   if(ApplyMode==std::string(
"multiply"))    ApplyMode_=
AM_MULTIPLY;
 
  134   else if(ApplyMode==std::string(
"invert")) ApplyMode_=
AM_INVERT;
 
  135   else if(ApplyMode==std::string(
"factor")) ApplyMode_=
AM_FACTOR;
 
  136   else EPETRA_CHK_ERR(-1);
 
  145   for (
int i=0;i<MaxData;i++) Values_[i]=value;
 
  157   if(!Map().SameAs(Source.Map()) || !DataMap_->
SameAs(*Source.DataMap_))
 
  158     throw ReportError(
"Maps of DistBlockMatrices incompatible in assignment",-1);
 
  162   for(
int i=0;i<MaxData;i++)                 Values_[i]=Source.Values_[i];
 
  163   for(
int i=0;i<Source.
NumMyUnknowns();i++)  Pivots_[i]=Source.Pivots_[i];
 
  166   ApplyMode_=Source.ApplyMode_;
 
  167   HasComputed_=Source.HasComputed_;
 
  184     for(
int i=0;i<NumBlocks;i++){
 
  193         double d=1/(v[0]*v[3]-v[1]*v[2]);
 
  203         if(info) EPETRA_CHK_ERR(-2);
 
  210       std::vector<double> work(lwork);
 
  211       for(
int i=0;i<NumBlocks;i++){
 
  219           LAPACK.
GETRI(Nb,&Values_[DataMap_->
FirstPointInElement(i)],Nb,&Pivots_[Map().FirstPointInElement(i)],&work[0],&lwork,&info);
 
  220           if(info) EPETRA_CHK_ERR(-3);
 
  234   int NumVectors=X.NumVectors();
 
  235   if(NumVectors!=Y.NumVectors())
 
  244   const int *xlist=Map().FirstPointInElementList();
 
  245   const int *blocksize=Map().ElementSizeList();
 
  250     for(
int i=0;i<NumBlocks;i++){
 
  254       for(
int j=0;j<NumVectors;j++){
 
  257           Y[j][xidx0]=Values_[vidx0]*X[j][xidx0];
 
  261           Y[j][xidx0  ]=Values_[vidx0  ]*X[j][xidx0] + Values_[vidx0+2]*X[j][xidx0+1];
 
  262           Y[j][xidx0+1]=Values_[vidx0+1]*X[j][xidx0] + Values_[vidx0+3]*X[j][xidx0+1];
 
  267           GEMV(
'N',Nb,Nb,1.0,&Values_[vidx0],Nb,&X[j][xidx0],0.0,&Y[j][xidx0]);
 
  275     for(
int i=0;i<NumBlocks;i++){
 
  279       for(
int j=0;j<NumVectors;j++){
 
  282           Y[j][xidx0]=Values_[vidx0]*X[j][xidx0];
 
  286           Y[j][xidx0  ]=Values_[vidx0  ]*X[j][xidx0] + Values_[vidx0+2]*X[j][xidx0+1];
 
  287           Y[j][xidx0+1]=Values_[vidx0+1]*X[j][xidx0] + Values_[vidx0+3]*X[j][xidx0+1];
 
  292           for(
int k=0;k<Nb;k++) Y[j][xidx0+k]=X[j][xidx0+k];
 
  293           LAPACK.
GETRS(
'N',Nb,1,&Values_[vidx0],Nb,&Pivots_[xidx0],&Y[j][xidx0],Nb,&info);
 
  294           if(info) EPETRA_CHK_ERR(info);
 
  311   for (
int iproc=0; iproc < NumProc; iproc++) {
 
  315       int * MyGlobalElements1_int = 0;
 
  316       long long * MyGlobalElements1_LL = 0;
 
  317 #ifndef EPETRA_NO_32BIT_GLOBAL_INDICES 
  323 #ifndef EPETRA_NO_64BIT_GLOBAL_INDICES 
  325           MyGlobalElements1_LL = DataMap_->MyGlobalElements64();
 
  329           throw "EpetraExt_BlockDiagMatrix::Print: GlobalIndices type unknown";
 
  331       int * FirstPointInElementList1 = (MaxElementSize1 == 1) ?
 
  336         os <<  
"     MyPID"; os << 
"    ";
 
  338         if (MaxElementSize1==1)
 
  346       for (
int i=0; i < NumMyElements1; i++) {
 
  347         for (
int ii=0; ii < DataMap_->
ElementSize(i); ii++) {
 
  350           os <<  MyPID; os << 
"    ";
 
  352           if (MaxElementSize1==1) {
 
  353             os << (MyGlobalElements1_int ? MyGlobalElements1_int[i] : MyGlobalElements1_LL[i]) << 
"    ";
 
  357             os <<  (MyGlobalElements1_int ? MyGlobalElements1_int[i] : MyGlobalElements1_LL[i]) << 
"/" << ii << 
"    ";
 
  358             iii = FirstPointInElementList1[i]+ii;
 
  369     Map().Comm().Barrier();
 
  370     Map().Comm().Barrier();
 
  371     Map().Comm().Barrier();
 
  380   return &Map() == &Source.Map();
 
  390                                            int * PermuteFromLIDs,
 
  398   double *To = Values_;
 
  400   int * ToFirstPointInElementList = 0;
 
  401   int * FromFirstPointInElementList = 0;
 
  402   int * FromElementSizeList = 0;
 
  406   if (!ConstantElementSize) {
 
  418   if (MaxElementSize==1) {
 
  420     NumSameEntries = NumSameIDs;
 
  422   else if (ConstantElementSize) {
 
  424     NumSameEntries = NumSameIDs * MaxElementSize;
 
  428     NumSameEntries = FromFirstPointInElementList[NumSameIDs];
 
  439       if (CombineMode==Epetra_AddLocalAlso) {
 
  440         for (
int j=0; j<NumSameEntries; j++) {
 
  444         for (
int j=0; j<NumSameEntries; j++) {
 
  450   if (NumPermuteIDs>0) {
 
  455       if (CombineMode==Epetra_AddLocalAlso) {
 
  456         for (
int j=0; j<NumPermuteIDs; j++) {
 
  457           To[PermuteToLIDs[j]] += From[PermuteFromLIDs[j]]; 
 
  461         for (
int j=0; j<NumPermuteIDs; j++) {
 
  462           To[PermuteToLIDs[j]] = From[PermuteFromLIDs[j]];
 
  468       for (
int j=0; j<NumPermuteIDs; j++) {
 
  469         int jj = MaxElementSize*PermuteToLIDs[j];
 
  470         int jjj = MaxElementSize*PermuteFromLIDs[j];
 
  471         if (CombineMode==Epetra_AddLocalAlso) {
 
  472           for (
int k=0; k<MaxElementSize; k++) {
 
  473             To[jj+k] += From[jjj+k]; 
 
  477           for (
int k=0; k<MaxElementSize; k++) {
 
  478             To[jj+k] = From[jjj+k];
 
  486       for (
int j=0; j<NumPermuteIDs; j++) {
 
  487         int jj = ToFirstPointInElementList[PermuteToLIDs[j]];
 
  488         int jjj = FromFirstPointInElementList[PermuteFromLIDs[j]];
 
  489         int ElementSize = FromElementSizeList[PermuteFromLIDs[j]];
 
  490         if (CombineMode==Epetra_AddLocalAlso) {
 
  491           for (
int k=0; k<ElementSize; k++) {
 
  492             To[jj+k] += From[jjj+k]; 
 
  496           for (
int k=0; k<ElementSize; k++) {
 
  497             To[jj+k] = From[jjj+k];
 
  528   int * FromFirstPointInElementList = 0;
 
  529   int * FromElementSizeList = 0;
 
  531   if (!ConstantElementSize) {
 
  536   SizeOfPacket = MaxElementSize * (int)
sizeof(
double);
 
  538   if(NumExportIDs*SizeOfPacket>LenExports) {
 
  539     if (LenExports>0) 
delete [] Exports;
 
  540     LenExports = NumExportIDs*SizeOfPacket;
 
  541     Exports = 
new char[LenExports];
 
  546   if (NumExportIDs>0) {
 
  547     ptr = (
double *) Exports;
 
  550     if (MaxElementSize==1) 
for (j=0; j<NumExportIDs; j++) *ptr++ = From[ExportLIDs[j]];
 
  553     else if (ConstantElementSize) {
 
  554       for (j=0; j<NumExportIDs; j++) {
 
  555         jj = MaxElementSize*ExportLIDs[j];
 
  556           for (k=0; k<MaxElementSize; k++)
 
  563       SizeOfPacket = MaxElementSize;
 
  564       for (j=0; j<NumExportIDs; j++) {
 
  565         ptr = (
double *) Exports + j*SizeOfPacket;
 
  566         jj = FromFirstPointInElementList[ExportLIDs[j]];
 
  567         int ElementSize = FromElementSizeList[ExportLIDs[j]];
 
  568           for (k=0; k<ElementSize; k++)
 
  595   if(    CombineMode != Add
 
  596       && CombineMode != Zero
 
  597       && CombineMode != Insert
 
  598       && CombineMode != Average
 
  599       && CombineMode != AbsMax )
 
  602   if (NumImportIDs<=0) 
return(0);
 
  604   double * To = Values_;
 
  608   int * ToFirstPointInElementList = 0;
 
  609   int * ToElementSizeList = 0;
 
  611   if (!ConstantElementSize) {
 
  619   ptr = (
double *) Imports;
 
  622   if (MaxElementSize==1) {
 
  624       if (CombineMode==Add)
 
  625         for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] += *ptr++; 
 
  626       else if(CombineMode==Insert)
 
  627         for (j=0; j<NumImportIDs; j++) To[ImportLIDs[j]] = *ptr++;
 
  628       else if(CombineMode==AbsMax)
 
  629         for (j=0; j<NumImportIDs; j++) {
 
  630           To[ImportLIDs[j]] = EPETRA_MAX( To[ImportLIDs[j]],std::abs(*ptr));
 
  635       else if(CombineMode==Average)
 
  636         for (j=0; j<NumImportIDs; j++) {To[ImportLIDs[j]] += *ptr++; To[ImportLIDs[j]] /= 2;}
 
  641   else if (ConstantElementSize) {
 
  643     if (CombineMode==Add) {
 
  644       for (j=0; j<NumImportIDs; j++) {
 
  645         jj = MaxElementSize*ImportLIDs[j];
 
  646           for (k=0; k<MaxElementSize; k++)
 
  650     else if(CombineMode==Insert) {
 
  651       for (j=0; j<NumImportIDs; j++) {
 
  652         jj = MaxElementSize*ImportLIDs[j];
 
  653           for (k=0; k<MaxElementSize; k++)
 
  657     else if(CombineMode==AbsMax) {
 
  658       for (j=0; j<NumImportIDs; j++) {
 
  659         jj = MaxElementSize*ImportLIDs[j];
 
  660         for (k=0; k<MaxElementSize; k++) {
 
  661             To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr));
 
  668     else if(CombineMode==Average) {
 
  669       for (j=0; j<NumImportIDs; j++) {
 
  670         jj = MaxElementSize*ImportLIDs[j];
 
  671           for (k=0; k<MaxElementSize; k++)
 
  672             { To[jj+k] += *ptr++; To[jj+k] /= 2;}
 
  681     SizeOfPacket = MaxElementSize;
 
  683     if (CombineMode==Add) {
 
  684       for (j=0; j<NumImportIDs; j++) {
 
  685         ptr = (
double *) Imports + j*SizeOfPacket;
 
  686         jj = ToFirstPointInElementList[ImportLIDs[j]];
 
  687         int ElementSize = ToElementSizeList[ImportLIDs[j]];
 
  688           for (k=0; k<ElementSize; k++)
 
  692     else  if(CombineMode==Insert){
 
  693       for (j=0; j<NumImportIDs; j++) {
 
  694         ptr = (
double *) Imports + j*SizeOfPacket;
 
  695         jj = ToFirstPointInElementList[ImportLIDs[j]];
 
  696         int ElementSize = ToElementSizeList[ImportLIDs[j]];
 
  697           for (k=0; k<ElementSize; k++)
 
  701     else  if(CombineMode==AbsMax){
 
  702       for (j=0; j<NumImportIDs; j++) {
 
  703         ptr = (
double *) Imports + j*SizeOfPacket;
 
  704         jj = ToFirstPointInElementList[ImportLIDs[j]];
 
  705         int ElementSize = ToElementSizeList[ImportLIDs[j]];
 
  706         for (k=0; k<ElementSize; k++) {
 
  707             To[jj+k] = EPETRA_MAX( To[jj+k], std::abs(*ptr));
 
  714     else if(CombineMode==Average) {
 
  715       for (j=0; j<NumImportIDs; j++) {
 
  716         ptr = (
double *) Imports + j*SizeOfPacket;
 
  717         jj = ToFirstPointInElementList[ImportLIDs[j]];
 
  718         int ElementSize = ToElementSizeList[ImportLIDs[j]];
 
  719           for (k=0; k<ElementSize; k++)
 
  720             { To[jj+k] += *ptr++; To[jj+k] /= 2;}
 
virtual const Epetra_BlockMap & DataMap() const 
Returns the Epetra_BlockMap object with the distribution of underlying values. 
 
virtual int ApplyInverse(const Epetra_MultiVector &X, Epetra_MultiVector &Y) const 
Returns the result of a Epetra_Operator inverse applied to an Epetra_MultiVector X in Y...
 
bool GlobalIndicesLongLong() const 
 
bool SameAs(const Epetra_BlockMap &Map) const 
 
int NumMyBlocks() const 
Returns the number of local blocks. 
 
int MyGlobalElements(int *MyGlobalElementList) const 
 
void GEMV(const char TRANS, const int M, const int N, const float ALPHA, const float *A, const int LDA, const float *X, const float BETA, float *Y, const int INCX=1, const int INCY=1) const 
 
double * Values() const 
Returns a pointer to the array containing the blocks. 
 
bool ConstantElementSize() const 
 
virtual const Epetra_Comm & Comm() const 
Returns a pointer to the Epetra_Comm communicator associated with this operator. 
 
bool GlobalIndicesInt() const 
 
int NumMyUnknowns() const 
Returns the number of local unknowns. 
 
EpetraExt_BlockDiagMatrix & operator=(const EpetraExt_BlockDiagMatrix &Source)
= Operator. 
 
int * FirstPointInElementList() const 
 
virtual int MyPID() const =0
 
void GETRF(const int M, const int N, float *A, const int LDA, int *IPIV, int *INFO) const 
 
virtual ~EpetraExt_BlockDiagMatrix()
Destructor. 
 
EpetraExt_BlockDiagMatrix: A class for storing distributed block matrices. 
 
int NumMyElements() const 
 
int BlockSize(int LID) const 
Returns the size of the given block. 
 
virtual void Print(std::ostream &os) const 
Print method. 
 
int NumData() const 
Returns the size of the total Data block. 
 
int FirstPointInElement(int LID) const 
 
EpetraExt_BlockDiagMatrix(const Epetra_BlockMap &Map, bool zero_out=true)
Constructor - This map is the map of the vector this can be applied to. 
 
virtual int Compute()
Computes the inverse / factorization if such is set on the list. 
 
int * ElementSizeList() const 
 
void GETRS(const char TRANS, const int N, const int NRHS, const float *A, const int LDA, const int *IPIV, float *X, const int LDX, int *INFO) const 
 
void GETRI(const int N, float *A, const int LDA, int *IPIV, float *WORK, const int *LWORK, int *INFO) const 
 
virtual int SetParameters(Teuchos::ParameterList &List)
SetParameters. 
 
const Epetra_Comm & Comm() const 
 
virtual int NumProc() const =0
 
int MaxElementSize() const 
 
int MaxMyElementSize() const 
 
void PutScalar(double value)
PutScalar function.