// ====================================================================== Operator GetTranspose(const Operator& A, const bool byrow = true) { ML_Operator* ML_transp; ML_transp = ML_Operator_Create(GetML_Comm()); if (byrow) ML_Operator_Transpose_byrow(A.GetML_Operator(),ML_transp); else ML_Operator_Transpose(A.GetML_Operator(),ML_transp); Operator transp(A.GetRangeSpace(),A.GetDomainSpace(), ML_transp,true); return(transp); }
// ====================================================================== Operator GetJacobiIterationOperator(const Operator& Amat, double Damping) { struct ML_AGG_Matrix_Context* widget = new struct ML_AGG_Matrix_Context; widget->near_bdry = 0; widget->aggr_info = 0; widget->drop_tol = 0.0; widget->Amat = Amat.GetML_Operator(); widget->omega = Damping; ML_Operator* tmp_ML = ML_Operator_Create(GetML_Comm()); ML_Operator_Set_ApplyFuncData(tmp_ML, widget->Amat->invec_leng, widget->Amat->outvec_leng, widget, widget->Amat->matvec->Nrows, NULL, 0); tmp_ML->data_destroy = widget_destroy; ML_Operator_Set_Getrow(tmp_ML, widget->Amat->getrow->Nrows, ML_AGG_JacobiSmoother_Getrows); // Creates a new copy of pre_comm, so that the old pre_comm // can be destroyed without worry ML_CommInfoOP_Clone(&(tmp_ML->getrow->pre_comm), widget->Amat->getrow->pre_comm); Operator tmp(Amat.GetDomainSpace(), Amat.GetRangeSpace(), tmp_ML, true, Amat.GetRCPOperatorBox()); return(tmp); }
// ====================================================================== double MaxEigPowerMethod(const Operator& Op, const bool DiagonalScaling) { ML_Krylov *kdata; double MaxEigen; kdata = ML_Krylov_Create(GetML_Comm()); if (DiagonalScaling == false) kdata->ML_dont_scale_by_diag = ML_TRUE; else kdata->ML_dont_scale_by_diag = ML_FALSE; ML_Krylov_Set_PrintFreq(kdata, 0); ML_Krylov_Set_ComputeNonSymEigenvalues(kdata); ML_Krylov_Set_Amatrix(kdata, Op.GetML_Operator()); ML_Krylov_Solve(kdata, Op.GetML_Operator()->outvec_leng, NULL, NULL); MaxEigen = ML_Krylov_Get_MaxEigenvalue(kdata); ML_Krylov_Destroy(&kdata); return(MaxEigen); }
Operator GetRAP(const Operator& R, const Operator& A, const Operator& P) { ML_Operator* Rmat = R.GetML_Operator(); ML_Operator* Amat = A.GetML_Operator(); ML_Operator* Pmat = P.GetML_Operator(); ML_Operator* result = 0; result = ML_Operator_Create (Rmat->comm); /* The fixing of coarse matrix only works if it is in MSR format */ int myMatrixType = ML_MSR_MATRIX; ML_rap(Rmat, Amat, Pmat, result, myMatrixType); result->num_PDEs = Pmat->num_PDEs; #ifdef MB_MODIF_QR ML_fixCoarseMtx(result, myMatrixType); #endif/*MB_MODIF_QR*/ Operator op(P.GetDomainSpace(),P.GetDomainSpace(), result); return(op); }
// ====================================================================== Operator GetScaledOperator(const Operator& A, const double alpha) { ML_Operator* ScaledA = 0; ScaledA = ML_Operator_ExplicitlyScale(A.GetML_Operator(), (double)alpha); if (ScaledA == 0) ML_THROW("ML_Operator_ExplicitlyScale returned 0", -1); Operator res; res.Reshape(A.GetDomainSpace(), A.GetRangeSpace(), ScaledA, true, A.GetRCPOperatorBox()); return(res); }
// ====================================================================== double MaxEigAnasazi(const Operator& Op, const bool DiagonalScaling) { double MaxEigen = 0.0; #if defined(HAVE_ML_EPETRA) && defined(HAVE_ML_ANASAxI) && defined(HAVE_ML_TEUCHOS) bool DiagScal; if (DiagonalScaling) DiagScal = ML_TRUE; else DiagScal = ML_FALSE; ML_Anasazi_Get_SpectralNorm_Anasazi(Op.GetML_Operator(), 0, 10, 1e-5, ML_FALSE, DiagScal, &MaxEigen); #else //ML_THROW("Configure w/ --enable-epetra --enable-anasazi --enable-teuchos", -1); ML_THROW("Anasazi is no longer supported", -1); #endif return(MaxEigen); }
// ====================================================================== MultiVector GetDiagonal(const Operator& A, const int offset) { // FIXME if (A.GetDomainSpace() != A.GetRangeSpace()) ML_THROW("Currently only square matrices are supported", -1); MultiVector D(A.GetDomainSpace()); D = 0.0; ML_Operator* matrix = A.GetML_Operator(); if (matrix->getrow == NULL) ML_THROW("getrow() not set!", -1); int row_length; int allocated = 128; int* bindx = (int *) ML_allocate(allocated*sizeof(int )); double* val = (double *) ML_allocate(allocated*sizeof(double)); for (int i = 0 ; i < matrix->getrow->Nrows; i++) { int GlobalRow = A.GetGRID(i); ML_get_matrix_row(matrix, 1, &i, &allocated, &bindx, &val, &row_length, 0); for (int j = 0; j < row_length; j++) { D(i) = 0.0; if (A.GetGCID(bindx[j]) == GlobalRow + offset) { D(i) = val[j]; break; } } } ML_free(val); ML_free(bindx); return (D); }
// ====================================================================== double MaxEigAnorm(const Operator& Op, const bool DiagonalScaling) { return(ML_Operator_MaxNorm(Op.GetML_Operator(), DiagonalScaling)); }
// ====================================================================== void GetPtent(const Operator& A, Teuchos::ParameterList& List, const MultiVector& ThisNS, Operator& Ptent, MultiVector& NextNS) { std::string CoarsenType = List.get("aggregation: type", "Uncoupled"); /* old version int NodesPerAggr = List.get("aggregation: per aggregate", 64); */ double Threshold = List.get("aggregation: threshold", 0.0); int NumPDEEquations = List.get("PDE equations", 1); ML_Aggregate* agg_object; ML_Aggregate_Create(&agg_object); ML_Aggregate_Set_MaxLevels(agg_object,2); ML_Aggregate_Set_StartLevel(agg_object,0); ML_Aggregate_Set_Threshold(agg_object,Threshold); //agg_object->curr_threshold = 0.0; ML_Operator* ML_Ptent = 0; ML_Ptent = ML_Operator_Create(GetML_Comm()); if (ThisNS.GetNumVectors() == 0) ML_THROW("zero-dimension null space", -1); int size = ThisNS.GetMyLength(); double* null_vect = 0; ML_memory_alloc((void **)(&null_vect), sizeof(double) * size * ThisNS.GetNumVectors(), "ns"); int incr = 1; for (int v = 0 ; v < ThisNS.GetNumVectors() ; ++v) DCOPY_F77(&size, (double*)ThisNS.GetValues(v), &incr, null_vect + v * ThisNS.GetMyLength(), &incr); ML_Aggregate_Set_NullSpace(agg_object, NumPDEEquations, ThisNS.GetNumVectors(), null_vect, ThisNS.GetMyLength()); if (CoarsenType == "Uncoupled") agg_object->coarsen_scheme = ML_AGGR_UNCOUPLED; else if (CoarsenType == "Uncoupled-MIS") agg_object->coarsen_scheme = ML_AGGR_HYBRIDUM; else if (CoarsenType == "MIS") { /* needed for MIS, otherwise it sets the number of equations to * the null space dimension */ agg_object->max_levels = -7; agg_object->coarsen_scheme = ML_AGGR_MIS; } else if (CoarsenType == "METIS") agg_object->coarsen_scheme = ML_AGGR_METIS; else { ML_THROW("Requested aggregation scheme (" + CoarsenType + ") not recognized", -1); } int NextSize = ML_Aggregate_Coarsen(agg_object, A.GetML_Operator(), &ML_Ptent, GetML_Comm()); /* This is the old version int NextSize; if (CoarsenType == "Uncoupled") { NextSize = ML_Aggregate_CoarsenUncoupled(agg_object, A.GetML_Operator(), } else if (CoarsenType == "MIS") { NextSize = ML_Aggregate_CoarsenMIS(agg_object, A.GetML_Operator(), &ML_Ptent, GetML_Comm()); } else if (CoarsenType == "METIS") { ML ml_object; ml_object.ML_num_levels = 1; // crap for line below ML_Aggregate_Set_NodesPerAggr(&ml_object,agg_object,0,NodesPerAggr); NextSize = ML_Aggregate_CoarsenMETIS(agg_object, A.GetML_Operator(), &ML_Ptent, GetML_Comm()); } else { ML_THROW("Requested aggregation scheme (" + CoarsenType + ") not recognized", -1); } */ ML_Operator_ChangeToSinglePrecision(ML_Ptent); int NumMyElements = NextSize; Space CoarseSpace(-1,NumMyElements); Ptent.Reshape(CoarseSpace,A.GetRangeSpace(),ML_Ptent,true); assert (NextSize * ThisNS.GetNumVectors() != 0); NextNS.Reshape(CoarseSpace, ThisNS.GetNumVectors()); size = NextNS.GetMyLength(); for (int v = 0 ; v < NextNS.GetNumVectors() ; ++v) DCOPY_F77(&size, agg_object->nullspace_vect + v * size, &incr, NextNS.GetValues(v), &incr); ML_Aggregate_Destroy(&agg_object); ML_memory_free((void**)(&null_vect)); }