54 label(
"Stokhos Approximate Gauss-Seidel Preconditioner"),
57 epetraCijk(epetraCijk_),
60 prec_factory(prec_factory_),
65 Cijk(epetraCijk->getParallelCijk()),
68 only_use_linear(
true),
72 scale_op = params_->
get(
"Scale Operator by Inverse Basis Norms",
true);
73 symmetric = params_->
get(
"Symmetric Gauss-Seidel",
false);
89 mean_prec = prec_factory->compute(sg_poly->getCoeffPtr(0));
90 label = std::string(
"Stokhos Approximate Gauss-Seidel Preconditioner:\n") +
91 std::string(
" ***** ") +
92 std::string(mean_prec->Label());
99 useTranspose = UseTheTranspose;
100 sg_op->SetUseTranspose(UseTheTranspose);
101 mean_prec->SetUseTranspose(UseTheTranspose);
110 return sg_op->Apply(Input, Result);
117 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
124 bool made_copy =
false;
131 if (mat_vec_tmp == Teuchos::null || mat_vec_tmp->NumVectors() != m)
133 if (rhs_block == Teuchos::null || rhs_block->NumVectors() != m)
135 Teuchos::rcp(
new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
138 EpetraExt::BlockMultiVector input_block(
View, *base_map, *input);
139 EpetraExt::BlockMultiVector result_block(
View, *base_map, Result);
141 result_block.PutScalar(0.0);
143 int k_limit = sg_poly->size();
145 k_limit = sg_poly->basis()->dimension() + 1;
148 rhs_block->Update(1.0, input_block, 0.0);
151 i_it!=Cijk->i_end(); ++i_it) {
157 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
160 mean_prec->ApplyInverse(*(rhs_block->GetBlock(i)), *res_i);
163 int i_gid = epetraCijk->GRID(i);
165 k_it != Cijk->k_end(i_it); ++k_it) {
167 if (k!=0 && k<k_limit) {
168 bool do_mat_vec =
false;
170 j_it != Cijk->j_end(k_it); ++j_it) {
172 int j_gid = epetraCijk->GCID(
j);
174 bool on_proc = epetraCijk->myGRID(j_gid);
182 (*sg_poly)[k].Apply(*res_i, *mat_vec_tmp);
184 j_it != Cijk->j_end(k_it); ++j_it) {
186 int j_gid = epetraCijk->GCID(
j);
187 double c = value(j_it);
195 bool on_proc = epetraCijk->myGRID(j_gid);
197 rhs_block->GetBlock(
j)->Update(-c, *mat_vec_tmp, 1.0);
210 i_it!=Cijk->i_rend(); ++i_it) {
216 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
219 mean_prec->ApplyInverse(*(rhs_block->GetBlock(i)), *res_i);
222 int i_gid = epetraCijk->GRID(i);
224 k_it != Cijk->k_end(i_it); ++k_it) {
226 if (k!=0 && k<k_limit) {
227 bool do_mat_vec =
false;
229 j_it != Cijk->j_end(k_it); ++j_it) {
231 int j_gid = epetraCijk->GCID(
j);
233 bool on_proc = epetraCijk->myGRID(j_gid);
241 (*sg_poly)[k].Apply(*res_i, *mat_vec_tmp);
243 j_it != Cijk->j_end(k_it); ++j_it) {
245 int j_gid = epetraCijk->GCID(
j);
246 double c = value(j_it);
250 bool on_proc = epetraCijk->myGRID(j_gid);
252 rhs_block->GetBlock(
j)->Update(-c, *mat_vec_tmp, 1.0);
272 return sg_op->NormInf();
280 return const_cast<char*>(label.c_str());
294 return sg_op->HasNormInf();