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"
24 namespace Tempus_Test {
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());
48 Thyra::put_scalar(1.0, x_dot_vec_.ptr());
57 Thyra::put_scalar(7.0, x_dot_dot_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 for (
int i=0; i<myVecLength; i++) {
271 f_out_view[i] += neg_sign*k_*x_in_view[i];
277 if (W_out != Teuchos::null) {
278 RCP<Thyra::MultiVectorBase<Scalar> > matrix = Teuchos::rcp_dynamic_cast<Thyra::MultiVectorBase<Scalar> >(W_out,
true);
279 Thyra::DetachedMultiVectorView<Scalar> matrix_view( *matrix );
281 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
282 "\n ERROR: omega = 0 in HarmonicOscillatorModel!\n");
284 matrix_view(0,0) = omega;
285 if (x_dot_in != Teuchos::null) {
286 matrix_view(0,0) += neg_sign*c_*alpha;
288 if (x_in != Teuchos::null) {
289 matrix_view(0,0) += neg_sign*k_*beta;
295 if (g_out != Teuchos::null) {
296 Thyra::DetachedVectorView<Scalar> g_out_view(*g_out);
297 g_out_view[0] = Thyra::sum(*x_in)/vecLength_;
301 template<
class Scalar>
302 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
306 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
307 "\n Error! HarmonicOscillatorModel::get_p_space() is not supported!\n");
308 return Teuchos::null;
311 template<
class Scalar>
312 Teuchos::RCP<const Teuchos::Array<std::string> >
316 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
317 "\n Error! HarmonicOscillatorModel::get_p_names() is not supported!\n");
318 return Teuchos::null;
321 template<
class Scalar>
322 Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
326 TEUCHOS_TEST_FOR_EXCEPTION(j != 0, std::logic_error,
327 "\n Error! HarmonicOscillatorModel::get_g_space() only " <<
328 " supports 1 parameter vector. Supplied index l = " <<
335 template<
class Scalar>
340 if (isInitialized_)
return;
343 Thyra::ModelEvaluatorBase::InArgsSetup<Scalar> inArgs;
344 inArgs.setModelEvalDescription(this->description());
346 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x);
347 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot);
348 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_x_dot_dot);
349 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_t);
350 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_W_x_dot_dot_coeff);
351 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_alpha);
352 inArgs.setSupports(Thyra::ModelEvaluatorBase::IN_ARG_beta);
356 Thyra::ModelEvaluatorBase::OutArgsSetup<Scalar> outArgs;
357 outArgs.setModelEvalDescription(this->description());
358 outArgs.set_Np_Ng(0, numResponses_);
360 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_f);
361 outArgs.setSupports(Thyra::ModelEvaluatorBase::OUT_ARG_W_op);
369 nominalValues_ = inArgs_;
370 nominalValues_.set_t(0.0);
371 nominalValues_.set_x(x_vec_);
372 nominalValues_.set_x_dot(x_dot_vec_);
373 nominalValues_.set_x_dot_dot(x_dot_dot_vec_);
375 isInitialized_ =
true;
379 template<
class Scalar>
386 using Teuchos::ParameterList;
387 RCP<ParameterList> tmpPL = Teuchos::rcp(
new ParameterList(
"HarmonicOscillatorModel"));
388 if (paramList != Teuchos::null) tmpPL = paramList;
389 tmpPL->validateParametersAndSetDefaults(*this->getValidParameters());
390 this->setMyParamList(tmpPL);
391 RCP<ParameterList> pl = this->getMyNonconstParamList();
392 c_ = get<Scalar>(*pl,
"Damping coeff c");
393 f_ = get<Scalar>(*pl,
"Forcing coeff f");
394 k_ = get<Scalar>(*pl,
"x coeff k");
395 m_ = get<Scalar>(*pl,
"Mass coeff m");
397 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
398 "Error: invalid value of Mass coeff m = " << m_ <<
"! Mass coeff m must be > 0.\n");
401 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
402 "Error: invalid value of x coeff k = " << k_ <<
"! x coeff k must be >= 0.\n");
404 if ((k_ > 0.0) && (c_ != 0.0)) {
405 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::logic_error,
406 "Error: HarmonicOscillator model only supports x coeff k > 0 when Damping coeff c = 0. You have "
407 <<
"specified x coeff k = " << k_ <<
" and Damping coeff c = " << c_ <<
".\n");
411 template<
class Scalar>
412 Teuchos::RCP<const Teuchos::ParameterList>
416 static Teuchos::RCP<const Teuchos::ParameterList> validPL;
417 if (is_null(validPL)) {
418 Teuchos::RCP<Teuchos::ParameterList> pl = Teuchos::parameterList();
420 Teuchos::setDoubleParameter(
421 "Damping coeff c", 0.0,
"Damping coefficient in model", &*pl);
422 Teuchos::setDoubleParameter(
423 "Forcing coeff f", -1.0,
"Forcing coefficient in model", &*pl);
424 Teuchos::setDoubleParameter(
425 "x coeff k", 0.0,
"x coefficient in model", &*pl);
426 Teuchos::setDoubleParameter(
427 "Mass coeff m", 1.0,
"Mass coefficient in model", &*pl);
433 #endif // TEMPUS_TEST_HARMONIC_OSCILLATOR_MODEL_IMPL_HPP
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const
Teuchos::RCP< Thyra::VectorBase< Scalar > > x_dot_vec_
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > g_space_
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const
Teuchos::RCP< const Teuchos::ParameterList > getValidParameters() const
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int l) const
Thyra::ModelEvaluatorBase::InArgs< Scalar > getExactSolution(double t) const
void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs_bar, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs_bar) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int j) const
Teuchos::RCP< Teuchos::FancyOStream > out_
Teuchos::RCP< Thyra::VectorBase< Scalar > > x_dot_dot_vec_
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int l) const
Teuchos::RCP< Thyra::LinearOpWithSolveBase< Scalar > > create_W() const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const ¶mList)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > x_space_
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const
Teuchos::RCP< Thyra::VectorBase< Scalar > > x_vec_
void setupInOutArgs_() const
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const
HarmonicOscillatorModel(Teuchos::RCP< Teuchos::ParameterList > pList=Teuchos::null)
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const