// ================================================ ====== ==== ==== == = // Forms the coarse matrix, given the prolongator int ML_Epetra::FaceMatrixFreePreconditioner::FormCoarseMatrix() { CoarseMat_ML = ML_Operator_Create(ml_comm_); CoarseMat_ML->data_destroy=free; ML_Operator *Temp_ML=0; ML_Operator *R= ML_Operator_Create(ml_comm_); ML_Operator *P= ML_Operator_Create(ml_comm_); /* Build ML_Operator version of Prolongator_, Restriction Operator */ ML_CHK_ERR(ML_Operator_WrapEpetraCrsMatrix(Prolongator_,P,verbose_)); P->num_rigid=P->num_PDEs=dim; //NTS: ML_CHK_ERR won't work on this: it returns 1 ML_Operator_Transpose_byrow(P, R); /* OPTION: Disable the addon */ const Epetra_CrsMatrix *Op11crs = dynamic_cast<const Epetra_CrsMatrix*>(&*Operator_); const Epetra_Operator_With_MatMat *Op11mm = dynamic_cast<const Epetra_Operator_With_MatMat*>(&*Operator_); /* Do the A*P with or without addon*/ if(Op11crs){ if(verbose_ && !Comm_->MyPID()) printf("FMFP: Running *without* addon\n"); ML_Operator *SM_ML = ML_Operator_Create(ml_comm_); Temp_ML = ML_Operator_Create(ml_comm_); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)Op11crs,SM_ML,verbose_); ML_2matmult(SM_ML,P,Temp_ML,ML_CSR_MATRIX); ML_Operator_Destroy(&SM_ML); } else if(Op11mm){ if(verbose_ && !Comm_->MyPID()) printf("FMFP: Running with addon\n"); ML_CHK_ERR(Op11mm->MatrixMatrix_Multiply(*Prolongator_,ml_comm_,&Temp_ML)); } else{ if(!Comm_->MyPID()) printf("ERROR: FMFP Illegal Operator\n"); delete R; ML_CHK_ERR(-1); } /* Do R * AP */ R->num_rigid=R->num_PDEs=dim; ML_2matmult_block(R, Temp_ML,CoarseMat_ML,ML_CSR_MATRIX); /* Wrap to Epetra-land */ int nnz=100; double time; ML_Operator2EpetraCrsMatrix(CoarseMat_ML,CoarseMatrix,nnz,true,time,0,verbose_); // NTS: This is a hack to get around the sticking ones on the diagonal issue; /* Cleanup */ ML_Operator_Destroy(&P); ML_Operator_Destroy(&R); ML_Operator_Destroy(&Temp_ML); ML_Operator_Destroy(&CoarseMat_ML);CoarseMat_ML=0;//HAX return 0; }/*end FormCoarseMatrix*/
// ================================================ ====== ==== ==== == = // Computes C= A^T * <me> * A. OptimizeStorage *must* be called for both A and the // matrices in *this, before this routine can work. int ML_Epetra::ML_RefMaxwell_11_Operator::PtAP(const Epetra_CrsMatrix & P, ML_Comm *comm, ML_Operator **C) const{ ML_Operator *SM_ML,*P_ML,*R_ML,*PtSMP_ML,*temp1,*temp2,*opwrap,*D0_M1_P_ML; /* General Stuff */ ML_Comm* temp = global_comm; P_ML = ML_Operator_Create(comm); R_ML = ML_Operator_Create(comm);; ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)&P,P_ML); ML_Operator_Transpose_byrow(P_ML,R_ML); /* Do the SM part */ SM_ML = ML_Operator_Create(comm); temp1 = ML_Operator_Create(comm); PtSMP_ML = ML_Operator_Create(comm); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)SM_Matrix_,SM_ML); ML_2matmult(SM_ML,P_ML,temp1,ML_CSR_MATRIX); ML_2matmult_block(R_ML,temp1,PtSMP_ML,ML_CSR_MATRIX); ML_Operator_Destroy(&temp1); ML_Operator_Destroy(&SM_ML); #ifdef MANUALLY_TRANSPOSE_D0 ML_Operator_Destroy(&R_ML); #endif ML_Matrix_Print(PtSMP_ML,*Comm_,*RangeMap_,"ptsmp.dat"); #ifdef MANUALLY_TRANSPOSE_D0 /* Do the Addon: Step #1: M1 * P*/ opwrap = ML_Operator_Create(comm); temp1 = ML_Operator_Create(comm); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)Addon_Matrix_[4],opwrap); ML_2matmult(opwrap,P_ML,temp1,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); ML_Operator_Destroy(&P_ML); /* Do the Addon: Step #2: D0^T *(M1 * P)*/ opwrap = ML_Operator_Create(comm); D0_M1_P_ML = ML_Operator_Create(comm); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)Addon_Matrix_[3],opwrap); ML_2matmult(opwrap,temp1,D0_M1_P_ML,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); ML_Operator_Destroy(&temp1); /* Do the Addon: Step #3: M0^{-1} * (D0^T * M1 * P)*/ opwrap = ML_Operator_Create(comm); temp1 = ML_Operator_Create(comm); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)Addon_Matrix_[2],opwrap); ML_2matmult(opwrap,D0_M1_P_ML,temp1,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); /* Do the Addon: Step #4: Transpose (D0^T * M1 * P) & multiply by output from Step 3*/ opwrap = ML_Operator_Create(comm); temp2 = ML_Operator_Create(comm); ML_Operator_Transpose_byrow(D0_M1_P_ML,opwrap); ML_2matmult(opwrap,temp1,temp2,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); ML_Operator_Destroy(&temp1); ML_Operator_Destroy(&D0_M1_P_ML); ML_Matrix_Print(temp2,*Comm_,*RangeMap_,"pt_add_p.dat"); #else ML_Operator *P_M1_D0_ML; /* Do the Addon: Step #1: P^T * M1 */ opwrap = ML_Operator_Create(comm); temp1 = ML_Operator_Create(comm); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)Addon_Matrix_[0],opwrap); ML_2matmult_block(R_ML,opwrap,temp1,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); ML_Operator_Destroy(&P_ML); ML_Operator_Destroy(&R_ML); /* Do the Addon: Step #2: (P^T * M1) * D0*/ opwrap = ML_Operator_Create(comm); P_M1_D0_ML = ML_Operator_Create(comm); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)Addon_Matrix_[1],opwrap); ML_2matmult_block(temp1,opwrap,P_M1_D0_ML,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); ML_Operator_Destroy(&temp1); /* Do the Addon: Step #3: (P^T * M1 * D0) * M0^{-1} */ opwrap = ML_Operator_Create(comm); temp1 = ML_Operator_Create(comm); ML_Operator_WrapEpetraCrsMatrix((Epetra_CrsMatrix*)Addon_Matrix_[2],opwrap); ML_2matmult(P_M1_D0_ML,opwrap,temp1,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); /* Do the Addon: Step #4: Transpose (P^T * M1 * D0) & multiply by output from Step 3*/ opwrap = ML_Operator_Create(comm); temp2 = ML_Operator_Create(comm); ML_Operator_Transpose_byrow(P_M1_D0_ML,opwrap); ML_2matmult(temp1,opwrap,temp2,ML_CSR_MATRIX); ML_Operator_Destroy(&opwrap); ML_Operator_Destroy(&temp1); ML_Operator_Destroy(&P_M1_D0_ML); ML_Matrix_Print(temp2,*Comm_,*RangeMap_,"pt_add_p_rev.dat"); #endif /* Add the matrices together */ ML_Operator_Add(PtSMP_ML,temp2,*C,ML_CSR_MATRIX,1.0); ML_Matrix_Print(*C,*Comm_,*RangeMap_,"ptap.dat"); /* Cleanup */ global_comm = temp; ML_Operator_Destroy(&temp2); ML_Operator_Destroy(&PtSMP_ML); return 0; }