// ================================================ ====== ==== ==== == = // Computes C= <me> * A int ML_Epetra::ML_RefMaxwell_11_Operator::MatrixMatrix_Multiply(const Epetra_CrsMatrix & A, Epetra_CrsMatrix **C) const { ML_Comm* comm; ML_Comm_Create(&comm); #ifdef ML_MPI const Epetra_MpiComm *epcomm = dynamic_cast<const Epetra_MpiComm*>(&(A.Comm())); // Get the MPI communicator, as it may not be MPI_COMM_W0RLD, and update the ML comm object if (epcomm) ML_Comm_Set_UsrComm(comm,epcomm->Comm()); #endif ML_Operator *C_; int rv=MatrixMatrix_Multiply(A,comm,&C_); Epetra_CrsMatrix_Wrap_ML_Operator(C_,*Comm_,*DomainMap_,C,Copy,A.IndexBase()); ML_Operator_Destroy(&C_); ML_Comm_Destroy(&comm); return rv; }/*end MatrixMatrix_Multiply*/
// ================================================ ====== ==== ==== == = //! Build the face-to-node prolongator described by Bochev, Siefert, Tuminaro, Xu and Zhu (2007). int ML_Epetra::FaceMatrixFreePreconditioner::PBuildSparsity(ML_Operator *P, Epetra_CrsMatrix *&Psparse){ /* Create wrapper to do abs(T) */ // NTS: Assume D0 has already been reindexed by now. ML_Operator* AbsFN_ML = ML_Operator_Create(ml_comm_); ML_CHK_ERR(ML_Operator_WrapEpetraCrsMatrix(const_cast<Epetra_CrsMatrix*>(&*FaceNode_Matrix_),AbsFN_ML,verbose_)); ML_Operator_Set_Getrow(AbsFN_ML,AbsFN_ML->outvec_leng,CSR_getrow_ones); /* Form abs(T) * P_n */ ML_Operator* AbsFNP = ML_Operator_Create(ml_comm_); ML_2matmult(AbsFN_ML,P,AbsFNP, ML_CSR_MATRIX); /* Wrap P_n into Epetra-land */ Epetra_CrsMatrix_Wrap_ML_Operator(AbsFNP,*Comm_,*FaceRangeMap_,&Psparse,Copy,0); /* Nuke the rows in Psparse */ if(BCfaces_.size()>0) Apply_BCsToMatrixRows(BCfaces_.get(),BCfaces_.size(),*Psparse); // Cleanup ML_Operator_Destroy(&AbsFN_ML); ML_Operator_Destroy(&AbsFNP); return 0; }