// Get a Kokkos::View of a Teuchos::ArrayView, and make sure that // it points to the same data. Thanks to Christian Trott for // implementing the necessary functionality (View constructor for // certain View specializations, that takes a raw pointer and // dimensions) in Kokkos Array. // // This example will be useful for implementing the // Tpetra::MultiVector methods get1dCopy and get2dCopy. TEUCHOS_UNIT_TEST( LinkTeuchosAndKokkos, ViewOfArrayView ) { typedef Teuchos::Array<double>::size_type size_type; typedef Kokkos::View<double*, Kokkos::LayoutLeft, Kokkos::Threads, Kokkos::MemoryUnmanaged> ka_view_type; typedef Kokkos::View<const double*, Kokkos::LayoutLeft, Kokkos::Threads, Kokkos::MemoryUnmanaged> ka_const_view_type; const size_type numElts = 10; Teuchos::Array<double> x (numElts); for (size_type k = 0; k < numElts; ++k) { x[k] = 42.0 + static_cast<double> (k); } // You can make an (unmanaged) View of a raw array with left or // right (Fortran or C) layout on the HostSpace device, just by passing // the array and stride(s) into the constructor. If you want the // dimensions to differ from the strides, you'll have to create a // subview with the desired dimensions. ka_view_type x_view (x.getRawPtr (), x.size ()); TEST_EQUALITY( x.size(), static_cast<size_type>(x_view.dimension_0()) ); for (size_type k = 0; k < x.size (); ++k) { TEST_EQUALITY( x_view[k], x[k] ); } // This ensures that conversions from double* to const double* work correctly. // x.getRawPtr() returns double*. ka_const_view_type x_view_const ( (const double*) x.getRawPtr (), x.size ()); TEST_EQUALITY( x.size(), static_cast<size_type>(x_view_const.dimension_0()) ); for (size_type k = 0; k < x.size (); ++k) { TEST_EQUALITY( x_view_const[k], x[k] ); } }
TEUCHOS_UNIT_TEST( Rythmos_ImplicitBDFStepper, exactNumericalAnswer_BE ) { double a = 1.5; double f = 1.6; double L = 1.7; RCP<ParameterList> modelPL = Teuchos::parameterList(); { modelPL->set("Implicit model formulation",true); modelPL->set("Coeff a",a); modelPL->set("Coeff f",f); modelPL->set("Coeff L",L); } RCP<SinCosModel> model = sinCosModel(); model->setParameterList(modelPL); Thyra::ModelEvaluatorBase::InArgs<double> model_ic = model->getNominalValues(); RCP<TimeStepNonlinearSolver<double> > nlSolver = timeStepNonlinearSolver<double>(); RCP<ParameterList> stepperPL = Teuchos::parameterList(); { ParameterList& pl = stepperPL->sublist("Step Control Settings"); pl.set("minOrder",1); pl.set("maxOrder",1); ParameterList& vopl = pl.sublist("VerboseObject"); vopl.set("Verbosity Level","none"); } RCP<ImplicitBDFStepper<double> > stepper = implicitBDFStepper<double>(model,nlSolver,stepperPL); stepper->setInitialCondition(model_ic); // Take a few steps and compare the output. int N = 3; double dt = 0.1; double x_exact_0 = 0.0; double x_exact_1 = 1.0; for (int i=1 ; i<=N ; ++i) { double t = i*dt; double dt_taken = stepper->takeStep(dt,STEP_TYPE_FIXED); TEST_ASSERT( dt_taken == dt ); RCP<const VectorBase<double> > x; RCP<const VectorBase<double> > xdot; { // Get x out of stepper. Array<double> t_vec; Array<RCP<const VectorBase<double> > > x_vec; Array<RCP<const VectorBase<double> > > xdot_vec; t_vec.resize(1); t_vec[0] = t; stepper->getPoints(t_vec,&x_vec,&xdot_vec,NULL); x = x_vec[0]; xdot = xdot_vec[0]; } // Compute exact solution: double c = dt/(1+f*f*dt*dt/(L*L)); double x_e_0 = c*(x_exact_0/dt + x_exact_1 + dt*f*f/(L*L)*a); double x_e_1 = c*(-f*f/(L*L)*x_exact_0 + x_exact_1/dt + f*f/(L*L)*a); double xd_e_0 = (x_e_0-x_exact_0)/dt; double xd_e_1 = (x_e_1-x_exact_1)/dt; double tol = 1.0e-12; { Thyra::ConstDetachedVectorView<double> x_view( *x ); TEST_FLOATING_EQUALITY( x_view[0], x_e_0, tol ); TEST_FLOATING_EQUALITY( x_view[1], x_e_1, tol ); Thyra::ConstDetachedVectorView<double> xdot_view( *xdot ); TEST_FLOATING_EQUALITY( xdot_view[0], xd_e_0, tol ); TEST_FLOATING_EQUALITY( xdot_view[1], xd_e_1, tol ); } x_exact_0 = x_e_0; x_exact_1 = x_e_1; } }
TEUCHOS_UNIT_TEST( Rythmos_ImplicitBDFStepper, exactNumericalAnswer_BE_nonlinear ) { double epsilon = 0.5; RCP<ParameterList> modelPL = Teuchos::parameterList(); { modelPL->set("Implicit model formulation",true); modelPL->set("Coeff epsilon",epsilon); } RCP<VanderPolModel> model = vanderPolModel(); model->setParameterList(modelPL); Thyra::ModelEvaluatorBase::InArgs<double> model_ic = model->getNominalValues(); RCP<TimeStepNonlinearSolver<double> > nlSolver = timeStepNonlinearSolver<double>(); { RCP<ParameterList> nlPL = Teuchos::parameterList(); nlPL->set("Default Tol",1.0e-10); nlPL->set("Default Max Iters",20); nlSolver->setParameterList(nlPL); } RCP<ParameterList> stepperPL = Teuchos::parameterList(); { ParameterList& pl = stepperPL->sublist("Step Control Settings"); pl.set("minOrder",1); pl.set("maxOrder",1); ParameterList& vopl = pl.sublist("VerboseObject"); vopl.set("Verbosity Level","none"); } RCP<ImplicitBDFStepper<double> > stepper = implicitBDFStepper<double>(model,nlSolver,stepperPL); stepper->setInitialCondition(model_ic); double h = 0.1; std::vector<double> x_0_exact; std::vector<double> x_1_exact; std::vector<double> x_0_dot_exact; std::vector<double> x_1_dot_exact; { x_0_exact.push_back(2.0); // IC x_1_exact.push_back(0.0); x_0_exact.push_back(1.982896621392518e+00); // matlab x_1_exact.push_back(-1.710337860748234e-01); x_0_exact.push_back(1.951487185706842e+00); // matlab x_1_exact.push_back(-3.140943568567556e-01); x_0_exact.push_back(1.908249109758246e+00); // matlab x_1_exact.push_back(-4.323807594859574e-01); x_0_dot_exact.push_back(0.0); x_1_dot_exact.push_back(0.0); for ( int i=1 ; i< Teuchos::as<int>(x_0_exact.size()) ; ++i ) { x_0_dot_exact.push_back( (x_0_exact[i]-x_0_exact[i-1])/h ); x_1_dot_exact.push_back( (x_1_exact[i]-x_1_exact[i-1])/h ); //std::cout << "x_0_dot_exact["<<i<<"] = "<<x_0_dot_exact[i] << std::endl; //std::cout << "x_1_dot_exact["<<i<<"] = "<<x_1_dot_exact[i] << std::endl; } } double tol_discrete = 1.0e-12; double tol_continuous = 1.0e-2; { // Get IC out double t = 0.0; RCP<const VectorBase<double> > x; RCP<const VectorBase<double> > xdot; { // Get x out of stepper. Array<double> t_vec; Array<RCP<const VectorBase<double> > > x_vec; Array<RCP<const VectorBase<double> > > xdot_vec; t_vec.resize(1); t_vec[0] = t; stepper->getPoints(t_vec,&x_vec,&xdot_vec,NULL); x = x_vec[0]; xdot = xdot_vec[0]; } { Thyra::ConstDetachedVectorView<double> x_view( *x ); TEST_FLOATING_EQUALITY( x_view[0], x_0_exact[0], tol_discrete ); TEST_FLOATING_EQUALITY( x_view[1], x_1_exact[0], tol_discrete ); Thyra::ConstDetachedVectorView<double> xdot_view( *xdot ); TEST_FLOATING_EQUALITY( xdot_view[0], x_0_dot_exact[0], tol_discrete ); TEST_FLOATING_EQUALITY( xdot_view[1], x_1_dot_exact[0], tol_discrete ); } } for (int i=1 ; i < Teuchos::as<int>(x_0_exact.size()); ++i) { // Each time step double t = 0.0+i*h; double h_taken = stepper->takeStep(h,STEP_TYPE_FIXED); TEST_ASSERT( h_taken == h ); RCP<const VectorBase<double> > x; RCP<const VectorBase<double> > xdot; { // Get x out of stepper. Array<double> t_vec; Array<RCP<const VectorBase<double> > > x_vec; Array<RCP<const VectorBase<double> > > xdot_vec; t_vec.resize(1); t_vec[0] = t; stepper->getPoints(t_vec,&x_vec,&xdot_vec,NULL); x = x_vec[0]; xdot = xdot_vec[0]; } { Thyra::ConstDetachedVectorView<double> x_view( *x ); TEST_FLOATING_EQUALITY( x_view[0], x_0_exact[i], tol_discrete ); TEST_FLOATING_EQUALITY( x_view[1], x_1_exact[i], tol_discrete ); Thyra::ConstDetachedVectorView<double> xdot_view( *xdot ); TEST_FLOATING_EQUALITY( xdot_view[0], x_0_dot_exact[i], tol_discrete ); TEST_FLOATING_EQUALITY( xdot_view[1], x_1_dot_exact[i], tol_discrete ); } // Now compare this to the continuous exact solution: { Thyra::ModelEvaluatorBase::InArgs<double> inArgs = model->getExactSolution(t); RCP<const VectorBase<double> > x_continuous_exact = inArgs.get_x(); RCP<const VectorBase<double> > xdot_continuous_exact = inArgs.get_x_dot(); { Thyra::ConstDetachedVectorView<double> x_view( *x ); Thyra::ConstDetachedVectorView<double> xce_view( *x_continuous_exact ); TEST_FLOATING_EQUALITY( x_view[0], xce_view[0], tol_continuous ); TEST_FLOATING_EQUALITY( x_view[1], xce_view[1], tol_continuous*10 ); Thyra::ConstDetachedVectorView<double> xdot_view( *xdot ); Thyra::ConstDetachedVectorView<double> xdotce_view( *xdot_continuous_exact ); TEST_FLOATING_EQUALITY( xdot_view[0], xdotce_view[0], tol_continuous*10 ); TEST_FLOATING_EQUALITY( xdot_view[1], xdotce_view[1], tol_continuous*10 ); } } } }
int main(int argc, char **argv) { Kokkos::initialize(); try { // Create random field int M = 10; Teuchos::ParameterList solverParams; solverParams.set("Number of KL Terms", M); solverParams.set("Mean", 1.0); solverParams.set("Standard Deviation", 0.1); int ndim = 3; Teuchos::Array<double> domain_upper(ndim), domain_lower(ndim), correlation_length(ndim); for (int i=0; i<ndim; i++) { domain_upper[i] = 1.0; domain_lower[i] = 0.0; correlation_length[i] = 10.0; } solverParams.set("Domain Upper Bounds", domain_upper); solverParams.set("Domain Lower Bounds", domain_lower); solverParams.set("Correlation Lengths", correlation_length); Stokhos::KL::ExponentialRandomField<double> rf(solverParams); rf.print(std::cout); // Evaluate random field at a point Teuchos::Array<double> x(ndim); for (int i=0; i<ndim; i++) x[i] = (domain_upper[i] + domain_lower[i])/2.0 + 0.1*(domain_upper[i] - domain_lower[i])/2.0; Teuchos::Array<double> rvar(M); for (int i=0; i<M; i++) rvar[i] = 1.5; double result = rf.evaluate(x, rvar); std::cout << "result (host) = " << result << std::endl; // Evaluate random field in a functor on device typedef Kokkos::View<double*> view_type; typedef view_type::HostMirror host_view_type; view_type x_view("x", ndim); host_view_type host_x = Kokkos::create_mirror_view(x_view); for (int i=0; i<ndim; i++) host_x(i) = x[i]; Kokkos::deep_copy(x_view, host_x); view_type rvar_view("rvar", M); host_view_type host_rvar = Kokkos::create_mirror_view(rvar_view); for (int i=0; i<M; i++) host_rvar(i) = rvar[i]; Kokkos::deep_copy(rvar_view, host_rvar); RF<double> rf_func(rf, x_view, rvar_view); host_view_type host_y = Kokkos::create_mirror_view(rf_func.y); Kokkos::deep_copy(host_y, rf_func.y); double result2 = host_y(0); std::cout << "result (device)= " << result2 << std::endl; } catch (std::exception& e) { std::cout << e.what() << std::endl; } Kokkos::finalize(); }
TEUCHOS_UNIT_TEST( Rythmos_ForwardSensitivityExplicitModelEvaluator, evalModel ) { typedef Thyra::ModelEvaluatorBase MEB; RCP<ForwardSensitivityExplicitModelEvaluator<double> > model = forwardSensitivityExplicitModelEvaluator<double>(); RCP<SinCosModel> innerModel = sinCosModel(false); double a = 0.4; double f = 1.5; double L = 1.6; { RCP<ParameterList> pl = Teuchos::parameterList(); pl->set("Accept model parameters",true); pl->set("Implicit model formulation",false); pl->set("Coeff a", a ); pl->set("Coeff f", f ); pl->set("Coeff L", L ); innerModel->setParameterList(pl); } model->initializeStructure(innerModel, 0 ); RCP<VectorBase<double> > x; MEB::InArgs<double> pointInArgs; // Used to change the solution for re-evaluation RCP<StepperBase<double> > stepper; // Used for initializePointState { pointInArgs = innerModel->createInArgs(); pointInArgs.set_t(0.1); x = Thyra::createMember(innerModel->get_x_space()); { Thyra::DetachedVectorView<double> x_view( *x ); x_view[0] = 2.0; x_view[1] = 3.0; } pointInArgs.set_x(x); RCP<VectorBase<double> > p0 = Thyra::createMember(innerModel->get_p_space(0)); { Thyra::DetachedVectorView<double> p0_view( *p0 ); p0_view[0] = a; p0_view[1] = f; p0_view[2] = L; } pointInArgs.set_p(0,p0); { // Create a stepper with these initial conditions to use to call // initializePointState on this ME: stepper = forwardEulerStepper<double>(); stepper->setInitialCondition(pointInArgs); model->initializePointState(Teuchos::inOutArg(*stepper),false); } } MEB::InArgs<double> inArgs = model->createInArgs(); RCP<VectorBase<double> > x_bar = Thyra::createMember(model->get_x_space()); RCP<Thyra::DefaultMultiVectorProductVector<double> > s_bar = Teuchos::rcp_dynamic_cast<Thyra::DefaultMultiVectorProductVector<double> >( x_bar, true ); RCP<Thyra::MultiVectorBase<double> > S = s_bar->getNonconstMultiVector(); // Fill S with data { TEST_EQUALITY_CONST( S->domain()->dim(), 3 ); TEST_EQUALITY_CONST( S->range()->dim(), 2 ); RCP<VectorBase<double> > S0 = S->col(0); RCP<VectorBase<double> > S1 = S->col(1); RCP<VectorBase<double> > S2 = S->col(2); TEST_EQUALITY_CONST( S0->space()->dim(), 2 ); TEST_EQUALITY_CONST( S1->space()->dim(), 2 ); TEST_EQUALITY_CONST( S2->space()->dim(), 2 ); Thyra::DetachedVectorView<double> S0_view( *S0 ); S0_view[0] = 7.0; S0_view[1] = 8.0; Thyra::DetachedVectorView<double> S1_view( *S1 ); S1_view[0] = 9.0; S1_view[1] = 10.0; Thyra::DetachedVectorView<double> S2_view( *S2 ); S2_view[0] = 11.0; S2_view[1] = 12.0; } inArgs.set_x(x_bar); MEB::OutArgs<double> outArgs = model->createOutArgs(); RCP<VectorBase<double> > f_bar = Thyra::createMember(model->get_f_space()); RCP<Thyra::DefaultMultiVectorProductVector<double> > f_sens = Teuchos::rcp_dynamic_cast<Thyra::DefaultMultiVectorProductVector<double> >( f_bar, true ); RCP<Thyra::MultiVectorBase<double> > F_sens = f_sens->getNonconstMultiVector().assert_not_null(); V_S(Teuchos::outArg(*f_bar),0.0); outArgs.set_f(f_bar); inArgs.set_t(0.1); model->evalModel(inArgs,outArgs); // Verify F_sens = df/dx*S = df/dp // df/dx = [ 0 1 ] // [ -(f/L)*(f/L) 0 ] // S = [ 7 9 11 ] x = [ 2 ] // [ 8 10 12 ] [ 3 ] // df/dp = [ 0 0 0 ] // [ (f/L)*(f/L) 2*f/(L*L)*(a-x_0) -2*f*f/(L*L*L)*(a-x_0) ] // F_sens_0 = // [ 8 ] // [ -7*(f/L)*(f/L)+(f*f)/(L*L) ] // F_sens_1 = // [ 10 ] // [ -9*(f/L)*(f/L)+2*f/(L*L)*(a-x_0) ] // F_sens_2 = // [ 12 ] // [ -11*(f/L)*(f/L)-2*f*f/(L*L*L)*(a-x_0) ] // double tol = 1.0e-10; { TEST_EQUALITY_CONST( F_sens->domain()->dim(), 3 ); TEST_EQUALITY_CONST( F_sens->range()->dim(), 2 ); RCP<VectorBase<double> > F_sens_0 = F_sens->col(0); RCP<VectorBase<double> > F_sens_1 = F_sens->col(1); RCP<VectorBase<double> > F_sens_2 = F_sens->col(2); TEST_EQUALITY_CONST( F_sens_0->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_1->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_2->space()->dim(), 2 ); Thyra::DetachedVectorView<double> F_sens_0_view( *F_sens_0 ); TEST_FLOATING_EQUALITY( F_sens_0_view[0], 8.0, tol ); TEST_FLOATING_EQUALITY( F_sens_0_view[1], -7.0*(f/L)*(f/L)+(f*f)/(L*L), tol ); Thyra::DetachedVectorView<double> F_sens_1_view( *F_sens_1 ); TEST_FLOATING_EQUALITY( F_sens_1_view[0], 10.0, tol ); TEST_FLOATING_EQUALITY( F_sens_1_view[1], -9*(f/L)*(f/L)+2*f/(L*L)*(a-2.0), tol ); Thyra::DetachedVectorView<double> F_sens_2_view( *F_sens_2 ); TEST_FLOATING_EQUALITY( F_sens_2_view[0], 12.0, tol ); TEST_FLOATING_EQUALITY( F_sens_2_view[1], -11*(f/L)*(f/L)-2*f*f/(L*L*L)*(a-2.0), tol ); } // Now change x and evaluate again. { Thyra::DetachedVectorView<double> x_view( *x ); x_view[0] = 20.0; x_view[1] = 21.0; } // We need to call initializePointState again due to the vector // being cloned inside. stepper->setInitialCondition(pointInArgs); model->initializePointState(Teuchos::inOutArg(*stepper),false); model->evalModel(inArgs,outArgs); { TEST_EQUALITY_CONST( F_sens->domain()->dim(), 3 ); TEST_EQUALITY_CONST( F_sens->range()->dim(), 2 ); RCP<VectorBase<double> > F_sens_0 = F_sens->col(0); RCP<VectorBase<double> > F_sens_1 = F_sens->col(1); RCP<VectorBase<double> > F_sens_2 = F_sens->col(2); TEST_EQUALITY_CONST( F_sens_0->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_1->space()->dim(), 2 ); TEST_EQUALITY_CONST( F_sens_2->space()->dim(), 2 ); Thyra::DetachedVectorView<double> F_sens_0_view( *F_sens_0 ); TEST_FLOATING_EQUALITY( F_sens_0_view[0], 8.0, tol ); TEST_FLOATING_EQUALITY( F_sens_0_view[1], -7.0*(f/L)*(f/L)+(f*f)/(L*L), tol ); Thyra::DetachedVectorView<double> F_sens_1_view( *F_sens_1 ); TEST_FLOATING_EQUALITY( F_sens_1_view[0], 10.0, tol ); TEST_FLOATING_EQUALITY( F_sens_1_view[1], -9*(f/L)*(f/L)+2*f/(L*L)*(a-20.0), tol ); Thyra::DetachedVectorView<double> F_sens_2_view( *F_sens_2 ); TEST_FLOATING_EQUALITY( F_sens_2_view[0], 12.0, tol ); TEST_FLOATING_EQUALITY( F_sens_2_view[1], -11*(f/L)*(f/L)-2*f*f/(L*L*L)*(a-20.0), tol ); } }