76 TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
77 "Error, setupInOutArgs_ must be called first!\n");
78 Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs = inArgs_;
80 inArgs.set_t(exact_t);
81 Teuchos::RCP<VectorBase<Scalar> > exact_x = createMember(x_space_);
83 Thyra::DetachedVectorView<Scalar> exact_x_view(*exact_x);
86 exact_x_view[0] = t * (1.0 + 0.5 * f_ * t);
89 (c_ - f_) / (c_ * c_) * (1.0 - exp(-c_ * t)) + f_ * t / c_;
92 exact_x_view[0] = 1.0 / sqrt(k_) * sin(sqrt(k_) * t) +
93 f_ / k_ * (1.0 - cos(sqrt(k_) * t));
96 inArgs.set_x(exact_x);
97 Teuchos::RCP<VectorBase<Scalar> > exact_x_dot = createMember(x_space_);
99 Thyra::DetachedVectorView<Scalar> exact_x_dot_view(*exact_x_dot);
102 exact_x_dot_view[0] = 1.0 + f_ * t;
104 exact_x_dot_view[0] = (c_ - f_) / c_ * exp(-c_ * t) + f_ / c_;
107 exact_x_dot_view[0] =
108 cos(sqrt(k_) * t) + f_ / sqrt(k_) * sin(sqrt(k_) * t);
111 inArgs.set_x_dot(exact_x_dot);
112 Teuchos::RCP<VectorBase<Scalar> > exact_x_dot_dot = createMember(x_space_);
114 Thyra::DetachedVectorView<Scalar> exact_x_dot_dot_view(*exact_x_dot_dot);
117 exact_x_dot_dot_view[0] = f_;
119 exact_x_dot_dot_view[0] = (f_ - c_) * exp(-c_ * t);
122 exact_x_dot_dot_view[0] =
123 f_ * cos(sqrt(k_) * t) - sqrt(k_) * sin(sqrt(k_) * t);
126 inArgs.set_x_dot_dot(exact_x_dot_dot);
157 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
158 this->get_W_factory();
159 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
160 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix_mv =
161 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
true);
162 Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix_mv);
164 matrix_view(0, 0) = 1.0;
165 Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
166 Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix);
208 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
209 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs)
const
213 TEUCHOS_TEST_FOR_EXCEPTION(!isInitialized_, std::logic_error,
214 "Error, setupInOutArgs_ must be called first!\n");
216 RCP<const VectorBase<Scalar> > x_in = inArgs.get_x();
217 double beta = inArgs.get_beta();
219 TEUCHOS_TEST_FOR_EXCEPTION(
220 true, std::logic_error,
221 "\n ERROR: HarmonicOscillatorModel requires x as InArgs.\n");
223 Thyra::ConstDetachedVectorView<Scalar> x_in_view(*x_in);
226 auto myVecLength = x_in_view.subDim();
228 RCP<const VectorBase<Scalar> > x_dot_in = inArgs.get_x_dot();
229 double alpha = inArgs.get_alpha();
231 RCP<const VectorBase<Scalar> > x_dotdot_in = inArgs.get_x_dot_dot();
232 double omega = inArgs.get_W_x_dot_dot_coeff();
235 RCP<VectorBase<Scalar> > f_out = outArgs.get_f();
236 RCP<VectorBase<Scalar> > g_out = outArgs.get_g(0);
237 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
239 Scalar neg_sign = 1.0;
241 if (inArgs.get_x_dot_dot().is_null()) neg_sign = -1.0;
244 if (f_out != Teuchos::null) {
245 Thyra::DetachedVectorView<Scalar> f_out_view(*f_out);
246 for (
int i = 0; i < myVecLength; i++) {
249 if (x_dotdot_in != Teuchos::null) {
250 Thyra::ConstDetachedVectorView<Scalar> x_dotdot_in_view(*x_dotdot_in);
251 for (
int i = 0; i < myVecLength; i++) {
252 f_out_view[i] = x_dotdot_in_view[i] - f_out_view[i];
255 if (x_dot_in != Teuchos::null) {
256 Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view(*x_dot_in);
257 for (
int i = 0; i < myVecLength; i++) {
258 f_out_view[i] += neg_sign * c_ * x_dot_in_view[i];
261 if (x_in != Teuchos::null) {
262 for (
int i = 0; i < myVecLength; i++) {
263 f_out_view[i] += neg_sign * k_ * x_in_view[i];
269 if (W_out != Teuchos::null) {
270 RCP<Thyra::MultiVectorBase<Scalar> > matrix =
271 Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
true);
272 Thyra::DetachedMultiVectorView<Scalar> matrix_view(*matrix);
274 TEUCHOS_TEST_FOR_EXCEPTION(
275 true, std::logic_error,
276 "\n ERROR: omega = 0 in HarmonicOscillatorModel!\n");
278 matrix_view(0, 0) = omega;
279 if (x_dot_in != Teuchos::null) {
280 matrix_view(0, 0) += neg_sign * c_ * alpha;
282 if (x_in != Teuchos::null) {
283 matrix_view(0, 0) += neg_sign * k_ * beta;
289 if (g_out != Teuchos::null) {
290 Thyra::DetachedVectorView<Scalar> g_out_view(*g_out);
291 g_out_view[0] = Thyra::sum(*x_in) / vecLength_;
331 if (isInitialized_)
return;
334 Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
335 inArgs.setModelEvalDescription(this->description());
337 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
338 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
339 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot_dot);
340 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
341 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_W_x_dot_dot_coeff);
342 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
343 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
347 Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
348 outArgs.setModelEvalDescription(this->description());
349 outArgs.set_Np_Ng(0, numResponses_);
351 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
352 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
360 nominalValues_ = inArgs_;
361 nominalValues_.set_t(0.0);
362 nominalValues_.set_x(x_vec_);
363 nominalValues_.set_x_dot(x_dot_vec_);
364 nominalValues_.set_x_dot_dot(x_dot_dot_vec_);
366 isInitialized_ =
true;
371 Teuchos::RCP<Teuchos::ParameterList>
const ¶mList)
374 using Teuchos::ParameterList;
376 RCP<ParameterList> tmpPL =
377 Teuchos::rcp(
new ParameterList(
"HarmonicOscillatorModel"));
378 if (paramList != Teuchos::null) tmpPL = paramList;
379 tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
380 this->setMyParamList(tmpPL);
381 RCP<ParameterList> pl = this->getMyNonconstParamList();
382 c_ = get<Scalar>(*pl,
"Damping coeff c");
383 f_ = get<Scalar>(*pl,
"Forcing coeff f");
384 k_ = get<Scalar>(*pl,
"x coeff k");
385 m_ = get<Scalar>(*pl,
"Mass coeff m");
387 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
388 "Error: invalid value of Mass coeff m = "
389 << m_ <<
"! Mass coeff m must be > 0.\n");
392 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
393 "Error: invalid value of x coeff k = "
394 << k_ <<
"! x coeff k must be >= 0.\n");
396 if ((k_ > 0.0) && (c_ != 0.0)) {
397 TEUCHOS_TEST_FOR_EXCEPTION(
398 true, std::logic_error,
399 "Error: HarmonicOscillator model only supports x coeff k > 0 when "
400 "Damping coeff c = 0. You have "
401 <<
"specified x coeff k = " << k_ <<
" and Damping coeff c = " << c_