00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #ifndef Rythmos_FORWARD_SENSITIVITY_STEPPER_TESTER_DEF_H
00030 #define Rythmos_FORWARD_SENSITIVITY_STEPPER_TESTER_DEF_H
00031
00032
00033 #include "Rythmos_ForwardSensitivityStepperTester_decl.hpp"
00034 #include "Rythmos_ForwardSensitivityStepper.hpp"
00035 #include "Rythmos_StepperAsModelEvaluator.hpp"
00036 #include "Thyra_DirectionalFiniteDiffCalculator.hpp"
00037 #include "Thyra_TestingTools.hpp"
00038
00039
00040 template<class Scalar>
00041 Teuchos::RCP<Rythmos::ForwardSensitivityStepperTester<Scalar> >
00042 Rythmos::forwardSensitivityStepperTester()
00043 {
00044 return Teuchos::rcp(new ForwardSensitivityStepperTester<Scalar>);
00045 }
00046
00047
00048 template<class Scalar>
00049 Teuchos::RCP<Rythmos::ForwardSensitivityStepperTester<Scalar> >
00050 Rythmos::forwardSensitivityStepperTester(const RCP<ParameterList> ¶mList)
00051 {
00052 const RCP<Rythmos::ForwardSensitivityStepperTester<Scalar> > fsst =
00053 forwardSensitivityStepperTester<Scalar>();
00054 fsst->setParameterList(paramList);
00055 return fsst;
00056 }
00057
00058
00059 namespace Rythmos {
00060
00061
00062
00063
00064
00065 template<class Scalar>
00066 void ForwardSensitivityStepperTester<Scalar>::setParameterList(
00067 RCP<ParameterList> const& paramList
00068 )
00069 {
00070 namespace FSSTU = ForwardSensitivityStepperTesterUtils;
00071 paramList->validateParametersAndSetDefaults(*this->getValidParameters());
00072 this->setMyParamList(paramList);
00073 errorTol_ = Teuchos::getParameter<double>(*paramList, FSSTU::ErrorTol_name);
00074 }
00075
00076
00077 template<class Scalar>
00078 RCP<const ParameterList>
00079 ForwardSensitivityStepperTester<Scalar>::getValidParameters() const
00080 {
00081 namespace FSSTU = ForwardSensitivityStepperTesterUtils;
00082 static RCP<const ParameterList> validPL;
00083 if (is_null(validPL)) {
00084 const RCP<ParameterList> pl = Teuchos::parameterList();
00085 pl->set(FSSTU::ErrorTol_name, FSSTU::ErrorTol_default);
00086 pl->sublist(FSSTU::FdCalc_name).disableRecursiveValidation().setParameters(
00087 *Thyra::DirectionalFiniteDiffCalculator<Scalar>().getValidParameters()
00088 );
00089 validPL = pl;
00090 }
00091 return validPL;
00092 }
00093
00094
00095 template<class Scalar>
00096 bool ForwardSensitivityStepperTester<Scalar>::testForwardSens(
00097 const Ptr<IntegratorBase<Scalar> > &fwdSensIntegrator
00098 )
00099 {
00100
00101 using Teuchos::outArg;
00102 using Teuchos::rcp_dynamic_cast;
00103 using Teuchos::OSTab;
00104 using Teuchos::sublist;
00105 typedef Thyra::ModelEvaluatorBase MEB;
00106 namespace FSSTU = ForwardSensitivityStepperTesterUtils;
00107
00108 const Teuchos::EVerbosityLevel verbLevel = this->getVerbLevel();
00109 const RCP<Teuchos::FancyOStream> out = this->getOStream();
00110
00111 const RCP<ParameterList> paramList = this->getMyNonconstParamList();
00112
00113 bool success = true;
00114
00115
00116 RCP<ForwardSensitivityStepper<Scalar> > fwdSensStepper =
00117 rcp_dynamic_cast<ForwardSensitivityStepper<Scalar> >(
00118 fwdSensIntegrator->getNonconstStepper()
00119 );
00120
00121
00122 RCP<StepperBase<Scalar> > stateStepper = fwdSensStepper->getNonconstStateStepper();
00123
00124
00125
00126 MEB::InArgs<Scalar> state_and_sens_ic = fwdSensStepper->getInitialCondition();
00127 MEB::InArgs<Scalar> state_ic =
00128 extractStateInitialCondition(*fwdSensStepper, state_and_sens_ic);
00129
00130
00131
00132 RCP<StepperAsModelEvaluator<Scalar> >
00133 stateIntegratorAsModel = stepperAsModelEvaluator(
00134 stateStepper, fwdSensIntegrator->cloneIntegrator(), state_ic
00135 );
00136
00137
00138
00139
00140 const Scalar finalTime = fwdSensIntegrator->getFwdTimeRange().upper();
00141
00142 *out << "\nCompute discrete forward sensitivities using fwdSensIntegrator ...\n";
00143
00144 RCP<const VectorBase<Scalar> > x_bar_final, x_bar_dot_final;
00145 {
00146 OSTab tab(out);
00147 get_fwd_x_and_x_dot( *fwdSensIntegrator, finalTime,
00148 outArg(x_bar_final), outArg(x_bar_dot_final) );
00149 *out
00150 << "\nx_bar_final = x_bar(p,finalTime) evaluated using stateAndSensIntegratorAsModel:\n"
00151 << describe(*x_bar_final, verbLevel);
00152 }
00153
00154
00155
00156 *out << "\nCompute discrete forward sensitivities by finite differences ...\n";
00157
00158 RCP<Thyra::MultiVectorBase<Scalar> > DxDp_fd_final;
00159 {
00160 OSTab tab(out);
00161
00162 Thyra::DirectionalFiniteDiffCalculator<Scalar> fdCalc;
00163 if (nonnull(paramList))
00164 fdCalc.setParameterList(sublist(paramList, FSSTU::FdCalc_name));
00165 fdCalc.setOStream(out);
00166 fdCalc.setVerbLevel(Teuchos::VERB_NONE);
00167
00168 MEB::InArgs<Scalar>
00169 fdBasePoint = stateIntegratorAsModel->createInArgs();
00170
00171 fdBasePoint.setArgs(state_ic, true);
00172 fdBasePoint.set_t(finalTime);
00173
00174 const int g_index = 0;
00175 const int p_index = fwdSensStepper->getFwdSensModel()->get_p_index();
00176
00177 DxDp_fd_final =
00178 createMembers(
00179 stateIntegratorAsModel->get_g_space(g_index),
00180 stateIntegratorAsModel->get_p_space(p_index)->dim()
00181 );
00182
00183 typedef Thyra::DirectionalFiniteDiffCalculatorTypes::SelectedDerivatives
00184 SelectedDerivatives;
00185
00186 MEB::OutArgs<Scalar> fdOutArgs =
00187 fdCalc.createOutArgs(
00188 *stateIntegratorAsModel,
00189 SelectedDerivatives().supports(MEB::OUT_ARG_DgDp, g_index, p_index)
00190 );
00191 fdOutArgs.set_DgDp(g_index, p_index, DxDp_fd_final);
00192
00193
00194
00195 stateStepper->setVerbLevel(Teuchos::VERB_NONE);
00196 stateIntegratorAsModel->setVerbLevel(Teuchos::VERB_NONE);
00197
00198 fdCalc.calcDerivatives(
00199 *stateIntegratorAsModel, fdBasePoint,
00200 stateIntegratorAsModel->createOutArgs(),
00201 fdOutArgs
00202 );
00203
00204 *out
00205 << "\nFinite difference DxDp_fd_final = DxDp(p,finalTime): "
00206 << describe(*DxDp_fd_final, verbLevel);
00207
00208 }
00209
00210
00211
00212 *out << "\nChecking that integrated DxDp(p,finalTime) and finite-diff DxDp(p,finalTime) are similar ...\n";
00213
00214 {
00215
00216 Teuchos::OSTab tab(out);
00217
00218 RCP<const Thyra::VectorBase<Scalar> >
00219 DxDp_vec_final = Thyra::productVectorBase<Scalar>(x_bar_final)->getVectorBlock(1);
00220
00221 RCP<const Thyra::VectorBase<Scalar> >
00222 DxDp_fd_vec_final = Thyra::multiVectorProductVector(
00223 rcp_dynamic_cast<const Thyra::DefaultMultiVectorProductVectorSpace<Scalar> >(
00224 DxDp_vec_final->range()
00225 ),
00226 DxDp_fd_final
00227 );
00228
00229 const bool result = Thyra::testRelNormDiffErr(
00230 "DxDp_vec_final", *DxDp_vec_final,
00231 "DxDp_fd_vec_final", *DxDp_fd_vec_final,
00232 "maxSensError", errorTol_,
00233 "warningTol", 1.0,
00234 &*out, verbLevel
00235 );
00236 if (!result)
00237 success = false;
00238
00239 }
00240
00241 return success;
00242
00243 }
00244
00245
00246 template<class Scalar>
00247 ForwardSensitivityStepperTester<Scalar>::ForwardSensitivityStepperTester()
00248 : errorTol_(ForwardSensitivityStepperTesterUtils::ErrorTol_default)
00249 {}
00250
00251
00252 }
00253
00254
00255
00256
00257
00258
00259
00260
00261 #define FORWARD_SENSITIVITY_STEPPER_INSTANT(SCALAR) \
00262 \
00263 template class ForwardSensitivityStepperTester<SCALAR >; \
00264 \
00265 template RCP<ForwardSensitivityStepperTester<SCALAR > > \
00266 forwardSensitivityStepperTester(); \
00267 \
00268 template RCP<ForwardSensitivityStepperTester<SCALAR> > \
00269 forwardSensitivityStepperTester(const RCP<ParameterList> ¶mList);
00270
00271
00272 #endif //Rythmos_FORWARD_SENSITIVITY_STEPPER_TESTER_DEF_H