12 #include "EpetraExt_BlockUtility.h"
15 Stokhos::GaussSeidelPreconditioner::
16 GaussSeidelPreconditioner(
24 label(
"Stokhos Gauss-Seidel Preconditioner"),
27 epetraCijk(epetraCijk_),
30 is_stoch_parallel(epetraCijk->isStochasticParallel()),
31 stoch_row_map(epetraCijk->getStochasticRowMap()),
32 det_solver(det_solver_),
37 Cijk(epetraCijk->getParallelCijk()),
38 is_parallel(epetraCijk->isStochasticParallel())
42 epetraCijk->getStochasticColMap();
44 Teuchos::rcp(EpetraExt::BlockUtility::GenerateBlockMap(*base_map,
51 Stokhos::GaussSeidelPreconditioner::
52 ~GaussSeidelPreconditioner()
57 Stokhos::GaussSeidelPreconditioner::
63 EpetraExt::BlockVector sg_x_block(View, *base_map, x);
64 det_solver->setJacobianOperatorForSolve(sg_poly->getCoeffPtr(0));
65 det_solver->createPreconditioner(*(sg_x_block.GetBlock(0)),
66 params->sublist(
"Deterministic Solver Parameters"),
71 Stokhos::GaussSeidelPreconditioner::
72 SetUseTranspose(
bool UseTranspose)
74 useTranspose = UseTranspose;
76 UseTranspose ==
true, std::logic_error,
77 "Stokhos::GaussSeidelPreconditioner::SetUseTranspose(): " <<
78 "Preconditioner does not support transpose!" << std::endl);
84 Stokhos::GaussSeidelPreconditioner::
87 return sg_op->Apply(Input,Result);
91 Stokhos::GaussSeidelPreconditioner::
94 int max_iter = params->get(
"Max Iterations",100 );
95 double sg_tol = params->get(
"Tolerance", 1e-12);
96 bool scale_op = params->get(
"Scale Operator by Inverse Basis Norms",
true);
97 bool only_use_linear = params->get(
"Only Use Linear Terms",
true);
102 bool made_copy =
false;
103 if (Input.Values() == Result.Values()) {
108 int k_limit = sg_poly->size();
109 int dim = sg_poly->basis()->dimension();
110 if (only_use_linear && sg_poly->size() > dim+1)
114 int m = input->NumVectors();
115 if (sg_df_block ==
Teuchos::null || sg_df_block->NumVectors() != m) {
117 Teuchos::rcp(
new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
119 Teuchos::rcp(
new EpetraExt::BlockMultiVector(*base_map, *sg_map, m));
122 sg_df_col =
Teuchos::rcp(
new EpetraExt::BlockMultiVector(*base_map,
124 sg_df_tmp =
Teuchos::rcp(
new EpetraExt::BlockMultiVector(*base_map,
130 EpetraExt::BlockMultiVector sg_dx_block(View, *base_map, Result);
131 EpetraExt::BlockMultiVector sg_f_block(View, *base_map, *input);
132 sg_dx_block.PutScalar(0.0);
135 double norm_f,norm_df;
136 sg_f_block.Norm2(&norm_f);
137 sg_op->Apply(sg_dx_block, *sg_df_block);
138 sg_df_block->Update(-1.0, sg_f_block, 1.0);
139 sg_df_block->Norm2(&norm_df);
143 sg_df_block->Update(1.0, sg_f_block, 0.0);
146 while (((norm_df/norm_f)>sg_tol) && (iter<max_iter)) {
147 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
152 sg_y_block->Update(1.0, sg_f_block, 0.0);
154 sg_df_col->PutScalar(0.0);
156 for (Cijk_type::i_iterator i_it=Cijk->i_begin();
157 i_it!=Cijk->i_end(); ++i_it) {
160 f = sg_f_block.GetBlock(i);
161 df = sg_df_block->GetBlock(i);
162 dx = sg_dx_block.GetBlock(i);
166 params->
sublist(
"Deterministic Solver Parameters");
167 for (
int col=0; col<m; col++) {
168 NOX::Epetra::Vector nox_df(
Teuchos::rcp((*df)(col),
false),
169 NOX::Epetra::Vector::CreateView);
170 NOX::Epetra::Vector nox_dx(
Teuchos::rcp((*dx)(col),
false),
171 NOX::Epetra::Vector::CreateView);
174 #ifdef STOKHOS_TEUCHOS_TIME_MONITOR
177 det_solver->applyJacobianInverse(det_solver_params, nox_df, nox_dx);
181 df->Update(1.0, *f, 0.0);
183 for (Cijk_type::ik_iterator k_it = Cijk->k_begin(i_it);
184 k_it != Cijk->k_end(i_it); ++k_it) {
186 if (k!=0 && k<k_limit) {
187 (*sg_poly)[k].Apply(*dx, *kx);
188 for (Cijk_type::ikj_iterator j_it = Cijk->j_begin(k_it);
189 j_it != Cijk->j_end(k_it); ++j_it) {
191 int j_gid = epetraCijk->GCID(j);
192 double c =
value(j_it);
195 bool owned = epetraCijk->myGRID(j_gid);
196 if (!is_parallel || owned) {
197 sg_df_block->GetBlock(j)->Update(-c, *kx, 1.0);
198 sg_y_block->GetBlock(j)->Update(-c, *kx, 1.0);
201 sg_df_col->GetBlock(j)->Update(-c, *kx, 1.0);
206 (*sg_poly)[0].Apply(*dx, *kx);
207 sg_y_block->GetBlock(i)->Update(-1.0, *kx, 1.0);
213 sg_df_tmp->Export(*sg_df_col, *col_exporter, InsertAdd);
214 sg_df_block->Update(1.0, *sg_df_tmp, 1.0);
215 sg_y_block->Update(1.0, *sg_df_tmp, 1.0);
218 sg_y_block->Norm2(&norm_df);
229 Stokhos::GaussSeidelPreconditioner::
232 return sg_op->NormInf();
237 Stokhos::GaussSeidelPreconditioner::
240 return const_cast<char*
>(label.c_str());
244 Stokhos::GaussSeidelPreconditioner::
251 Stokhos::GaussSeidelPreconditioner::
254 return sg_op->HasNormInf();
258 Stokhos::GaussSeidelPreconditioner::
264 Stokhos::GaussSeidelPreconditioner::
265 OperatorDomainMap()
const
271 Stokhos::GaussSeidelPreconditioner::
272 OperatorRangeMap()
const
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
SparseArrayIterator< index_iterator, value_iterator >::value_type index(const SparseArrayIterator< index_iterator, value_iterator > &it)
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
RCP< ParameterList > sublist(const RCP< ParameterList > ¶mList, const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual Teuchos::RCP< Stokhos::EpetraOperatorOrthogPoly > getSGPolynomial()=0
Get SG polynomial.
const Epetra_Comm & Comm() const
ScalarType f(const Teuchos::Array< ScalarType > &x, double a, double b)
SparseArrayIterator< index_iterator, value_iterator >::value_reference value(const SparseArrayIterator< index_iterator, value_iterator > &it)