TEUCHOS_UNIT_TEST( Rythmos_TimeRange, copyAndScaleInvalid ) { TimeRange<double> tr; TimeRange<double> newTr = tr.copyAndScale(5.0); TEST_EQUALITY_CONST( newTr.isValid(), false ); TEST_EQUALITY( newTr.lower(), tr.lower() ); TEST_EQUALITY( newTr.upper(), tr.upper() ); TEST_EQUALITY( newTr.length(), tr.length() ); }
bool Rythmos::isInRange_cc(const TimeRange<TimeType> &tr, const TimeType &p) { return ( compareTimeValues(p,tr.lower()) >= 0 && compareTimeValues(p,tr.upper()) <= 0 ); }
TEUCHOS_UNIT_TEST( Rythmos_TimeRange, copyAndScale ) { TimeRange<double> tr(1.0,2.0); TimeRange<double> newTr = tr.copyAndScale(5.0); TEST_EQUALITY_CONST( newTr.isValid(), true ); TEST_EQUALITY_CONST( newTr.lower(), 5.0 ); TEST_EQUALITY_CONST( newTr.upper(), 10.0 ); TEST_EQUALITY_CONST( newTr.length(), 5.0 ); }
TEUCHOS_UNIT_TEST( Rythmos_TimeRange, newTimeRange ) { TimeRange<double> tr; // it should be initialized as [0,-1] TEST_EQUALITY_CONST( tr.isValid(), false ); TEST_COMPARE( tr.lower(), >, tr.upper() ); TEST_EQUALITY_CONST( tr.isInRange(0.5), false ); TEST_EQUALITY_CONST( tr.isInRange(0.0), false ); TEST_EQUALITY_CONST( tr.isInRange(-1.0), false ); TEST_EQUALITY_CONST( tr.length(), -1.0 ); }
void Rythmos::assertNoTimePointsInsideCurrentTimeRange( const InterpolationBufferBase<Scalar>& interpBuffer, const Array<Scalar>& time_vec ) { typedef ScalarTraits<Scalar> ST; const int numTimePoints = time_vec.size(); const TimeRange<Scalar> currentTimeRange = interpBuffer.getTimeRange(); if (currentTimeRange.length() >= ST::zero()) { for ( int i = 0; i < numTimePoints; ++i ) { TEST_FOR_EXCEPTION( currentTimeRange.isInRange(time_vec[i]), std::out_of_range, "Error, time_vec["<<i<<"] = " << time_vec[i] << " is in TimeRange of " << interpBuffer.description() << " = [" << currentTimeRange.lower() << "," << currentTimeRange.upper() << "]!" ); } } }
TEUCHOS_UNIT_TEST( Rythmos_ExplicitRKStepper, getTimeRange ) { { RCP<SinCosModel> model = sinCosModel(false); RCP<ExplicitRKStepper<double> > stepper = explicitRKStepper<double>(model); Thyra::ModelEvaluatorBase::InArgs<double> ic = model->getNominalValues(); stepper->setInitialCondition(ic); TimeRange<double> tr = stepper->getTimeRange(); TEST_EQUALITY_CONST( tr.isValid(), true ); TEST_EQUALITY_CONST( tr.lower(), 0.0 ); TEST_EQUALITY_CONST( tr.upper(), 0.0 ); TEST_EQUALITY_CONST( tr.length(), 0.0 ); } { RCP<SinCosModel> model = sinCosModel(false); RCP<ExplicitRKStepper<double> > stepper = explicitRKStepper<double>(); stepper->setModel(model); TimeRange<double> tr; TEST_NOTHROW( tr = stepper->getTimeRange() ); TEST_EQUALITY_CONST( tr.isValid(), false ); } }
TEUCHOS_UNIT_TEST( BasicDiscreteAdjointStepperTester, rawNonlinearAdjoint ) { using Teuchos::outArg; using Teuchos::describe; using Teuchos::getParametersFromXmlString; typedef Thyra::ModelEvaluatorBase MEB; // out << "\nA) Create the nonlinear ME ...\n"; // RCP<VanderPolModel> stateModel = vanderPolModel( getParametersFromXmlString( "<ParameterList>" " <Parameter name=\"Implicit model formulation\" type=\"bool\" value=\"1\"/>" "</ParameterList>" ) ); // out << "\nB) Create the nonlinear solver ...\n"; // RCP<TimeStepNonlinearSolver<double> > nlSolver = timeStepNonlinearSolver<double>( getParametersFromXmlString( "<ParameterList>" " <Parameter name=\"Default Tol\" type=\"double\" value=\"1.0e-10\"/>" " <Parameter name=\"Default Max Iters\" type=\"int\" value=\"20\"/>" "</ParameterList>" ) ); // out << "\nC) Create the integrator for the forward state problem ...\n"; // RCP<IntegratorBuilder<double> > ib = integratorBuilder<double>( Teuchos::getParametersFromXmlString( "<ParameterList>" " <ParameterList name=\"Stepper Settings\">" " <ParameterList name=\"Stepper Selection\">" " <Parameter name=\"Stepper Type\" type=\"string\" value=\"Backward Euler\"/>" " </ParameterList>" " </ParameterList>" " <ParameterList name=\"Integration Control Strategy Selection\">" " <Parameter name=\"Integration Control Strategy Type\" type=\"string\"" " value=\"Simple Integration Control Strategy\"/>" " <ParameterList name=\"Simple Integration Control Strategy\">" " <Parameter name=\"Take Variable Steps\" type=\"bool\" value=\"false\"/>" " <Parameter name=\"Fixed dt\" type=\"double\" value=\"0.5\"/>" // Gives 2 time steps! " </ParameterList>" " </ParameterList>" " <ParameterList name=\"Interpolation Buffer Settings\">" " <ParameterList name=\"Trailing Interpolation Buffer Selection\">" " <Parameter name=\"Interpolation Buffer Type\" type=\"string\" value=\"Interpolation Buffer\"/>" " </ParameterList>" " </ParameterList>" "</ParameterList>" ) ); MEB::InArgs<double> ic = stateModel->getNominalValues(); RCP<IntegratorBase<double> > integrator = ib->create(stateModel, ic, nlSolver); //integrator->setVerbLevel(Teuchos::VERB_EXTREME); // ToDo: Set the trailing IB to pick up the entire state solution! // out << "\nD) Solve the basic forward problem ...\n"; // const TimeRange<double> fwdTimeRange = integrator->getFwdTimeRange(); const double t_final = fwdTimeRange.upper(); RCP<const Thyra::VectorBase<double> > x_final, x_dot_final; get_fwd_x_and_x_dot( *integrator, t_final, outArg(x_final), outArg(x_dot_final) ); out << "\nt_final = " << t_final << "\n"; out << "\nx_final: " << *x_final; out << "\nx_dot_final: " << *x_dot_final; // out << "\nE) Create the basic adjoint model (no distributed response) ...\n"; // RCP<AdjointModelEvaluator<double> > adjModel = adjointModelEvaluator<double>( stateModel, fwdTimeRange ); adjModel->setFwdStateSolutionBuffer(integrator); // out << "\nF) Create a stepper and integrator for the adjoint ...\n"; // RCP<Thyra::LinearNonlinearSolver<double> > adjTimeStepSolver = Thyra::linearNonlinearSolver<double>(); RCP<Rythmos::StepperBase<double> > adjStepper = integrator->getStepper()->cloneStepperAlgorithm(); // out << "\nG) Set up the initial condition for the adjoint at the final time ...\n"; // const RCP<const Thyra::VectorSpaceBase<double> > f_space = stateModel->get_f_space(); // lambda(t_final) = x_final const RCP<Thyra::VectorBase<double> > lambda_ic = createMember(f_space); V_V( lambda_ic.ptr(), *x_final ); // lambda_dot(t_final,i) = 0.0 const RCP<Thyra::VectorBase<double> > lambda_dot_ic = createMember(f_space); Thyra::V_S( lambda_dot_ic.ptr(), 0.0 ); MEB::InArgs<double> adj_ic = adjModel->getNominalValues(); adj_ic.set_x(lambda_ic); adj_ic.set_x_dot(lambda_dot_ic); out << "\nadj_ic: " << describe(adj_ic, Teuchos::VERB_EXTREME); RCP<Rythmos::IntegratorBase<double> > adjIntegrator = ib->create(adjModel, adj_ic, adjTimeStepSolver); // out << "\nH) Integrate the adjoint backwards in time (using backward time) ...\n"; // adjStepper->setInitialCondition(adj_ic); adjIntegrator->setStepper(adjStepper, fwdTimeRange.length()); const double adj_t_final = fwdTimeRange.length(); RCP<const Thyra::VectorBase<double> > lambda_final, lambda_dot_final; get_fwd_x_and_x_dot( *adjIntegrator, adj_t_final, outArg(lambda_final), outArg(lambda_dot_final) ); out << "\nadj_t_final = " << adj_t_final << "\n"; out << "\nlambda_final: " << *lambda_final; out << "\nlambda_dot_final: " << *lambda_dot_final; }
void PointwiseInterpolationBufferAppender<Scalar>::append( const InterpolationBufferBase<Scalar>& interpBuffSource, const TimeRange<Scalar>& appendRange, const Ptr<InterpolationBufferBase<Scalar> > &interpBuffSink ) { TEUCHOS_ASSERT( !is_null(interpBuffSink) ); #ifdef RYTHMOS_DEBUG this->assertAppendPreconditions(interpBuffSource,appendRange,*interpBuffSink); #endif // RYTHMOS_DEBUG RCP<Teuchos::FancyOStream> out = this->getOStream(); Teuchos::OSTab ostab(out,1,"PointwiseInterpolationBufferAppender::append"); if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) { *out << "Interpolation Buffer source range = [" << interpBuffSource.getTimeRange().lower() << "," << interpBuffSource.getTimeRange().upper() << "]" << std::endl; *out << "Append range = [" << appendRange.lower() << "," << appendRange.upper() << "]" << std::endl; *out << "Interpolation Buffer sink range = [" << interpBuffSink->getTimeRange().lower() << "," << interpBuffSink->getTimeRange().upper() << "]" << std::endl; } // Set up appendRange correctly to be either (] or [): RCP<const TimeRange<Scalar> > correctedAppendRange = Teuchos::rcp(&appendRange,false); if (compareTimeValues<Scalar>(interpBuffSink->getTimeRange().upper(),appendRange.lower()) == 0) { // adding to end of buffer correctedAppendRange = Teuchos::rcp(new TimeRange_oc<Scalar>(appendRange)); if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) { *out << "Corrected append range = (" << correctedAppendRange->lower() << "," << correctedAppendRange->upper() << "]" << std::endl; } } else if (compareTimeValues<Scalar>(interpBuffSink->getTimeRange().lower(),appendRange.upper()) == 0) { // adding to beginning of buffer correctedAppendRange = Teuchos::rcp(new TimeRange_co<Scalar>(appendRange)); if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) { *out << "Corrected append range = [" << correctedAppendRange->lower() << "," << correctedAppendRange->upper() << ")" << std::endl; } } Array<Scalar> time_vec_in; interpBuffSource.getNodes(&time_vec_in); Array<Scalar> time_vec; selectPointsInTimeRange(time_vec_in,*correctedAppendRange,Teuchos::outArg(time_vec)); if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) { *out << "Selected points for appending to sink buffer: " << time_vec << std::endl; } Array<RCP<const Thyra::VectorBase<Scalar> > > x_vec; Array<RCP<const Thyra::VectorBase<Scalar> > > xdot_vec; Array<ScalarMag> accuracy_vec; interpBuffSource.getPoints(time_vec, &x_vec, &xdot_vec, &accuracy_vec); if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) { *out << "Sink buffer range before addPoints = [" << interpBuffSink->getTimeRange().lower() << "," << interpBuffSink->getTimeRange().upper() << "]" << std::endl; } interpBuffSink->addPoints(time_vec, x_vec, xdot_vec); if ( Teuchos::as<int>(this->getVerbLevel()) >= Teuchos::as<int>(Teuchos::VERB_HIGH) ) { *out << "Sink buffer range after addPoints = [" << interpBuffSink->getTimeRange().lower() << "," << interpBuffSink->getTimeRange().upper() << "]" << std::endl; } }
bool DefaultIntegrator<Scalar>::advanceStepperToTime( const Scalar& advance_to_t ) { #ifdef ENABLE_RYTHMOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR_DIFF("Rythmos:DefaultIntegrator::advanceStepperToTime", TopLevel); #endif using std::endl; typedef std::numeric_limits<Scalar> NL; using Teuchos::incrVerbLevel; #ifndef _MSC_VER using Teuchos::Describable; #endif using Teuchos::OSTab; typedef Teuchos::ScalarTraits<Scalar> ST; RCP<Teuchos::FancyOStream> out = this->getOStream(); Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel(); if (!is_null(integrationControlStrategy_)) { integrationControlStrategy_->setOStream(out); integrationControlStrategy_->setVerbLevel(incrVerbLevel(verbLevel,-1)); } if (!is_null(integrationObserver_)) { integrationObserver_->setOStream(out); integrationObserver_->setVerbLevel(incrVerbLevel(verbLevel,-1)); } if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) ) *out << "\nEntering " << this->Describable::description() << "::advanceStepperToTime("<<advance_to_t<<") ...\n"; // Remember what timestep index we are on so we can report it later const int initCurrTimeStepIndex = currTimeStepIndex_; // Take steps until we the requested time is reached (or passed) TimeRange<Scalar> currStepperTimeRange = stepper_->getTimeRange(); // Start by assume we can reach the time advance_to_t bool return_val = true; while ( !currStepperTimeRange.isInRange(advance_to_t) ) { // Halt immediatly if exceeded max iterations if (currTimeStepIndex_ >= maxNumTimeSteps_) { if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) ) *out << "\n***" << "\n*** NOTICE: currTimeStepIndex = "<<currTimeStepIndex_ << " >= maxNumTimeSteps = "<<maxNumTimeSteps_<< ", halting time integration!" << "\n***\n"; return_val = false; break; // Exit the loop immediately! } if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) ) *out << "\nTake step: current_stepper_t = " << currStepperTimeRange.upper() << ", currTimeStepIndex = " << currTimeStepIndex_ << endl; // // A) Reinitialize if a hard breakpoint was reached on the last time step // if (stepCtrlInfoLast_.limitedByBreakPoint) { if ( stepCtrlInfoLast_.breakPointType == BREAK_POINT_TYPE_HARD ) { #ifdef ENABLE_RYTHMOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR("Rythmos:DefaultIntegrator::restart"); #endif if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) ) *out << "\nAt a hard-breakpoint, restarting time integrator ...\n"; restart(&*stepper_); } else { if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) ) *out << "\nAt a soft-breakpoint, NOT restarting time integrator ...\n"; } } // // B) Get the trial step control info // StepControlInfo<Scalar> trialStepCtrlInfo; { #ifdef ENABLE_RYTHMOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR("Rythmos:DefaultIntegrator::advanceStepperToTime: getStepCtrl"); #endif if (!is_null(integrationControlStrategy_)) { // Let an external strategy object determine the step size and type. // Note that any breakpoint info is also related through this call. trialStepCtrlInfo = integrationControlStrategy_->getNextStepControlInfo( *stepper_, stepCtrlInfoLast_, currTimeStepIndex_ ); } else { // Take a variable step if we have no control strategy trialStepCtrlInfo.stepType = STEP_TYPE_VARIABLE; trialStepCtrlInfo.stepSize = NL::max(); } } // Print the initial trial step if ( includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM) ) { *out << "\nTrial step:\n"; OSTab tab(out); *out << trialStepCtrlInfo; } // Halt immediately if we where told to do so if (trialStepCtrlInfo.stepSize < ST::zero()) { if ( includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM) ) *out << "\n***" << "\n*** NOTICE: The IntegrationControlStrategy object return stepSize < 0.0, halting time integration!" << "\n***\n"; return_val = false; break; // Exit the loop immediately! } // Make sure we don't step past the final time if asked not to bool updatedTrialStepCtrlInfo = false; { const Scalar finalTime = integrationTimeDomain_.upper(); if (landOnFinalTime_ && trialStepCtrlInfo.stepSize + currStepperTimeRange.upper() > finalTime) { if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) ) *out << "\nCutting trial step to avoid stepping past final time ...\n"; trialStepCtrlInfo.stepSize = finalTime - currStepperTimeRange.upper(); updatedTrialStepCtrlInfo = true; } } // Print the modified trial step if ( updatedTrialStepCtrlInfo && includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM) ) { *out << "\nUpdated trial step:\n"; OSTab tab(out); *out << trialStepCtrlInfo; } // // C) Take the step // // Print step type and size if ( includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM) ) { if (trialStepCtrlInfo.stepType == STEP_TYPE_VARIABLE) *out << "\nTaking a variable time step with max step size = " << trialStepCtrlInfo.stepSize << " ....\n"; else *out << "\nTaking a fixed time step of size = " << trialStepCtrlInfo.stepSize << " ....\n"; } // Take step Scalar stepSizeTaken; { #ifdef ENABLE_RYTHMOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR("Rythmos:DefaultIntegrator::advanceStepperToTime: takeStep"); #endif stepSizeTaken = stepper_->takeStep( trialStepCtrlInfo.stepSize, trialStepCtrlInfo.stepType ); } // Validate step taken if (trialStepCtrlInfo.stepType == STEP_TYPE_VARIABLE) { TEST_FOR_EXCEPTION( stepSizeTaken < ST::zero(), std::logic_error, "Error, stepper took negative step of dt = " << stepSizeTaken << "!\n" ); TEST_FOR_EXCEPTION( stepSizeTaken > trialStepCtrlInfo.stepSize, std::logic_error, "Error, stepper took step of dt = " << stepSizeTaken << " > max step size of = " << trialStepCtrlInfo.stepSize << "!\n" ); } else { // STEP_TYPE_FIXED TEST_FOR_EXCEPTION( stepSizeTaken != trialStepCtrlInfo.stepSize, std::logic_error, "Error, stepper took step of dt = " << stepSizeTaken << " when asked to take step of dt = " << trialStepCtrlInfo.stepSize << "\n" ); } // Update info about this step currStepperTimeRange = stepper_->getTimeRange(); const StepControlInfo<Scalar> stepCtrlInfo = stepCtrlInfoTaken(trialStepCtrlInfo,stepSizeTaken); // Print the step actually taken if ( includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM) ) { *out << "\nStep actually taken:\n"; OSTab tab(out); *out << stepCtrlInfo; } // Append the trailing interpolation buffer (if defined) if (!is_null(trailingInterpBuffer_)) { interpBufferAppender_->append(*stepper_,currStepperTimeRange, trailingInterpBuffer_.ptr() ); } // // D) Output info about step // { #ifdef ENABLE_RYTHMOS_TIMERS TEUCHOS_FUNC_TIME_MONITOR("Rythmos:DefaultIntegrator::advanceStepperToTime: output"); #endif // Print our own brief output if ( includesVerbLevel(verbLevel,Teuchos::VERB_MEDIUM) ) { StepStatus<Scalar> stepStatus = stepper_->getStepStatus(); *out << "\nTime point reached = " << stepStatus.time << endl; *out << "\nstepStatus:\n" << stepStatus; if ( includesVerbLevel(verbLevel,Teuchos::VERB_EXTREME) ) { RCP<const Thyra::VectorBase<Scalar> > solution = stepStatus.solution, solutionDot = stepStatus.solutionDot; if (!is_null(solution)) *out << "\nsolution = \n" << Teuchos::describe(*solution,verbLevel); if (!is_null(solutionDot)) *out << "\nsolutionDot = \n" << Teuchos::describe(*solutionDot,verbLevel); } } // Output to the observer if (!is_null(integrationObserver_)) integrationObserver_->observeCompletedTimeStep( *stepper_, stepCtrlInfo, currTimeStepIndex_ ); } // // E) Update info for next time step // stepCtrlInfoLast_ = stepCtrlInfo; ++currTimeStepIndex_; } if ( includesVerbLevel(verbLevel,Teuchos::VERB_LOW) ) *out << "\nNumber of steps taken in this call to advanceStepperToTime(...) = " << (currTimeStepIndex_ - initCurrTimeStepIndex) << endl << "\nLeaving" << this->Describable::description() << "::advanceStepperToTime("<<advance_to_t<<") ...\n"; return return_val; }
TEUCHOS_UNIT_TEST( Rythmos_GlobalErrorEstimator, SinCos ) { typedef Teuchos::ScalarTraits<double> ST; // Forward Solve, storing data in linear interpolation buffer int storageLimit = 100; double finalTime = 0.1; double dt = 0.1; RCP<IntegratorBuilder<double> > ib = integratorBuilder<double>(); { RCP<ParameterList> ibPL = Teuchos::parameterList(); ibPL->sublist("Integrator Settings").sublist("Integrator Selection").set("Integrator Type","Default Integrator"); ibPL->sublist("Integrator Settings").set("Final Time",finalTime); ibPL->sublist("Integration Control Strategy Selection").set("Integration Control Strategy Type","Simple Integration Control Strategy"); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Take Variable Steps",false); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Fixed dt",dt); ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Backward Euler"); //ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Implicit RK"); //ibPL->sublist("Stepper Settings").sublist("Runge Kutta Butcher Tableau Selection").set("Runge Kutta Butcher Tableau Type","Backward Euler"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").set("Interpolation Buffer Type","Interpolation Buffer"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").sublist("Interpolation Buffer").set("StorageLimit",storageLimit); ibPL->sublist("Interpolation Buffer Settings").sublist("Interpolator Selection").set("Interpolator Type","Linear Interpolator"); ib->setParameterList(ibPL); } RCP<SinCosModel> fwdModel = sinCosModel(true); // implicit formulation Thyra::ModelEvaluatorBase::InArgs<double> fwdIC = fwdModel->getNominalValues(); RCP<Thyra::NonlinearSolverBase<double> > fwdNLSolver = timeStepNonlinearSolver<double>(); RCP<IntegratorBase<double> > fwdIntegrator = ib->create(fwdModel,fwdIC,fwdNLSolver); RCP<const VectorBase<double> > x_final; { Array<double> time_vec; time_vec.push_back(finalTime); Array<RCP<const Thyra::VectorBase<double> > > x_final_array; fwdIntegrator->getFwdPoints(time_vec,&x_final_array,NULL,NULL); x_final = x_final_array[0]; } // Verify x_final is correct { // Defaults from SinCos Model: double f = 1.0; double L = 1.0; double a = 0.0; double x_ic_0 = 0.0; double x_ic_1 = 1.0; double x_0 = dt/(1.0+std::pow(dt*f/L,2))*(x_ic_0/dt+x_ic_1+dt*std::pow(f/L,2)*a); double x_1 = dt/(1.0+std::pow(dt*f/L,2))*(-std::pow(f/L,2)*x_ic_0+x_ic_1/dt+std::pow(f/L,2)*a); double tol = 1.0e-10; Thyra::ConstDetachedVectorView<double> x_final_view( *x_final ); TEST_FLOATING_EQUALITY( x_final_view[0], x_0, tol ); TEST_FLOATING_EQUALITY( x_final_view[1], x_1, tol ); } // Copy InterpolationBuffer data into Cubic Spline interpolation buffer for use in Adjoint Solve TimeRange<double> fwdTimeRange; RCP<InterpolationBufferBase<double> > fwdCubicSplineInterpBuffer; { RCP<PointwiseInterpolationBufferAppender<double> > piba = pointwiseInterpolationBufferAppender<double>(); RCP<InterpolationBuffer<double> > sinkInterpBuffer = interpolationBuffer<double>(); sinkInterpBuffer->setStorage(storageLimit); RCP<CubicSplineInterpolator<double> > csi = cubicSplineInterpolator<double>(); sinkInterpBuffer->setInterpolator(csi); RCP<const InterpolationBufferBase<double> > sourceInterpBuffer; { RCP<TrailingInterpolationBufferAcceptingIntegratorBase<double> > tibaib = Teuchos::rcp_dynamic_cast<TrailingInterpolationBufferAcceptingIntegratorBase<double> >(fwdIntegrator,true); sourceInterpBuffer = tibaib->getTrailingInterpolationBuffer(); } fwdTimeRange = sourceInterpBuffer->getTimeRange(); piba->append(*sourceInterpBuffer, fwdTimeRange, Teuchos::outArg(*sinkInterpBuffer)); fwdCubicSplineInterpBuffer = sinkInterpBuffer; TimeRange<double> sourceRange = sourceInterpBuffer->getTimeRange(); TimeRange<double> sinkRange = sinkInterpBuffer->getTimeRange(); TEST_EQUALITY( sourceRange.lower(), sinkRange.lower() ); TEST_EQUALITY( sourceRange.upper(), sinkRange.upper() ); } // Adjoint Solve, reading forward solve data from Cubic Spline interpolation buffer { RCP<ParameterList> ibPL = Teuchos::parameterList(); ibPL->sublist("Integrator Settings").sublist("Integrator Selection").set("Integrator Type","Default Integrator"); ibPL->sublist("Integrator Settings").set("Final Time",finalTime); ibPL->sublist("Integration Control Strategy Selection").set("Integration Control Strategy Type","Simple Integration Control Strategy"); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Take Variable Steps",false); ibPL->sublist("Integration Control Strategy Selection").sublist("Simple Integration Control Strategy").set("Fixed dt",dt); ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Backward Euler"); //ibPL->sublist("Stepper Settings").sublist("Stepper Selection").set("Stepper Type","Implicit RK"); //ibPL->sublist("Stepper Settings").sublist("Runge Kutta Butcher Tableau Selection").set("Runge Kutta Butcher Tableau Type","Implicit 1 Stage 2nd order Gauss"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").set("Interpolation Buffer Type","Interpolation Buffer"); ibPL->sublist("Interpolation Buffer Settings").sublist("Trailing Interpolation Buffer Selection").sublist("Interpolation Buffer").set("StorageLimit",storageLimit); ibPL->sublist("Interpolation Buffer Settings").sublist("Interpolator Selection").set("Interpolator Type","Linear Interpolator"); ib->setParameterList(ibPL); } RCP<Thyra::ModelEvaluator<double> > adjModel; { RCP<Rythmos::AdjointModelEvaluator<double> > model = Rythmos::adjointModelEvaluator<double>( fwdModel, fwdTimeRange ); //model->setFwdStateSolutionBuffer(fwdCubicSplineInterpBuffer); adjModel = model; } Thyra::ModelEvaluatorBase::InArgs<double> adjIC = adjModel->getNominalValues(); double phi_ic_0 = 2.0; double phi_ic_1 = 3.0; { // Initial conditions for adjoint: const RCP<const Thyra::VectorSpaceBase<double> > f_space = fwdModel->get_f_space(); const RCP<Thyra::VectorBase<double> > x_ic = createMember(f_space); { Thyra::DetachedVectorView<double> x_ic_view( *x_ic ); x_ic_view[0] = phi_ic_0; x_ic_view[1] = phi_ic_1; } const RCP<Thyra::VectorBase<double> > xdot_ic = createMember(f_space); V_S( Teuchos::outArg(*xdot_ic), ST::zero() ); adjIC.set_x(x_ic); adjIC.set_x_dot(xdot_ic); } RCP<Thyra::LinearNonlinearSolver<double> > adjNLSolver = Thyra::linearNonlinearSolver<double>(); RCP<IntegratorBase<double> > adjIntegrator = ib->create(adjModel,adjIC,adjNLSolver); RCP<const VectorBase<double> > phi_final; { Array<double> time_vec; time_vec.push_back(finalTime); Array<RCP<const Thyra::VectorBase<double> > > phi_final_array; adjIntegrator->getFwdPoints(time_vec,&phi_final_array,NULL,NULL); phi_final = phi_final_array[0]; } // Verify phi_final is correct { // Defaults from SinCos Model: double f = 1.0; double L = 1.0; double h = -dt; double phi_0 = 1.0/(1.0+std::pow(f*h/L,2.0))*(phi_ic_0+std::pow(f/L,2.0)*h*phi_ic_1); double phi_1 = 1.0/(1.0+std::pow(f*h/L,2.0))*(-h*phi_ic_0+phi_ic_1); double tol = 1.0e-10; Thyra::ConstDetachedVectorView<double> phi_final_view( *phi_final ); TEST_FLOATING_EQUALITY( phi_final_view[0], phi_0, tol ); TEST_FLOATING_EQUALITY( phi_final_view[1], phi_1, tol ); } // Compute error estimate //TEST_ASSERT( false ); }
TEUCHOS_UNIT_TEST( Rythmos_TimeRange, invalidTimeRange ) { TimeRange<double> tr = invalidTimeRange<double>(); TEST_EQUALITY_CONST( tr.isValid(), false ); TEST_COMPARE( tr.lower(), >, tr.upper() ); TEST_EQUALITY_CONST( tr.isInRange(0.5), false ); }
TEUCHOS_UNIT_TEST( Rythmos_TimeRange, nonMemberConstructor ) { TimeRange<double> tr = timeRange(1.25,3.45); TEST_EQUALITY_CONST( tr.isValid(), true ); TEST_EQUALITY_CONST( tr.lower(), 1.25 ); TEST_EQUALITY_CONST( tr.upper(), 3.45 ); }