Teko  Version of the Day
 All Classes Files Functions Variables Pages
Teko_mlutils.cpp
1 #include "Teko_mlutils.hpp"
2 
3 #include <vector>
4 
5 #ifdef HAVE_MPI
6 #include "mpi.h"
7 #include "Epetra_MpiComm.h"
8 #else
9 #include "Epetra_SerialComm.h"
10 #endif
11 #include "Epetra_Vector.h"
12 
13 #include "ml_epetra_utils.h"
14 #include "ml_op_utils.h"
15 
16 #include "Thyra_EpetraLinearOp.hpp"
17 
18 #include "EpetraExt_RowMatrixOut.h"
19 
20 #include "Teuchos_XMLParameterListHelpers.hpp"
21 
22 #include "Teko_InverseFactory.hpp"
23 #include "Teko_InverseLibrary.hpp"
24 #include "Teko_Utilities.hpp"
25 #include "Teko_PreconditionerFactory.hpp"
26 #include "Teko_EpetraOperatorWrapper.hpp"
27 #include "Teko_SmootherPreconditionerFactory.hpp"
28 
29 namespace Teko {
30 namespace mlutils {
31 
32 // build a very simple row map from the ML_Operator
33 Teuchos::RCP<Epetra_Map> buildRowMap(ML_Operator *mlOp) {
34  ML_Comm *comm = mlOp->comm;
35 #ifdef ML_MPI
36  MPI_Comm mpi_comm;
37  mpi_comm = comm->USR_comm;
38  Epetra_MpiComm eComm(mpi_comm);
39 #else
40  Epetra_SerialComm eComm;
41 #endif
42 
43  // get operators row count, build map...who cares what GIDs are
44  int rowCnt = mlOp->outvec_leng;
45  return Teuchos::rcp(new Epetra_Map(-1, rowCnt, 0, eComm));
46 }
47 
51 Teuchos::RCP<Epetra_CrsMatrix> convertToCrsMatrix(ML_Operator *mlOp,
52  const Teuchos::RCP<Epetra_Map> &rowMapArg) {
53  ML_Comm *comm = mlOp->comm;
54 #ifdef ML_MPI
55  MPI_Comm mpi_comm;
56  mpi_comm = comm->USR_comm;
57  Epetra_MpiComm eComm(mpi_comm);
58 #else
59  Epetra_SerialComm eComm;
60 #endif
61 
62  // build a default row map
63  Teuchos::RCP<Epetra_Map> rowMap = rowMapArg;
64  if (rowMapArg == Teuchos::null) rowMap = buildRowMap(mlOp);
65 
66  // build lightweight CrsMatrix wrapper
67  Epetra_CrsMatrix *crsMatrixPtr = 0;
68  int maxNumNonzeros = 0;
69  double cpuTime = 0.0;
70  bool verbose = false;
71  ML_Operator2EpetraCrsMatrix(mlOp, crsMatrixPtr, maxNumNonzeros, false, cpuTime, verbose);
72 
73  return Teuchos::rcp(crsMatrixPtr);
74 }
75 
76 Teko::LinearOp buildTekoBlockOp(ML_Operator *mlOp, int level) {
77  Teko_DEBUG_SCOPE("Teko::mlutils::buildTekoBlockOp", 0);
78 
79  using Teuchos::RCP;
80 
81  int numRows = ML_Operator_BlkMatNumBlockRows(mlOp);
82  int numCols = ML_Operator_BlkMatNumBlockCols(mlOp);
83 
84  Teko::BlockedLinearOp tekoOp = Teko::createBlockedOp();
85  Teko::beginBlockFill(tekoOp, numRows, numCols);
86  for (int i = 0; i < numRows; i++) {
87  for (int j = 0; j < numCols; j++) {
88  ML_Operator *subBlock = ML_Operator_BlkMatExtract(mlOp, i, j);
89 
90  // if required construct and add a block to tekoOp
91  if (subBlock != 0) {
92  // create a CRS matrix from ML operator
93  RCP<const Epetra_CrsMatrix> eCrsMat = convertToCrsMatrix(subBlock);
94 
95 #if 0
96  std::stringstream ss;
97  ss << "A(" << level << ")_" << i << "_" << j << ".mm";
98  EpetraExt::RowMatrixToMatrixMarketFile(ss.str().c_str(),*eCrsMat);
99 #endif
100 
101  // build Teko operator, add to Teko blocked operator
102  Teko::LinearOp tekoSubBlock = Thyra::epetraLinearOp(eCrsMat);
103  Teko::setBlock(i, j, tekoOp, tekoSubBlock);
104  }
105  }
106  }
107  Teko::endBlockFill(tekoOp);
108 
109  return tekoOp.getConst();
110 }
111 
112 int smoother(ML_Smoother *mydata, int leng1, double x[], int leng2, double rhs[]) {
113  Teko_DEBUG_SCOPE("Teko::mlutils::smoother", 10);
114 
115  // std::cout << "init guess = " << mydata->init_guess << std::endl;
116 
117  // grab data object
118  SmootherData *smootherData = (struct SmootherData *)ML_Get_MySmootherData(mydata);
119 
120  Epetra_Vector X(View, smootherData->Amat->OperatorDomainMap(), x);
121  Epetra_Vector Y(View, smootherData->Amat->OperatorRangeMap(), rhs);
122 
123  smootherData->smootherOperator->Apply(Y, X);
124 
125  return 0;
126 }
127 
128 Teuchos::RCP<Teko::InverseFactory> ML_Gen_Init_Teko_Prec(const std::string smoothName,
129  const Teko::InverseLibrary &invLib) {
130  Teko_DEBUG_SCOPE("Teko::mlutils::ML_Gen_Init_Teko_Prec", 10);
131 
132  // Teuchos::RCP<Teko::RequestHandler> rh = Teuchos::rcp(new Teko::RequestHandler());
133  // Teuchos::RCP<Teko::InverseLibrary> invLib
134  // = Teko::InverseLibrary::buildFromParameterList(pl);
135  // invLib->setRequestHandler(rh);
136 
137  Teuchos::RCP<Teko::PreconditionerFactory> precFact;
138  Teuchos::RCP<Teko::InverseFactory> invFact = invLib.getInverseFactory(smoothName);
139 
140  return invFact;
141 }
142 
143 extern "C" void ML_Destroy_Smoother_Teko(void *data) {
145  delete sData;
146 }
147 
148 extern "C" int ML_Gen_Smoother_Teko(ML *ml, int level, int pre_or_post, int ntimes,
149  const Teuchos::RCP<const Teuchos::ParameterList> &tekoPL,
150  const Teuchos::RCP<const Teko::InverseLibrary> &invLib_in,
151  const std::string &inverse, bool isBlocked) {
152  Teko_DEBUG_SCOPE("Teko::mlutils::ML_Gen_Smoother_Teko", 10);
153  ML_Operator *BlkMat = &(ml->Amat[level]);
154 
155  Teuchos::RCP<const Teko::InverseLibrary> invLib;
156  if (invLib_in == Teuchos::null) {
157  Teuchos::RCP<Teko::RequestHandler> rh = Teuchos::rcp(new Teko::RequestHandler());
158  Teuchos::RCP<Teko::InverseLibrary> ncInvLib =
159  Teko::InverseLibrary::buildFromParameterList(*tekoPL);
160  ncInvLib->setRequestHandler(rh);
161 
162  invLib = ncInvLib.getConst();
163  } else {
164  // this assumes a request handler has already been set
165  invLib = invLib_in;
166  }
167 
168  Teko::LinearOp tekoAmat;
169  if (isBlocked) {
170  // build teko blocked operator
171  tekoAmat = Teko::mlutils::buildTekoBlockOp(BlkMat, level);
172  } else {
173  // build unblocked operator
174  Teuchos::RCP<const Epetra_CrsMatrix> eCrsMat = convertToCrsMatrix(BlkMat);
175  tekoAmat = Thyra::epetraLinearOp(eCrsMat);
176  }
177 
178  // Teuchos::RCP<Teko::mlutils::SmootherData> data = Teuchos::rcp(new Teko::mlutils::SmootherData);
180  data->Amat = Teuchos::rcp(new Teko::Epetra::EpetraOperatorWrapper(tekoAmat));
181 
182  // Teuchos::ParameterList pl = *Teuchos::getParametersFromXmlFile(filename);
183  Teuchos::RCP<Teko::InverseFactory> invFact = ML_Gen_Init_Teko_Prec(inverse, *invLib);
184  Teuchos::RCP<Teko::RequestHandler> rh = invFact->getRequestHandler();
185 
186  // build smoother operator
187  Teko::LinearOp precOp = Teko::buildInverse(*invFact, tekoAmat);
188  Teko::LinearOp smootherOp = Teko::buildSmootherLinearOp(tekoAmat, precOp, ntimes, true);
189 
190  // get an epetra operator wrapper
191  data->smootherOperator = Teuchos::rcp(new Teko::Epetra::EpetraOperatorWrapper(smootherOp));
192 
193  int ret_val =
194  ML_Set_Smoother(ml, level, pre_or_post, (void *)data, Teko::mlutils::smoother, NULL);
195  ml->post_smoother[level].data_destroy = ML_Destroy_Smoother_Teko;
196 
197  return ret_val;
198 }
199 
200 } // namespace mlutils
201 } // namespace Teko
Implements the Epetra_Operator interface with a Thyra LinearOperator. This enables the use of absrtac...
InverseLinearOp buildInverse(const InverseFactory &factory, const LinearOp &A)
Build an inverse operator using a factory and a linear operator.