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
00030
00031
00032 #include "FEApp_ModelEvaluator.hpp"
00033 #include "Teuchos_ScalarTraits.hpp"
00034 #include "Teuchos_TestForException.hpp"
00035
00036 FEApp::ModelEvaluator::ModelEvaluator(
00037 const Teuchos::RCP<FEApp::Application>& app_,
00038 const Teuchos::RCP< Teuchos::Array<std::string> >& free_param_names)
00039 : app(app_),
00040 param_names(free_param_names)
00041 {
00042
00043 sacado_param_vec = Teuchos::rcp(new Sacado::ScalarParameterVector);
00044 if (param_names != Teuchos::null)
00045 app->getParamLib()->fillVector(*param_names, *sacado_param_vec);
00046
00047
00048 const Epetra_Comm& comm = app->getMap()->Comm();
00049 epetra_param_map = Teuchos::rcp(new Epetra_LocalMap(sacado_param_vec->size(),
00050 0, comm));
00051
00052
00053 epetra_param_vec = Teuchos::rcp(new Epetra_Vector(*epetra_param_map));
00054
00055
00056 for (unsigned int i=0; i<sacado_param_vec->size(); i++)
00057 (*epetra_param_vec)[i] = (*sacado_param_vec)[i].baseValue;
00058
00059 }
00060
00061
00062
00063 Teuchos::RCP<const Epetra_Map>
00064 FEApp::ModelEvaluator::get_x_map() const
00065 {
00066 return app->getMap();
00067 }
00068
00069 Teuchos::RCP<const Epetra_Map>
00070 FEApp::ModelEvaluator::get_f_map() const
00071 {
00072 return app->getMap();
00073 }
00074
00075 Teuchos::RCP<const Epetra_Map>
00076 FEApp::ModelEvaluator::get_p_map(int l) const
00077 {
00078 TEST_FOR_EXCEPTION(l != 0, Teuchos::Exceptions::InvalidParameter,
00079 std::endl <<
00080 "Error! FEApp::ModelEvaluator::get_p_map() only " <<
00081 " supports 1 parameter vector. Supplied index l = " <<
00082 l << std::endl);
00083
00084 return epetra_param_map;
00085 }
00086
00087 Teuchos::RCP<const Teuchos::Array<std::string> >
00088 FEApp::ModelEvaluator::get_p_names(int l) const
00089 {
00090 TEST_FOR_EXCEPTION(l != 0, Teuchos::Exceptions::InvalidParameter,
00091 std::endl <<
00092 "Error! FEApp::ModelEvaluator::get_p_names() only " <<
00093 " supports 1 parameter vector. Supplied index l = " <<
00094 l << std::endl);
00095 return param_names;
00096 }
00097
00098 Teuchos::RCP<const Epetra_Vector>
00099 FEApp::ModelEvaluator::get_x_init() const
00100 {
00101 return app->getInitialSolution();
00102 }
00103
00104 Teuchos::RCP<const Epetra_Vector>
00105 FEApp::ModelEvaluator::get_p_init(int l) const
00106 {
00107 TEST_FOR_EXCEPTION(l != 0, Teuchos::Exceptions::InvalidParameter,
00108 std::endl <<
00109 "Error! FEApp::ModelEvaluator::get_p_init() only " <<
00110 " supports 1 parameter vector. Supplied index l = " <<
00111 l << std::endl);
00112
00113 return epetra_param_vec;
00114 }
00115
00116 Teuchos::RCP<Epetra_Operator>
00117 FEApp::ModelEvaluator::create_W() const
00118 {
00119 return
00120 Teuchos::rcp(new Epetra_CrsMatrix(::Copy, *(app->getJacobianGraph())));
00121 }
00122
00123 EpetraExt::ModelEvaluator::InArgs
00124 FEApp::ModelEvaluator::createInArgs() const
00125 {
00126 InArgsSetup inArgs;
00127 inArgs.setModelEvalDescription(this->description());
00128 inArgs.setSupports(IN_ARG_x,true);
00129 inArgs.set_Np(1);
00130 if (app->isTransient()) {
00131 inArgs.setSupports(IN_ARG_t,true);
00132 inArgs.setSupports(IN_ARG_x_dot,true);
00133 inArgs.setSupports(IN_ARG_alpha,true);
00134 inArgs.setSupports(IN_ARG_beta,true);
00135 }
00136 return inArgs;
00137 }
00138
00139 EpetraExt::ModelEvaluator::OutArgs
00140 FEApp::ModelEvaluator::createOutArgs() const
00141 {
00142 OutArgsSetup outArgs;
00143 outArgs.setModelEvalDescription(this->description());
00144 outArgs.set_Np_Ng(1, 0);
00145 outArgs.setSupports(OUT_ARG_f,true);
00146 outArgs.setSupports(OUT_ARG_W,true);
00147 outArgs.setSupports(OUT_ARG_DfDp, 0, DerivativeSupport(DERIV_MV_BY_COL));
00148 outArgs.set_W_properties(
00149 DerivativeProperties(
00150 DERIV_LINEARITY_UNKNOWN ,DERIV_RANK_FULL ,true)
00151 );
00152 return outArgs;
00153 }
00154
00155 void
00156 FEApp::ModelEvaluator::evalModel(const InArgs& inArgs,
00157 const OutArgs& outArgs) const
00158 {
00159
00160
00161
00162 const Epetra_Vector& x = *inArgs.get_x();
00163 const Epetra_Vector *x_dot = NULL;
00164 double alpha = 0.0;
00165 double beta = 1.0;
00166 if (app->isTransient()) {
00167 x_dot = inArgs.get_x_dot().get();
00168 if (x_dot) {
00169 alpha = inArgs.get_alpha();
00170 beta = inArgs.get_beta();
00171 }
00172 }
00173 const Epetra_Vector *p = inArgs.get_p(0).get();
00174 if (p != NULL) {
00175 for (unsigned int i=0; i<sacado_param_vec->size(); i++)
00176 (*sacado_param_vec)[i].baseValue = (*p)[i];
00177 }
00178
00179
00180
00181
00182 Teuchos::RCP<Epetra_Vector> f_out = outArgs.get_f();
00183 Teuchos::RCP<Epetra_Operator> W_out = outArgs.get_W();
00184 Teuchos::RCP<Epetra_MultiVector> dfdp_out;
00185 if (outArgs.Np() > 0)
00186 dfdp_out = outArgs.get_DfDp(0).getMultiVector();
00187
00188
00189 Teuchos::RCP<Epetra_CrsMatrix> W_out_crs =
00190 Teuchos::rcp_dynamic_cast<Epetra_CrsMatrix>(W_out, true);
00191
00192
00193
00194
00195 if(W_out != Teuchos::null) {
00196 app->computeGlobalJacobian(alpha, beta, x_dot, x, sacado_param_vec.get(),
00197 f_out.get(), *W_out_crs);
00198 }
00199 else if (dfdp_out != Teuchos::null) {
00200 Teuchos::Array<int> p_indexes =
00201 outArgs.get_DfDp(0).getDerivativeMultiVector().getParamIndexes();
00202 unsigned int n_params = p_indexes.size();
00203 Teuchos::Array<std::string> p_names(n_params);
00204 for (unsigned int i=0; i<n_params; i++)
00205 p_names[i] = (*param_names)[p_indexes[i]];
00206 Sacado::ScalarParameterVector p_vec;
00207 app->getParamLib()->fillVector(p_names, p_vec);
00208 for (unsigned int i=0; i<p_vec.size(); i++)
00209 p_vec[i].baseValue = (*p)[p_indexes[i]];
00210
00211 app->computeGlobalTangent(0.0, 0.0, false, x_dot, x, &p_vec,
00212 NULL, NULL, f_out.get(), NULL, dfdp_out.get());
00213 }
00214 else if(f_out != Teuchos::null ) {
00215 app->computeGlobalResidual(x_dot, x, sacado_param_vec.get(), *f_out);
00216 }
00217 }