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 #ifndef PHX_FIELD_EVALUATOR_MANAGER_DEF_HPP
00033 #define PHX_FIELD_EVALUATOR_MANAGER_DEF_HPP
00034
00035 #include "Phalanx_ConfigDefs.hpp"
00036 #include "Teuchos_TestForException.hpp"
00037 #include "Phalanx_Evaluator.hpp"
00038 #include "Phalanx_FieldTag_STL_Functors.hpp"
00039
00040
00041 template<typename Traits>
00042 PHX::EvaluatorManager<Traits>::
00043 EvaluatorManager(const std::string& evaluation_type_name) :
00044 evaluation_type_name_(evaluation_type_name),
00045 sorting_called_(false)
00046 { }
00047
00048
00049 template<typename Traits>
00050 PHX::EvaluatorManager<Traits>::~EvaluatorManager()
00051 { }
00052
00053
00054 template<typename Traits>
00055 void PHX::EvaluatorManager<Traits>::
00056 requireField(const PHX::FieldTag& t)
00057 {
00058 FTPredRef pred(t);
00059 std::vector< Teuchos::RCP<PHX::FieldTag> >::iterator i =
00060 find_if(fields_.begin(), fields_.end(), pred);
00061
00062 if (i == fields_.end())
00063 fields_.push_back(t.clone());
00064 }
00065
00066
00067 template<typename Traits>
00068 void PHX::EvaluatorManager<Traits>::
00069 registerEvaluator(const Teuchos::RCP<PHX::Evaluator<Traits> >& p)
00070 {
00071 varProviders.push_back(p);
00072 providerVariables.push_back(p->evaluatedFields());
00073 providerRequirements.push_back(p->dependentFields());
00074 providerNames.push_back(p->getName());
00075
00076 #ifdef CHARONDEBUG
00077 char const* const methodID =
00078 "charon:EvaluatorManager::registerEvaluator";
00079 if (DO_DEBUG_OUTPUT(methodID,10)) {
00080 std::cout << "Registered provider: " << p->getName()
00081 << std::endl
00082 << "Element block: " << blockID << std::endl
00083 << "Index in vector: " << varProviders.size() - 1
00084 << std::endl << "Evaluates:" << std::endl;
00085 for (uint i=0; i < p->evaluatedFields().size(); ++i) {
00086 std::cout << " " << p->evaluatedFields()[i].name() << std::endl;
00087 }
00088 }
00089 #endif
00090
00095 }
00096
00097
00098 template<typename Traits>
00099 void PHX::EvaluatorManager<Traits>::
00100 sortAndOrderEvaluators()
00101 {
00102 if (sorting_called_) {
00103 std::string msg = "Setup was already called. ";
00104 msg += "Don't call setup more than once!";
00105 TEST_FOR_EXCEPTION(true, std::logic_error, msg);
00106 }
00107
00108
00109 this->createProviderEvaluationOrder();
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 for (std::size_t i = 0; i < providerEvalOrderIndex.size(); i++) {
00123 std::size_t k = providerEvalOrderIndex[i];
00124 for (std::size_t j = 0; j <providerVariables[k].size(); j++)
00125 this->requireField(*(providerVariables[k][j]));
00126 }
00127
00128 sorting_called_ = true;
00129 }
00130
00131
00132 template<typename Traits>
00133 void PHX::EvaluatorManager<Traits>::
00134 postRegistrationSetup(PHX::FieldManager<Traits>& vm)
00135 {
00136
00137 for (std::size_t i = 0; i < providerEvalOrderIndex.size(); i++)
00138 (varProviders[providerEvalOrderIndex[i]])->postRegistrationSetup(vm);
00139 }
00140
00141
00142 template<typename Traits>
00143 void PHX::EvaluatorManager<Traits>::createProviderEvaluationOrder()
00144 {
00145
00146
00147 bool done = false;
00148 while (!done) {
00149 bool addedVariables = false;
00150
00151 for (std::size_t i = 0; i < fields_.size(); i++) {
00152 const PHX::FieldTag& v = *(fields_[i]);
00153
00154
00155 for (std::size_t prov = 0; prov < providerVariables.size(); prov++) {
00156 for (std::size_t var = 0; var < providerVariables[prov].size(); var++) {
00157 if (*(providerVariables[prov][var]) == v) {
00158
00159 for (std::size_t r = 0; r < providerRequirements[prov].size(); r++) {
00160 bool isVariable = false;
00161 for (std::size_t j = 0; j < fields_.size(); j++) {
00162 if (*(fields_[j]) == *(providerRequirements[prov][r]))
00163 isVariable = true;
00164 }
00165 if (!isVariable) {
00166 fields_.push_back(providerRequirements[prov][r]);
00167 addedVariables = true;
00168 }
00169 }
00170 }
00171 }
00172 }
00173 }
00174 if (!addedVariables)
00175 done = true;
00176 }
00177
00178 std::vector<Teuchos::RCP<PHX::FieldTag> > tmpList = fields_;
00179 std::vector<Teuchos::RCP<PHX::FieldTag> > tmpProvided;
00180
00181
00182 while (tmpList.size() > 0) {
00183
00184 bool removedVariable = false;
00185
00186
00187
00188 bool foundProvider = false;
00189 int providerIndex = -1;
00190 for (std::size_t var = 0; var < tmpList.size(); var++) {
00191
00192 foundProvider = false;
00193 providerIndex = -1;
00194
00195
00196 for (std::size_t prov = 0; prov < varProviders.size(); prov++) {
00197
00198
00199 for (std::size_t i = 0; i < providerVariables[prov].size(); i++) {
00200
00201 if (*(tmpList[var]) == *(providerVariables[prov][i])) {
00202 foundProvider = true;
00203 providerIndex = prov;
00204 break;
00205 }
00206
00207 }
00208
00209 if (foundProvider)
00210 break;
00211 }
00212
00213
00214
00215 bool requirementsSatisfied = true;
00216
00217 if (foundProvider) {
00218 if (providerRequirements[providerIndex].size() > 0) {
00219
00220 for (std::size_t req = 0;
00221 req < providerRequirements[providerIndex].size();
00222 req++) {
00223 bool requiredVariableFound = false;
00224 for (std::size_t j = 0; j < tmpProvided.size(); j++) {
00225 if (*(providerRequirements[providerIndex][req]) ==
00226 *(tmpProvided[j]))
00227 requiredVariableFound = true;
00228 }
00229 if (!requiredVariableFound) {
00230 requirementsSatisfied = false;
00231 break;
00232 }
00233
00234 }
00235 }
00236 }
00237
00238 if (foundProvider && requirementsSatisfied) {
00239
00240
00241 std::vector<Teuchos::RCP<PHX::FieldTag> >::iterator p =
00242 tmpList.begin();
00243 tmpList.erase(p+var);
00244
00245
00246 for (std::size_t i = 0; i < providerVariables[providerIndex].size(); i++) {
00247 tmpProvided.push_back(providerVariables[providerIndex][i]);
00248 for (std::size_t j = 0; j < tmpList.size(); j++) {
00249 if (*(providerVariables[providerIndex][i]) == *(tmpList[j])) {
00250 std::vector<Teuchos::RCP<PHX::FieldTag> >::iterator a =
00251 tmpList.begin();
00252 tmpList.erase(a+j);
00253 break;
00254 }
00255 }
00256 }
00257 providerEvalOrderIndex.push_back(providerIndex);
00258 removedVariable = true;
00259 break;
00260 }
00261
00262 }
00263
00264 if (!removedVariable) {
00265 std::string msg = "EvaluatorManager";
00266 msg += evaluation_type_name_;
00267 msg += " \nCould not meet dependencies!\n";
00268 msg += "The following variables either have no provider or have a\n";
00269 msg += "provider but could not satisfy provider requirements:\n\n";
00270 std::ostringstream ost;
00271 for (std::size_t i = 0; i < tmpList.size(); i++)
00272 ost << *(tmpList[i]) << std::endl;
00273 msg += ost.str();
00274 msg += "\nPrinting EvaluatorManager:\n";
00275 std::ostringstream ost2;
00276 ost2 << *this << std::endl;
00277 msg += ost2.str();
00278 TEST_FOR_EXCEPTION(true, std::logic_error, msg);
00279 }
00280
00281 }
00282
00283 }
00284
00285
00286 template<typename Traits>
00287 void PHX::EvaluatorManager<Traits>::
00288 evaluateFields(typename Traits::EvalData d)
00289 {
00290 for (std::size_t i = 0; i < providerEvalOrderIndex.size(); i++)
00291 (varProviders[providerEvalOrderIndex[i]])->evaluateFields(d);
00292 }
00293
00294
00295 template<typename Traits>
00296 void PHX::EvaluatorManager<Traits>::
00297 preEvaluate(typename Traits::PreEvalData d)
00298 {
00299 for (std::size_t i = 0; i < providerEvalOrderIndex.size(); i++)
00300 (varProviders[providerEvalOrderIndex[i]])->preEvaluate(d);
00301 }
00302
00303
00304 template<typename Traits>
00305 void PHX::EvaluatorManager<Traits>::
00306 postEvaluate(typename Traits::PostEvalData d)
00307 {
00308 for (std::size_t i = 0; i < providerEvalOrderIndex.size(); i++)
00309 (varProviders[providerEvalOrderIndex[i]])->postEvaluate(d);
00310 }
00311
00312
00313 template<typename Traits>
00314 void PHX::EvaluatorManager<Traits>::
00315 setEvaluationTypeName(const std::string& evaluation_type_name)
00316 {
00317 evaluation_type_name_ = evaluation_type_name;
00318 }
00319
00320
00321 template<typename Traits>
00322 const std::vector< Teuchos::RCP<PHX::FieldTag> >&
00323 PHX::EvaluatorManager<Traits>::getFieldTags()
00324 {
00325 return fields_;
00326 }
00327
00328
00329 template<typename Traits>
00330 bool PHX::EvaluatorManager<Traits>::sortingCalled() const
00331 {
00332 return sorting_called_;
00333 }
00334
00335
00336 template<typename Traits>
00337 void PHX::EvaluatorManager<Traits>::print(std::ostream& os) const
00338 {
00339 os << "******************************************************" << std::endl;
00340 os << "PHX::EvaluatorManager" << std::endl;
00341 os << "Evaluation Type = " << evaluation_type_name_ << std::endl;
00342 os << "******************************************************" << std::endl;
00343
00344 os << "\n** Starting Required Field List" << std::endl;
00345 for (std::size_t i = 0; i < fields_.size(); i++) {
00346 os << *(this->fields_[i]) << std::endl;
00347 }
00348 os << "** Finished Required Field List" << std::endl;
00349
00350 os << "\n** Starting Registered Field Evaluators" << std::endl;
00351 for (std::size_t i = 0; i < varProviders.size(); i++) {
00352 os << "Evaluator[" << i << "]: " << providerNames[i] << std::endl;
00353 os << " *Evaluates:" << std::endl;
00354 for (std::size_t j = 0; j < providerVariables[i].size(); j++)
00355 os << " " << *((this->providerVariables[i])[j]) << std::endl;
00356 os << " *Dependencies:";
00357 if (providerRequirements[i].size() == 0) {
00358 os << " None!" << std::endl;
00359 }
00360 else {
00361 os << std::endl;
00362 for (std::size_t j = 0; j < providerRequirements[i].size(); j++)
00363 os << " " << *((this->providerRequirements[i])[j]) << std::endl;
00364 }
00365 }
00366 os << "** Finished Registered Field Evaluators" << std::endl;
00367
00368
00369 os << "\n** Starting Evaluator Order" << std::endl;
00370 for (std::size_t k = 0; k < providerEvalOrderIndex.size(); k++) {
00371 os << k << " " << providerEvalOrderIndex[k] << std::endl;
00372 }
00373 os << "\nDetails:\n";
00374 for (std::size_t k = 0; k < providerEvalOrderIndex.size(); k++) {
00375 int i = providerEvalOrderIndex[k];
00376 os << "Evaluator[" << i << "]: " << providerNames[i] << std::endl;
00377 os << " *Evaluates:" << std::endl;
00378 for (std::size_t j = 0; j < providerVariables[i].size(); j++)
00379 os << " " << *((this->providerVariables[i])[j]) << std::endl;
00380 os << " *Dependencies:";
00381 if (providerRequirements[i].size() == 0) {
00382 os << " None!" << std::endl;
00383 }
00384 else {
00385 os << std::endl;
00386 for (std::size_t j = 0; j < providerRequirements[i].size(); j++)
00387 os << " " << *((this->providerRequirements[i])[j]) << std::endl;
00388 }
00389 }
00390 os << "** Finished Provider Evaluation Order" << std::endl;
00391
00392 os << "******************************************************" << std::endl;
00393 os << "Finished PHX::EvaluatorManager" << std::endl;
00394 os << "Evaluation Type = " << evaluation_type_name_ << std::endl;
00395 os << "******************************************************" << std::endl;
00396
00397 }
00398
00399
00400 template<typename Traits>
00401 std::ostream&
00402 PHX::operator<<(std::ostream& os, const PHX::EvaluatorManager<Traits>& m)
00403 {
00404 m.print(os);
00405 return os;
00406 }
00407
00408
00409
00410 #endif