14 #include "NOX_Epetra_Interface_Jacobian.H"
15 #include "EpetraExt_BlockVector.h"
16 #include "EpetraExt_BlockUtility.h"
20 NOX::Epetra::LinearSystemSGGS::
33 det_solver(det_solver_),
35 epetraCijk(sg_parallel_data->getEpetraCijk()),
36 is_stoch_parallel(epetraCijk->isStochasticParallel()),
37 stoch_row_map(epetraCijk->getStochasticRowMap()),
38 Cijk(epetraCijk->getParallelCijk()),
39 jacInterfacePtr(iJac),
43 utils(printingParams),
44 is_parallel(epetraCijk->isStochasticParallel())
49 sg_df_block =
Teuchos::rcp(
new EpetraExt::BlockVector(*base_map, *sg_map));
50 sg_y_block =
Teuchos::rcp(
new EpetraExt::BlockVector(*base_map, *sg_map));
53 only_use_linear = linearSolverParams.
get(
"Only Use Linear Terms",
false);
54 k_limit = sg_poly->size();
55 int dim = sg_basis->dimension();
56 if (only_use_linear && sg_poly->size() > dim+1)
61 epetraCijk->getStochasticColMap();
63 Teuchos::rcp(EpetraExt::BlockUtility::GenerateBlockMap(*base_map,
67 sg_df_col =
Teuchos::rcp(
new EpetraExt::BlockVector(*base_map,
69 sg_df_tmp =
Teuchos::rcp(
new EpetraExt::BlockVector(*base_map, *sg_map));
73 NOX::Epetra::LinearSystemSGGS::
78 bool NOX::Epetra::LinearSystemSGGS::
79 applyJacobian(
const NOX::Epetra::Vector& input,
80 NOX::Epetra::Vector& result)
const
82 sg_op->SetUseTranspose(
false);
83 int status = sg_op->Apply(input.getEpetraVector(), result.getEpetraVector());
88 bool NOX::Epetra::LinearSystemSGGS::
89 applyJacobianTranspose(
const NOX::Epetra::Vector& input,
90 NOX::Epetra::Vector& result)
const
92 sg_op->SetUseTranspose(
true);
93 int status = sg_op->Apply(input.getEpetraVector(), result.getEpetraVector());
94 sg_op->SetUseTranspose(
false);
99 bool NOX::Epetra::LinearSystemSGGS::
101 const NOX::Epetra::Vector &input,
102 NOX::Epetra::Vector &result)
104 int max_iter = params.
get(
"Max Iterations",100 );
105 double sg_tol = params.
get(
"Tolerance", 1e-12);
106 bool scale_op = params.
get(
"Scale Operator by Inverse Basis Norms",
true);
109 EpetraExt::BlockVector sg_dx_block(View, *base_map, result.getEpetraVector());
110 EpetraExt::BlockVector sg_f_block(View, *base_map, input.getEpetraVector());
111 sg_dx_block.PutScalar(0.0);
114 double norm_f,norm_df;
115 sg_f_block.Norm2(&norm_f);
116 sg_op->Apply(sg_dx_block, *sg_df_block);
117 sg_df_block->Update(-1.0, sg_f_block, 1.0);
118 sg_df_block->Norm2(&norm_df);
130 while (((norm_df/norm_f)>sg_tol) && (iter<max_iter)) {
134 sg_y_block->Update(1.0, sg_f_block, 0.0);
136 sg_df_col->PutScalar(0.0);
138 for (Cijk_type::i_iterator i_it=Cijk->i_begin();
139 i_it!=Cijk->i_end(); ++i_it) {
140 int i = Stokhos::index(i_it);
141 f = sg_f_block.GetBlock(i);
142 df = sg_df_block->GetBlock(i);
143 dx = sg_dx_block.GetBlock(i);
147 params.
sublist(
"Deterministic Solver Parameters");
148 NOX::Epetra::Vector nox_df(df, NOX::Epetra::Vector::CreateView);
149 NOX::Epetra::Vector nox_dx(dx, NOX::Epetra::Vector::CreateView);
153 det_solver->applyJacobianInverse(det_solver_params, nox_df, nox_dx);
156 df->Update(1.0, *f, 0.0);
158 for (Cijk_type::ik_iterator k_it = Cijk->k_begin(i_it);
159 k_it != Cijk->k_end(i_it); ++k_it) {
160 int k = Stokhos::index(k_it);
161 if (k!=0 && k<k_limit) {
162 (*sg_poly)[k].Apply(*dx, *kx);
163 for (Cijk_type::ikj_iterator j_it = Cijk->j_begin(k_it);
164 j_it != Cijk->j_end(k_it); ++j_it) {
165 int j = Stokhos::index(j_it);
166 int j_gid = epetraCijk->GCID(j);
167 double c = Stokhos::value(j_it);
170 bool owned = epetraCijk->myGRID(j_gid);
171 if (!is_parallel || owned) {
172 sg_df_block->GetBlock(j)->Update(-c, *kx, 1.0);
173 sg_y_block->GetBlock(j)->Update(-c, *kx, 1.0);
176 sg_df_col->GetBlock(j)->Update(-c, *kx, 1.0);
181 (*sg_poly)[0].Apply(*dx, *kx);
182 sg_y_block->GetBlock(i)->Update(-1.0, *kx, 1.0);
188 sg_df_tmp->Export(*sg_df_col, *col_exporter, InsertAdd);
189 sg_df_block->Update(1.0, *sg_df_tmp, 1.0);
190 sg_y_block->Update(1.0, *sg_df_tmp, 1.0);
193 sg_y_block->Norm2(&norm_df);
194 utils.out() <<
"\t Gauss-Seidel relative residual norm at iteration "
195 << iter <<
" is " << norm_df/norm_f << std::endl;
202 bool NOX::Epetra::LinearSystemSGGS::
203 applyRightPreconditioning(
bool useTranspose,
205 const NOX::Epetra::Vector& input,
206 NOX::Epetra::Vector& result)
const
217 void NOX::Epetra::LinearSystemSGGS::
224 bool NOX::Epetra::LinearSystemSGGS::
225 computeJacobian(
const NOX::Epetra::Vector& x)
227 bool success = jacInterfacePtr->computeJacobian(x.getEpetraVector(),
229 sg_poly = sg_op->getSGPolynomial();
230 det_solver->setJacobianOperatorForSolve(sg_poly->getCoeffPtr(0));
234 bool NOX::Epetra::LinearSystemSGGS::
235 createPreconditioner(
const NOX::Epetra::Vector& x,
237 bool recomputeGraph)
const
239 EpetraExt::BlockVector sg_x_block(View, *base_map, x.getEpetraVector());
241 det_solver->createPreconditioner(*(sg_x_block.GetBlock(0)),
242 p.
sublist(
"Deterministic Solver Parameters"),
248 bool NOX::Epetra::LinearSystemSGGS::
249 destroyPreconditioner()
const
251 return det_solver->destroyPreconditioner();
254 bool NOX::Epetra::LinearSystemSGGS::
255 recomputePreconditioner(
const NOX::Epetra::Vector& x,
258 EpetraExt::BlockVector sg_x_block(View, *base_map, x.getEpetraVector());
260 det_solver->recomputePreconditioner(
261 *(sg_x_block.GetBlock(0)),
262 linearSolverParams.
sublist(
"Deterministic Solver Parameters"));
268 NOX::Epetra::LinearSystem::PreconditionerReusePolicyType
269 NOX::Epetra::LinearSystemSGGS::
270 getPreconditionerPolicy(
bool advanceReuseCounter)
272 return det_solver->getPreconditionerPolicy(advanceReuseCounter);
275 bool NOX::Epetra::LinearSystemSGGS::
276 isPreconditionerConstructed()
const
278 return det_solver->isPreconditionerConstructed();
281 bool NOX::Epetra::LinearSystemSGGS::
282 hasPreconditioner()
const
284 return det_solver->hasPreconditioner();
288 getJacobianOperator()
const
294 getJacobianOperator()
300 getGeneratedPrecOperator()
const
306 getGeneratedPrecOperator()
311 void NOX::Epetra::LinearSystemSGGS::
312 setJacobianOperatorForSolve(
const
321 void NOX::Epetra::LinearSystemSGGS::
#define TEUCHOS_FUNC_TIME_MONITOR(FUNCNAME)
T & get(ParameterList &l, const std::string &name)
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)
An abstract class to represent a generic stochastic Galerkin operator as an Epetra_Operator.
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)