103 const Teuchos::RCP<const Teuchos::ParameterList>& pl = Teuchos::null)
106 TEUCHOS_TEST_FOR_EXCEPTION(
107 dae_ == Teuchos::null, std::invalid_argument,
108 "Error - Tempus::AdjointDAEJumpSolver: null DAE structure.\n");
110 if (pl != Teuchos::null) params = *pl;
112 rel_tol_ = params.get<
double>(
"Relative Tolerance");
113 max_iters_ = params.get<
int>(
"Maximum Iterations Per Alpha");
117 min_reduction_ = params.get<
double>(
"Minimum Residual Reduction");
118 verbose_ = params.get<
bool>(
"Verbose");
119 TEUCHOS_TEST_FOR_EXCEPTION(
123 std::invalid_argument,
124 "Error - Tempus::AdjointDAEJumpSolver: invalid options (need "
125 "\"Initial Alpha Factor\" > 0, \"Alpha Growth Factor\" > 1, "
126 "\"Maximum Iterations Per Alpha\" >= 1, \"Maximum Alpha Increases\" "
127 ">= 0, 0 < \"Minimum Residual Reduction\" < 1).\n");
141 const Thyra::ModelEvaluatorBase::InArgs<Scalar>& inArgs,
145 typedef Teuchos::ScalarTraits<Scalar> ST;
146 typedef Thyra::ModelEvaluatorBase MEB;
148 TEUCHOS_TEST_FOR_EXCEPTION(
149 !(dt > Scalar(0.0)), std::logic_error,
150 "Error - Tempus::AdjointDAEJumpSolver: the time step size must be "
153 RCP<Teuchos::FancyOStream> out = Teuchos::VerboseObjectBase::getDefaultOStream();
156 RCP<Thyra::LinearOpBase<Scalar> > ET = adjoint_model.create_W_op();
157 RCP<Thyra::LinearOpBase<Scalar> > AT = adjoint_model.create_W_op();
159 MEB::InArgs<Scalar> in = inArgs;
160 MEB::OutArgs<Scalar> outs = adjoint_model.createOutArgs();
161 in.set_alpha(ST::one());
162 in.set_beta(ST::zero());
164 adjoint_model.evalModel(in, outs);
165 in.set_alpha(ST::zero());
166 in.set_beta(ST::one());
168 adjoint_model.evalModel(in, outs);
171 const int num_cols = b.domain()->dim();
172 Teuchos::Array<Mag> b_norms(num_cols);
173 Thyra::norms_2(b, b_norms());
174 Thyra::assign(Teuchos::ptrFromRef(z), ST::zero());
175 if (*std::max_element(b_norms.begin(), b_norms.end()) == Teuchos::ScalarTraits<Mag>::zero())
178 RCP<MultiVector> r = b.clone_mv();
179 RCP<MultiVector> w = z.clone_mv();
180 RCP<Vector> d = Thyra::createMember(
dae_->getAlgebraicMask()->space());
187 RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
189 Thyra::assign(d.ptr(), *
dae_->getAlgebraicMask());
190 Thyra::Vp_StV(d.ptr(), alpha, *
dae_->getDifferentialMask());
195 *out <<
"Tempus::AdjointDAEJumpSolver: converged, residual " << res
196 <<
", alpha*dt = " << alpha * dt <<
", " << num_solves
197 <<
" solves" << std::endl;
201 Thyra::assign(w.ptr(), ST::zero());
202 W->solve(Thyra::NOTRANS, *r, w.ptr());
204 for (
int j = 0; j < num_cols; ++j)
205 Thyra::ele_wise_scale(*d, w->col(j).ptr());
206 Thyra::update(ST::one(), *w, Teuchos::ptrFromRef(z));
208 const Mag res_old = res;
209 res =
residual(*ET, *AT, b, z, b_norms, *r);
211 *out <<
"Tempus::AdjointDAEJumpSolver: alpha*dt = " << alpha * dt
212 <<
", iteration " << it + 1 <<
", residual " << res
219 *out <<
"WARNING - Tempus::AdjointDAEJumpSolver: no convergence, relative "
220 <<
"residual " << res <<
" > " <<
rel_tol_ <<
" after " << num_solves
221 <<
" solves (final alpha*dt = " << alpha * dt / Scalar(
alpha_growth_)
222 <<
")." << std::endl;
231 const MultiVector& z,
const Teuchos::Array<Mag>& b_norms,
234 typedef Teuchos::ScalarTraits<Scalar> ST;
235 Teuchos::RCP<MultiVector> za = z.clone_mv();
236 dae_->zeroDifferentialComponents(*za);
237 Teuchos::RCP<MultiVector> zd = z.clone_mv();
238 dae_->zeroAlgebraicComponents(*zd);
239 Thyra::assign(Teuchos::ptrFromRef(r), b);
240 AT.apply(Thyra::NOTRANS, *za, Teuchos::ptrFromRef(r), -ST::one(), ST::one());
241 ET.apply(Thyra::NOTRANS, *zd, Teuchos::ptrFromRef(r), -ST::one(), ST::one());
243 Teuchos::Array<Mag> r_norms(b_norms.size());
244 Thyra::norms_2(r, r_norms());
245 Mag res = Teuchos::ScalarTraits<Mag>::zero();
246 for (
int j = 0; j < static_cast<int>(b_norms.size()); ++j)
247 if (b_norms[j] > Teuchos::ScalarTraits<Mag>::zero())
248 res = std::max(res, r_norms[j] / b_norms[j]);