9 #ifndef TEMPUS_TEST_HARMONIC_OSCILLATOR_MODEL_IMPL_HPP
10 #define TEMPUS_TEST_HARMONIC_OSCILLATOR_MODEL_IMPL_HPP
12 #include "Teuchos_StandardParameterEntryValidators.hpp"
14 #include "Thyra_DefaultSpmdVectorSpace.hpp"
15 #include "Thyra_DetachedVectorView.hpp"
16 #include "Thyra_DetachedMultiVectorView.hpp"
17 #include "Thyra_DefaultSerialDenseLinearOpWithSolveFactory.hpp"
18 #include "Thyra_DefaultMultiVectorLinearOpWithSolve.hpp"
19 #include "Thyra_DefaultLinearOpSource.hpp"
20 #include "Thyra_VectorStdOps.hpp"
26 template<
class Scalar>
29 out_(
Teuchos::VerboseObjectBase::getDefaultOStream())
33 *
out_ <<
"\n\nDamping coeff c = " <<
c_ <<
"\n";
34 *
out_ <<
"Forcing coeff f = " <<
f_ <<
"\n";
35 *
out_ <<
"x coeff k = " <<
k_ <<
"\n";
36 *
out_ <<
"Mass coeff m = " <<
m_ <<
"\n";
46 Thyra::put_scalar(0.0,
x_vec_.ptr());
66 template<
class Scalar>
67 Thyra::ModelEvaluatorBase::InArgs<Scalar>
71 using Thyra::VectorBase;
72 TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
73 "Error, setupInOutArgs_ must be called first!\n");
74 Thyra::ModelEvaluatorBase::InArgs<Scalar> inArgs = inArgs_;
76 inArgs.set_t(exact_t);
77 Teuchos::RCP<VectorBase<Scalar> > exact_x = createMember(x_space_);
79 Thyra::DetachedVectorView<Scalar> exact_x_view(*exact_x);
82 exact_x_view[0] = t*(1.0+0.5*f_*t);
84 exact_x_view[0] = (c_-f_)/(c_*c_)*(1.0-exp(-c_*t))
88 exact_x_view[0] = 1.0/sqrt(k_)*sin(sqrt(k_)*t) + f_/k_*(1.0-cos(sqrt(k_)*t));
91 inArgs.set_x(exact_x);
92 Teuchos::RCP<VectorBase<Scalar> > exact_x_dot = createMember(x_space_);
94 Thyra::DetachedVectorView<Scalar> exact_x_dot_view(*exact_x_dot);
97 exact_x_dot_view[0] = 1.0+f_*t;
99 exact_x_dot_view[0] = (c_-f_)/c_*exp(-c_*t)+f_/c_;
102 exact_x_dot_view[0] = cos(sqrt(k_)*t) + f_/sqrt(k_)*sin(sqrt(k_)*t);
105 inArgs.set_x_dot(exact_x_dot);
106 Teuchos::RCP<VectorBase<Scalar> > exact_x_dot_dot = createMember(x_space_);
108 Thyra::DetachedVectorView<Scalar> exact_x_dot_dot_view(*exact_x_dot_dot);
111 exact_x_dot_dot_view[0] = f_;
113 exact_x_dot_dot_view[0] = (f_-c_)*exp(-c_*t);
116 exact_x_dot_dot_view[0] = f_*cos(sqrt(k_)*t) - sqrt(k_)*sin(sqrt(k_)*t);
119 inArgs.set_x_dot_dot(exact_x_dot_dot);
123 template<
class Scalar>
124 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
132 template<
class Scalar>
133 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
141 template<
class Scalar>
142 Thyra::ModelEvaluatorBase::InArgs<Scalar>
146 TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
147 "Error, setupInOutArgs_ must be called first!\n");
148 return nominalValues_;
152 template<
class Scalar>
153 Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> >
157 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory = this->get_W_factory();
158 Teuchos::RCP<Thyra::LinearOpBase<Scalar> > matrix = this->create_W_op();
159 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix_mv = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(matrix,
true);
160 Thyra::DetachedMultiVectorView<Scalar> matrix_view( *matrix_mv );
162 matrix_view(0,0) = 1.0;
163 Teuchos::RCP<Thyra::LinearOpWithSolveBase<Scalar> > W =
164 Thyra::linearOpWithSolve<Scalar>(*W_factory, matrix );
169 template<
class Scalar>
170 Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
174 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > matrix = Thyra::createMembers(x_space_, vecLength_);
179 template<
class Scalar>
180 Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
184 Teuchos::RCP<Thyra::LinearOpWithSolveFactoryBase<Scalar> > W_factory =
185 Thyra::defaultSerialDenseLinearOpWithSolveFactory<Scalar>();
190 template<
class Scalar>
191 Thyra::ModelEvaluatorBase::InArgs<Scalar>
203 template<
class Scalar>
204 Thyra::ModelEvaluatorBase::OutArgs<Scalar>
213 template<
class Scalar>
217 const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
218 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs
222 using Thyra::VectorBase;
223 TEUCHOS_TEST_FOR_EXCEPTION( !isInitialized_, std::logic_error,
224 "Error, setupInOutArgs_ must be called first!\n");
226 RCP<const VectorBase<Scalar> > x_in = inArgs.get_x();
227 double beta = inArgs.get_beta();
229 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
230 "\n ERROR: HarmonicOscillatorModel requires x as InArgs.\n");
232 Thyra::ConstDetachedVectorView<Scalar> x_in_view( *x_in );
234 auto myVecLength = x_in_view.subDim();
236 RCP<const VectorBase<Scalar> > x_dot_in = inArgs.get_x_dot();
237 double alpha = inArgs.get_alpha();
239 RCP<const VectorBase<Scalar> > x_dotdot_in = inArgs.get_x_dot_dot();
240 double omega = inArgs.get_W_x_dot_dot_coeff();
243 RCP<VectorBase<Scalar> > f_out = outArgs.get_f();
244 RCP<VectorBase<Scalar> > g_out = outArgs.get_g(0);
245 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
247 Scalar neg_sign = 1.0;
249 if (inArgs.get_x_dot_dot().is_null()) neg_sign = -1.0;
252 if (f_out != Teuchos::null) {
253 Thyra::DetachedVectorView<Scalar> f_out_view( *f_out );
254 for (
int i=0; i<myVecLength; i++) {
257 if (x_dotdot_in != Teuchos::null) {
258 Thyra::ConstDetachedVectorView<Scalar> x_dotdot_in_view( *x_dotdot_in);
259 for (
int i=0; i<myVecLength; i++) {
260 f_out_view[i] = x_dotdot_in_view[i] - f_out_view[i];
263 if (x_dot_in != Teuchos::null) {
264 Thyra::ConstDetachedVectorView<Scalar> x_dot_in_view( *x_dot_in);
265 for (
int i=0; i<myVecLength; i++) {
266 f_out_view[i] += neg_sign*c_*x_dot_in_view[i];
269 if (x_in != Teuchos::null) {
270 Thyra::ConstDetachedVectorView<Scalar> x_in_view( *x_in);
271 for (
int i=0; i<myVecLength; i++) {
272 f_out_view[i] += neg_sign*k_*x_in_view[i];
278 if (W_out != Teuchos::null) {
279 RCP<Thyra::MultiVectorBase<Scalar> > matrix = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
true);
280 Thyra::DetachedMultiVectorView<Scalar> matrix_view( *matrix );
282 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
283 "\n ERROR: omega = 0 in HarmonicOscillatorModel!\n");
285 matrix_view(0,0) = omega;
286 if (x_dot_in != Teuchos::null) {
287 matrix_view(0,0) += neg_sign*c_*alpha;
289 if (x_in != Teuchos::null) {
290 matrix_view(0,0) += neg_sign*k_*beta;
296 if (g_out != Teuchos::null) {
297 Thyra::DetachedVectorView<Scalar> g_out_view(*g_out);
298 g_out_view[0] = Thyra::sum(*x_in)/vecLength_;
302 template<
class Scalar>
303 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
307 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
308 "\n Error! HarmonicOscillatorModel::get_p_space() is not supported!\n");
309 return Teuchos::null;
312 template<
class Scalar>
313 Teuchos::RCP<const Teuchos::Array<std::string> >
317 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
318 "\n Error! HarmonicOscillatorModel::get_p_names() is not supported!\n");
319 return Teuchos::null;
322 template<
class Scalar>
323 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
327 TEUCHOS_TEST_FOR_EXCEPTION(j != 0, std::logic_error,
328 "\n Error! HarmonicOscillatorModel::get_g_space() only " <<
329 " supports 1 parameter vector. Supplied index l = " <<
336 template<
class Scalar>
341 if (isInitialized_)
return;
344 Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
345 inArgs.setModelEvalDescription(this->description());
347 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
348 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
349 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot_dot);
350 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
351 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_W_x_dot_dot_coeff);
352 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
353 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
357 Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
358 outArgs.setModelEvalDescription(this->description());
359 outArgs.set_Np_Ng(0, numResponses_);
361 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
362 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
370 nominalValues_ = inArgs_;
371 nominalValues_.set_t(0.0);
372 nominalValues_.set_x(x_vec_);
373 nominalValues_.set_x_dot(x_dot_vec_);
374 nominalValues_.set_x_dot_dot(x_dot_dot_vec_);
376 isInitialized_ =
true;
380 template<
class Scalar>
387 using Teuchos::ParameterList;
388 RCP<ParameterList> tmpPL = Teuchos::rcp(
new ParameterList(
"HarmonicOscillatorModel"));
389 if (paramList != Teuchos::null) tmpPL = paramList;
390 tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
391 this->setMyParamList(tmpPL);
392 RCP<ParameterList> pl = this->getMyNonconstParamList();
393 c_ = get<Scalar>(*pl,
"Damping coeff c");
394 f_ = get<Scalar>(*pl,
"Forcing coeff f");
395 k_ = get<Scalar>(*pl,
"x coeff k");
396 m_ = get<Scalar>(*pl,
"Mass coeff m");
398 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
399 "Error: invalid value of Mass coeff m = " << m_ <<
"! Mass coeff m must be > 0.\n");
402 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
403 "Error: invalid value of x coeff k = " << k_ <<
"! x coeff k must be >= 0.\n");
405 if ((k_ > 0.0) && (c_ != 0.0)) {
406 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
407 "Error: HarmonicOscillator model only supports x coeff k > 0 when Damping coeff c = 0. You have "
408 <<
"specified x coeff k = " << k_ <<
" and Damping coeff c = " << c_ <<
".\n");
412 template<
class Scalar>
413 Teuchos::RCP<const Teuchos::ParameterList>
417 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
418 if (is_null(validPL)) {
419 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
421 Teuchos::setDoubleParameter(
422 "Damping coeff c", 0.0,
"Damping coefficient in model", &*pl);
423 Teuchos::setDoubleParameter(
424 "Forcing coeff f", -1.0,
"Forcing coefficient in model", &*pl);
425 Teuchos::setDoubleParameter(
426 "x coeff k", 0.0,
"x coefficient in model", &*pl);
427 Teuchos::setDoubleParameter(
428 "Mass coeff m", 1.0,
"Mass coefficient in model", &*pl);
434 #endif // TEMPUS_TEST_HARMONIC_OSCILLATOR_MODEL_IMPL_HPP