TEUCHOS_UNIT_TEST(explicit_model_evaluator, basic) { using Teuchos::RCP; PHX::KokkosDeviceSession session; bool parameter_on = true; Teuchos::RCP<panzer::FieldManagerBuilder> fmb; Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> > rLibrary; Teuchos::RCP<panzer::LinearObjFactory<panzer::Traits> > lof; Teuchos::RCP<panzer::GlobalData> gd; buildAssemblyPieces(parameter_on,fmb,rLibrary,gd,lof); // Test a transient me { typedef Thyra::ModelEvaluatorBase MEB; typedef Thyra::ModelEvaluatorBase::InArgs<double> InArgs; typedef Thyra::ModelEvaluatorBase::OutArgs<double> OutArgs; typedef Thyra::VectorBase<double> VectorType; typedef Thyra::LinearOpBase<double> OperatorType; typedef panzer::ModelEvaluator<double> PME; typedef panzer::ExplicitModelEvaluator<double> ExpPME; std::vector<Teuchos::RCP<Teuchos::Array<std::string> > > p_names; std::vector<Teuchos::RCP<Teuchos::Array<double> > > p_values; bool build_transient_support = true; Stratimikos::DefaultLinearSolverBuilder builder; Teuchos::RCP<Teuchos::ParameterList> validList = Teuchos::rcp(new Teuchos::ParameterList(*builder.getValidParameters())); builder.setParameterList(validList); RCP<const Thyra::LinearOpWithSolveFactoryBase<double> > lowsFactory = builder.createLinearSolveStrategy("Amesos"); RCP<PME> me = Teuchos::rcp(new PME(fmb,rLibrary,lof,p_names,p_values,lowsFactory,gd,build_transient_support,0.0)); RCP<ExpPME> exp_me = Teuchos::rcp(new ExpPME(me,true,false)); // constant mass, use lumped RCP<VectorType> exp_f, f; // explicit evaluation { // set the nominal values InArgs nom_vals = exp_me->getNominalValues(); TEST_ASSERT(nom_vals.supports(MEB::IN_ARG_x)); TEST_ASSERT(!nom_vals.supports(MEB::IN_ARG_x_dot)); // this will be supported for stabilization purposes TEST_ASSERT(!nom_vals.supports(MEB::IN_ARG_alpha)); TEST_ASSERT(!nom_vals.supports(MEB::IN_ARG_beta)); // create in args InArgs in_args = exp_me->createInArgs(); TEST_ASSERT(in_args.supports(MEB::IN_ARG_x)); TEST_ASSERT(!in_args.supports(MEB::IN_ARG_x_dot)); // this will be supported for stabilization purposes TEST_ASSERT(!in_args.supports(MEB::IN_ARG_alpha)); TEST_ASSERT(!in_args.supports(MEB::IN_ARG_beta)); InArgs nomValues = exp_me->getNominalValues(); RCP<VectorType> x = Thyra::createMember(*exp_me->get_x_space()); RCP<VectorType> x_dot = Thyra::createMember(*exp_me->get_x_space()); Thyra::assign(x_dot.ptr(),5.0); Thyra::assign(x.ptr(),5.0); in_args.set_x(x); // in_args.set_x_dot(x_dot); // create out args OutArgs out_args = exp_me->createOutArgs(); TEST_ASSERT(out_args.supports(MEB::OUT_ARG_f)); TEST_ASSERT(!out_args.supports(MEB::OUT_ARG_W_op)); TEST_ASSERT(!out_args.supports(MEB::OUT_ARG_W)); exp_f = Thyra::createMember(*exp_me->get_f_space()); out_args.set_f(exp_f); exp_me->evalModel(in_args, out_args); } // implicit evaluation RCP<OperatorType> mass = me->create_W_op(); { // create in args InArgs in_args = me->createInArgs(); InArgs nomValues = me->getNominalValues(); RCP<VectorType> x = Thyra::createMember(*me->get_x_space()); RCP<VectorType> x_dot = Thyra::createMember(*me->get_x_space()); Thyra::assign(x_dot.ptr(),0.0); Thyra::assign(x.ptr(),5.0); in_args.set_x(x); in_args.set_x_dot(x_dot); // create out args OutArgs out_args = me->createOutArgs(); f = Thyra::createMember(*me->get_f_space()); out_args.set_f(f); me->evalModel(in_args, out_args); in_args.set_x(x); in_args.set_x_dot(x_dot); in_args.set_alpha(1.0); in_args.set_beta(0.0); out_args.set_f(Teuchos::null); out_args.set_W_op(mass); me->setOneTimeDirichletBeta(1.0); me->evalModel(in_args, out_args); } Teuchos::RCP<Thyra::VectorBase<double> > mass_exp_f = Thyra::createMember(*exp_me->get_f_space()); Thyra::apply(*mass,Thyra::NOTRANS,*exp_f,mass_exp_f.ptr()); out << "f_i = \n" << Teuchos::describe(*f,Teuchos::VERB_EXTREME) << std::endl; out << "f_e = \n" << Teuchos::describe(*mass_exp_f,Teuchos::VERB_EXTREME) << std::endl; // it should be that exp_f = -f b/c x_dot=0 in the evaluation Thyra::Vp_StV(mass_exp_f.ptr(),1.0,*f); out << "Error = " << Thyra::norm_2(*mass_exp_f) << std::endl; TEST_ASSERT(Thyra::norm_2(*mass_exp_f)<=1e-16); } }