Panzer Version of the Day
Loading...
Searching...
No Matches
Panzer_ModelEvaluator_impl.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Panzer: A partial differential equation assembly
4// engine for strongly coupled complex multiphysics systems
5//
6// Copyright 2011 NTESS and the Panzer contributors.
7// SPDX-License-Identifier: BSD-3-Clause
8// *****************************************************************************
9// @HEADER
10
11#ifndef __Panzer_ModelEvaluator_impl_hpp__
12#define __Panzer_ModelEvaluator_impl_hpp__
13
14#include "Teuchos_DefaultComm.hpp"
15#include "Teuchos_ArrayRCP.hpp"
16
17#include "PanzerDiscFE_config.hpp"
18#include "Panzer_Traits.hpp"
25#include "Panzer_GlobalData.hpp"
33
34#include "Thyra_TpetraThyraWrappers.hpp"
35#include "Thyra_SpmdVectorBase.hpp"
36#include "Thyra_DefaultSpmdVector.hpp"
37#include "Thyra_DefaultSpmdVectorSpace.hpp"
38#include "Thyra_DefaultMultiVectorProductVectorSpace.hpp"
39#include "Thyra_DefaultMultiVectorProductVector.hpp"
40#include "Thyra_MultiVectorStdOps.hpp"
41#include "Thyra_VectorStdOps.hpp"
42
43// For writing out residuals/Jacobians
44#include "Thyra_ProductVectorBase.hpp"
45#include "Thyra_BlockedLinearOpBase.hpp"
46#include "Thyra_TpetraVector.hpp"
47#include "Thyra_TpetraLinearOp.hpp"
48#include "Tpetra_CrsMatrix.hpp"
49
50// Constructors/Initializers/Accessors
51
52template<typename Scalar>
54ModelEvaluator(const Teuchos::RCP<panzer::FieldManagerBuilder>& fmb,
55 const Teuchos::RCP<panzer::ResponseLibrary<panzer::Traits> >& rLibrary,
56 const Teuchos::RCP<const panzer::LinearObjFactory<panzer::Traits> >& lof,
57 const std::vector<Teuchos::RCP<Teuchos::Array<std::string> > >& p_names,
58 const std::vector<Teuchos::RCP<Teuchos::Array<double> > >& p_values,
59 const Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > & solverFactory,
60 const Teuchos::RCP<panzer::GlobalData>& global_data,
61 bool build_transient_support,
62 double t_init)
63 : t_init_(t_init)
64 , num_me_parameters_(0)
65 , do_fd_dfdp_(false)
66 , fd_perturb_size_(1e-7)
67 , require_in_args_refresh_(true)
68 , require_out_args_refresh_(true)
69 , responseLibrary_(rLibrary)
70 , global_data_(global_data)
71 , build_transient_support_(build_transient_support)
72 , lof_(lof)
73 , solverFactory_(solverFactory)
74 , oneTimeDirichletBeta_on_(false)
75 , oneTimeDirichletBeta_(0.0)
76 , build_volume_field_managers_(true)
77 , build_bc_field_managers_(true)
78 , active_evaluation_types_(Sacado::mpl::size<panzer::Traits::EvalTypes>::value, true)
79 , write_matrix_count_(0)
80{
81 using Teuchos::RCP;
82 using Teuchos::rcp;
83 using Teuchos::rcp_dynamic_cast;
84 using Teuchos::tuple;
86 using Thyra::createMember;
87
88 TEUCHOS_ASSERT(lof_!=Teuchos::null);
89
91 ae_tm_.buildObjects(builder);
92
93 //
94 // Build x, f spaces
95 //
96
97 // dynamic cast to blocked LOF for now
98 RCP<const ThyraObjFactory<Scalar> > tof = rcp_dynamic_cast<const ThyraObjFactory<Scalar> >(lof,true);
99
100 x_space_ = tof->getThyraDomainSpace();
101 f_space_ = tof->getThyraRangeSpace();
102
103 //
104 // Setup parameters
105 //
106 for(std::size_t i=0;i<p_names.size();i++)
107 addParameter(*(p_names[i]),*(p_values[i]));
108
109 // now that the vector spaces are setup we can allocate the nominal values
110 // (i.e. initial conditions)
112}
113
114template<typename Scalar>
116ModelEvaluator(const Teuchos::RCP<const panzer::LinearObjFactory<panzer::Traits> >& lof,
117 const Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> > & solverFactory,
118 const Teuchos::RCP<panzer::GlobalData>& global_data,
119 bool build_transient_support,double t_init)
120 : t_init_(t_init)
121 , num_me_parameters_(0)
122 , do_fd_dfdp_(false)
123 , fd_perturb_size_(1e-7)
124 , require_in_args_refresh_(true)
125 , require_out_args_refresh_(true)
126 , global_data_(global_data)
127 , build_transient_support_(build_transient_support)
128 , lof_(lof)
129 , solverFactory_(solverFactory)
130 , oneTimeDirichletBeta_on_(false)
131 , oneTimeDirichletBeta_(0.0)
132 , build_volume_field_managers_(true)
133 , build_bc_field_managers_(true)
134 , active_evaluation_types_(Sacado::mpl::size<panzer::Traits::EvalTypes>::value, true)
135 , write_matrix_count_(0)
136{
137 using Teuchos::RCP;
138 using Teuchos::rcp_dynamic_cast;
139
140 TEUCHOS_ASSERT(lof_!=Teuchos::null);
141
142 //
143 // Build x, f spaces
144 //
145
146 // dynamic cast to blocked LOF for now
147 RCP<const ThyraObjFactory<Scalar> > tof = rcp_dynamic_cast<const ThyraObjFactory<Scalar> >(lof_,true);
148
149 x_space_ = tof->getThyraDomainSpace();
150 f_space_ = tof->getThyraRangeSpace();
151
152 // now that the vector spaces are setup we can allocate the nominal values
153 // (i.e. initial conditions)
155
156 // allocate a response library so that responses can be added, it will be initialized in "setupModel"
158}
159
160template<typename Scalar>
163{
164 TEUCHOS_ASSERT(false);
165}
166
167// Public functions overridden from ModelEvaulator
168
169template<typename Scalar>
170Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
172{
173 return x_space_;
174}
175
176
177template<typename Scalar>
178Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
180{
181 return f_space_;
182}
183
184template<typename Scalar>
185Teuchos::RCP<const Teuchos::Array<std::string> >
187{
188 TEUCHOS_TEST_FOR_EXCEPTION(!(i>=0 && i<num_me_parameters_),std::runtime_error,
189 "panzer::ModelEvaluator::get_p_names: Requested parameter index out of range.");
190
191 if (i < Teuchos::as<int>(parameters_.size()))
192 return parameters_[i]->names;
193 else if (i < Teuchos::as<int>(parameters_.size()+tangent_space_.size())) {
194 Teuchos::RCP<Teuchos::Array<std::string> > names = rcp(new Teuchos::Array<std::string>);
195 int param_index = i-parameters_.size();
196 std::ostringstream ss;
197 ss << "TANGENT VECTOR: " << param_index;
198 names->push_back(ss.str());
199 return names;
200 }
201 else if (build_transient_support_ && i < Teuchos::as<int>(parameters_.size()+2*tangent_space_.size())) {
202 Teuchos::RCP<Teuchos::Array<std::string> > names = rcp(new Teuchos::Array<std::string>);
203 int param_index = i-parameters_.size()-tangent_space_.size();
204 std::ostringstream ss;
205 ss << "TIME DERIVATIVE TANGENT VECTOR: " << param_index;
206 names->push_back(ss.str());
207 return names;
208 }
209
210 return Teuchos::null;
211}
212
213template<typename Scalar>
214Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
216{
217 TEUCHOS_TEST_FOR_EXCEPTION(!(i>=0 && i<num_me_parameters_),std::runtime_error,
218 "panzer::ModelEvaluator::get_p_space: Requested parameter index out of range.");
219
220 if (i < Teuchos::as<int>(parameters_.size()))
221 return parameters_[i]->space;
222 else if (i < Teuchos::as<int>(parameters_.size()+tangent_space_.size()))
223 return tangent_space_[i-parameters_.size()];
224 else if (build_transient_support_ && i < Teuchos::as<int>(parameters_.size()+2*tangent_space_.size()))
225 return tangent_space_[i-parameters_.size()-tangent_space_.size()];
226
227 return Teuchos::null;
228}
229
230template<typename Scalar>
231Teuchos::ArrayView<const std::string>
233{
234 TEUCHOS_TEST_FOR_EXCEPTION(!(i>=0 && i<Teuchos::as<int>(responses_.size())),std::runtime_error,
235 "panzer::ModelEvaluator::get_g_names: Requested response index out of range.");
236
237 return Teuchos::ArrayView<const std::string>(&(responses_[i]->name),1);
238}
239
240template<typename Scalar>
241const std::string &
243{
244 TEUCHOS_ASSERT(i>=0 &&
245 static_cast<typename std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > >::size_type>(i)<responses_.size());
246
247 return responses_[i]->name;
248}
249
250template<typename Scalar>
251Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> >
253{
254 TEUCHOS_ASSERT(i>=0 &&
255 static_cast<typename std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > >::size_type>(i)<responses_.size());
256
257 return responses_[i]->space;
258}
259
260template<typename Scalar>
261Thyra::ModelEvaluatorBase::InArgs<Scalar>
263{
264 return getNominalValues();
265}
266
267template<typename Scalar>
268Thyra::ModelEvaluatorBase::InArgs<Scalar>
270{
271 using Teuchos::RCP;
272 using Teuchos::rcp_dynamic_cast;
273
274 if(require_in_args_refresh_) {
275 typedef Thyra::ModelEvaluatorBase MEB;
276
277 //
278 // Refresh nominal values, this is primarily adding
279 // new parameters.
280 //
281
282 MEB::InArgsSetup<Scalar> nomInArgs;
283 nomInArgs = nominalValues_;
284 nomInArgs.setSupports(nominalValues_);
285
286 // setup parameter support
287 nomInArgs.set_Np(num_me_parameters_);
288 for(std::size_t p=0;p<parameters_.size();p++) {
289 // setup nominal in arguments
290 nomInArgs.set_p(p,parameters_[p]->initial_value);
291
292 // We explicitly do not set nominal values for tangent parameters
293 // as these are parameters that should be hidden from client code
294 }
295
296 nominalValues_ = nomInArgs;
297 }
298
299 // refresh no longer required
300 require_in_args_refresh_ = false;
301
302 return nominalValues_;
303}
304
305template<typename Scalar>
306void
308{
309 typedef Thyra::ModelEvaluatorBase MEB;
310
311 //
312 // Setup nominal values
313 //
314
315 MEB::InArgsSetup<Scalar> nomInArgs;
316 nomInArgs.setModelEvalDescription(this->description());
317 nomInArgs.setSupports(MEB::IN_ARG_x);
318 Teuchos::RCP<Thyra::VectorBase<Scalar> > x_nom = Thyra::createMember(x_space_);
319 Thyra::assign(x_nom.ptr(),0.0);
320 nomInArgs.set_x(x_nom);
321 if(build_transient_support_) {
322 nomInArgs.setSupports(MEB::IN_ARG_x_dot,true);
323 nomInArgs.setSupports(MEB::IN_ARG_t,true);
324 nomInArgs.setSupports(MEB::IN_ARG_alpha,true);
325 nomInArgs.setSupports(MEB::IN_ARG_beta,true);
326 nomInArgs.setSupports(MEB::IN_ARG_step_size,true);
327 nomInArgs.setSupports(MEB::IN_ARG_stage_number,true);
328
329 Teuchos::RCP<Thyra::VectorBase<Scalar> > x_dot_nom = Thyra::createMember(x_space_);
330 Thyra::assign(x_dot_nom.ptr(),0.0);
331 nomInArgs.set_x_dot(x_dot_nom);
332 nomInArgs.set_t(t_init_);
333 nomInArgs.set_alpha(0.0); // these have no meaning initially!
334 nomInArgs.set_beta(0.0);
335 //TODO: is this needed?
336 nomInArgs.set_step_size(0.0);
337 nomInArgs.set_stage_number(1.0);
338 }
339
340 // setup parameter support -- for each scalar parameter we support the parameter itself and tangent vectors for x, xdot
341 nomInArgs.set_Np(num_me_parameters_);
342 std::size_t v_index = 0;
343 for(std::size_t p=0;p<parameters_.size();p++) {
344 nomInArgs.set_p(p,parameters_[p]->initial_value);
345 if (!parameters_[p]->is_distributed) {
346 Teuchos::RCP<Thyra::VectorBase<Scalar> > v_nom_x = Thyra::createMember(*tangent_space_[v_index]);
347 Thyra::assign(v_nom_x.ptr(),0.0);
348 nomInArgs.set_p(v_index+parameters_.size(),v_nom_x);
349 if (build_transient_support_) {
350 Teuchos::RCP<Thyra::VectorBase<Scalar> > v_nom_xdot = Thyra::createMember(*tangent_space_[v_index]);
351 Thyra::assign(v_nom_xdot.ptr(),0.0);
352 nomInArgs.set_p(v_index+parameters_.size()+tangent_space_.size(),v_nom_xdot);
353 }
354 ++v_index;
355 }
356 }
357
358 nominalValues_ = nomInArgs;
359}
360
361template <typename Scalar>
363buildVolumeFieldManagers(const bool value)
364{
365 build_volume_field_managers_ = value;
366}
367
368template <typename Scalar>
370buildBCFieldManagers(const bool value)
371{
372 build_bc_field_managers_ = value;
373}
374
375template <typename Scalar>
377setupModel(const Teuchos::RCP<panzer::WorksetContainer> & wc,
378 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
379 const std::vector<panzer::BC> & bcs,
380 const panzer::EquationSetFactory & eqset_factory,
381 const panzer::BCStrategyFactory& bc_factory,
384 const Teuchos::ParameterList& closure_models,
385 const Teuchos::ParameterList& user_data,
386 bool writeGraph,const std::string & graphPrefix,
387 const Teuchos::ParameterList& me_params)
388{
389 // First: build residual assembly engine
391 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::ModelEvaluator::setupModel()",setupModel);
392
393 {
394 // 1. build Field manager builder
396
397 Teuchos::RCP<panzer::FieldManagerBuilder> fmb;
398 {
399 PANZER_FUNC_TIME_MONITOR_DIFF("allocate FieldManagerBuilder",allocFMB);
400 fmb = Teuchos::rcp(new panzer::FieldManagerBuilder);
401 fmb->setActiveEvaluationTypes(active_evaluation_types_);
402 }
403 {
404 PANZER_FUNC_TIME_MONITOR_DIFF("fmb->setWorksetContainer()",setupWorksets);
405 fmb->setWorksetContainer(wc);
406 }
407 if (build_volume_field_managers_) {
408 PANZER_FUNC_TIME_MONITOR_DIFF("fmb->setupVolumeFieldManagers()",setupVolumeFieldManagers);
409 fmb->setupVolumeFieldManagers(physicsBlocks,volume_cm_factory,closure_models,*lof_,user_data);
410 }
411 if (build_bc_field_managers_) {
412 PANZER_FUNC_TIME_MONITOR_DIFF("fmb->setupBCFieldManagers()",setupBCFieldManagers);
413 fmb->setupBCFieldManagers(bcs,physicsBlocks,eqset_factory,bc_cm_factory,bc_factory,closure_models,*lof_,user_data);
414 }
415
416 // Print Phalanx DAGs
417 if (writeGraph){
418 if (build_volume_field_managers_)
419 fmb->writeVolumeGraphvizDependencyFiles(graphPrefix, physicsBlocks);
420 if (build_bc_field_managers_)
421 fmb->writeBCGraphvizDependencyFiles(graphPrefix+"BC_");
422 }
423
424 {
425 PANZER_FUNC_TIME_MONITOR_DIFF("AssemblyEngine_TemplateBuilder::buildObjects()",AETM_BuildObjects);
427 ae_tm_.buildObjects(builder);
428 }
429 }
430
431 // Second: build the responses
433
434 {
435 PANZER_FUNC_TIME_MONITOR_DIFF("build response library",buildResponses);
436
437 responseLibrary_->initialize(wc,lof_->getRangeGlobalIndexer(),lof_);
438
439 buildResponses(physicsBlocks,eqset_factory,volume_cm_factory,closure_models,user_data,writeGraph,graphPrefix+"Responses_");
440 buildDistroParamDfDp_RL(wc,physicsBlocks,bcs,eqset_factory,bc_factory,volume_cm_factory,closure_models,user_data,writeGraph,graphPrefix+"Response_DfDp_");
441 buildDistroParamDgDp_RL(wc,physicsBlocks,bcs,eqset_factory,bc_factory,volume_cm_factory,closure_models,user_data,writeGraph,graphPrefix+"Response_DgDp_");
442
443 do_fd_dfdp_ = false;
444 fd_perturb_size_ = 1.0e-7;
445 if (me_params.isParameter("FD Forward Sensitivities"))
446 do_fd_dfdp_ = me_params.get<bool>("FD Forward Sensitivities");
447 if (me_params.isParameter("FD Perturbation Size"))
448 fd_perturb_size_ = me_params.get<double>("FD Perturbation Size");
449 }
450}
451
452template <typename Scalar>
454setupAssemblyInArgs(const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
455 panzer::AssemblyEngineInArgs & ae_inargs) const
456{
457 using Teuchos::RCP;
458 using Teuchos::rcp;
459 using Teuchos::rcp_dynamic_cast;
460 using Teuchos::rcp_const_cast;
461 typedef Thyra::ModelEvaluatorBase MEB;
462
463 // if neccessary build a ghosted container
464 if(Teuchos::is_null(ghostedContainer_)) {
465 ghostedContainer_ = lof_->buildGhostedLinearObjContainer();
466 lof_->initializeGhostedContainer(panzer::LinearObjContainer::X |
469 panzer::LinearObjContainer::Mat, *ghostedContainer_);
470 }
471
472 bool is_transient = false;
473 if (inArgs.supports(MEB::IN_ARG_x_dot ))
474 is_transient = !Teuchos::is_null(inArgs.get_x_dot());
475
476 if(Teuchos::is_null(xContainer_))
477 xContainer_ = lof_->buildReadOnlyDomainContainer();
478 if(Teuchos::is_null(xdotContainer_) && is_transient)
479 xdotContainer_ = lof_->buildReadOnlyDomainContainer();
480
481 const RCP<const Thyra::VectorBase<Scalar> > x = inArgs.get_x();
482 RCP<const Thyra::VectorBase<Scalar> > x_dot; // possibly empty, but otherwise uses x_dot
483
484 // Make sure construction built in transient support
485 TEUCHOS_TEST_FOR_EXCEPTION(is_transient && !build_transient_support_, std::runtime_error,
486 "ModelEvaluator was not built with transient support enabled!");
487
488 ae_inargs.container_ = lof_->buildLinearObjContainer(); // we use a new global container
489 ae_inargs.ghostedContainer_ = ghostedContainer_; // we can reuse the ghosted container
490 ae_inargs.alpha = 0.0;
491 ae_inargs.beta = 1.0;
492 ae_inargs.evaluate_transient_terms = false;
493 if (build_transient_support_) {
494 x_dot = inArgs.get_x_dot();
495 ae_inargs.alpha = inArgs.get_alpha();
496 ae_inargs.beta = inArgs.get_beta();
497 ae_inargs.time = inArgs.get_t();
498
499 ae_inargs.step_size= inArgs.get_step_size();
500 ae_inargs.stage_number = inArgs.get_stage_number();
501 ae_inargs.evaluate_transient_terms = true;
502 }
503
504 // this member is handled in the individual functions
505 ae_inargs.apply_dirichlet_beta = false;
506
507 // Set input parameters
508 int num_param_vecs = parameters_.size();
509 for (int i=0; i<num_param_vecs; i++) {
510
511 RCP<const Thyra::VectorBase<Scalar> > paramVec = inArgs.get_p(i);
512 if ( paramVec!=Teuchos::null && !parameters_[i]->is_distributed) {
513 // non distributed parameters
514
515 Teuchos::ArrayRCP<const Scalar> p_data;
516 rcp_dynamic_cast<const Thyra::SpmdVectorBase<Scalar> >(paramVec,true)->getLocalData(Teuchos::ptrFromRef(p_data));
517
518 for (unsigned int j=0; j < parameters_[i]->scalar_value.size(); j++) {
519 parameters_[i]->scalar_value[j].baseValue = p_data[j];
520 parameters_[i]->scalar_value[j].family->setRealValueForAllTypes(parameters_[i]->scalar_value[j].baseValue);
521 }
522 }
523 else if ( paramVec!=Teuchos::null && parameters_[i]->is_distributed) {
524 // distributed parameters
525
526 std::string key = (*parameters_[i]->names)[0];
527 RCP<GlobalEvaluationData> ged = distrParamGlobalEvaluationData_.getDataObject(key);
528
529 TEUCHOS_ASSERT(ged!=Teuchos::null);
530
531 // cast to a LOCPair throwing an exception if the cast doesn't work.
532 RCP<LOCPair_GlobalEvaluationData> loc_pair_ged = rcp_dynamic_cast<LOCPair_GlobalEvaluationData>(ged);
533 RCP<ReadOnlyVector_GlobalEvaluationData> ro_ged = rcp_dynamic_cast<ReadOnlyVector_GlobalEvaluationData>(ged);
534 if(loc_pair_ged!=Teuchos::null) {
535 // cast to a ThyraObjContainer throwing an exception if the cast doesn't work.
536 RCP<ThyraObjContainer<Scalar> > th_ged = rcp_dynamic_cast<ThyraObjContainer<Scalar> >(loc_pair_ged->getGlobalLOC(),true);
537 th_ged->set_x_th(Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(paramVec));
538 }
539 else {
540 TEUCHOS_ASSERT(ro_ged!=Teuchos::null);
541 ro_ged->setOwnedVector(paramVec);
542 }
543 }
544 }
545
546 ae_inargs.addGlobalEvaluationData(distrParamGlobalEvaluationData_);
547
548 // here we are building a container, this operation is fast, simply allocating a struct
549 const RCP<panzer::ThyraObjContainer<Scalar> > thGlobalContainer =
550 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.container_);
551
552 TEUCHOS_ASSERT(!Teuchos::is_null(thGlobalContainer));
553
554 // Ghosted container objects are zeroed out below only if needed for
555 // a particular calculation. This makes it more efficient than
556 // zeroing out all objects in the container here.
557 // const RCP<panzer::ThyraObjContainer<Scalar> > thGhostedContainer =
558 // Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.ghostedContainer_);
559
560 // Set the solution vector (currently all targets require solution).
561 // In the future we may move these into the individual cases below.
562 // A very subtle (and fragile) point: A non-null pointer in global
563 // container triggers export operations during fill. Also, the
564 // introduction of the container is forcing us to cast away const on
565 // arguments that should be const. Another reason to redesign
566 // LinearObjContainer layers.
567 thGlobalContainer->set_x_th(Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(x));
568 xContainer_->setOwnedVector(x);
569 ae_inargs.addGlobalEvaluationData("Solution Gather Container - X",xContainer_);
570
571 if (is_transient) {
572 thGlobalContainer->set_dxdt_th(Teuchos::rcp_const_cast<Thyra::VectorBase<Scalar> >(x_dot));
573 xdotContainer_->setOwnedVector(x_dot);
574 ae_inargs.addGlobalEvaluationData("Solution Gather Container - Xdot",xdotContainer_);
575 }
576
577 // Add tangent vectors for x and xdot to GlobalEvaluationData, one for each
578 // scalar parameter vector and parameter within that vector.
579 // Note: The keys for the global evaluation data containers for the tangent
580 // vectors are constructed in EquationSet_AddFieldDefaultImpl::
581 // buildAndRegisterGatherAndOrientationEvaluators().
582 int vIndex(0);
583 for (int i(0); i < num_param_vecs; ++i)
584 {
585 using std::string;
587 using Thyra::VectorBase;
589 if (not parameters_[i]->is_distributed)
590 {
591 auto dxdp = rcp_const_cast<VectorBase<Scalar>>
592 (inArgs.get_p(vIndex + num_param_vecs));
593 if (not dxdp.is_null())
594 {
595 // We need to cast away const because the object container requires
596 // non-const vectors.
597 auto dxdpBlock = rcp_dynamic_cast<ProductVectorBase<Scalar>>(dxdp);
598 int numParams(parameters_[i]->scalar_value.size());
599 for (int j(0); j < numParams; ++j)
600 {
601 RCP<ROVGED> dxdpContainer = lof_->buildReadOnlyDomainContainer();
602 dxdpContainer->setOwnedVector(dxdpBlock->getNonconstVectorBlock(j));
603 string name("X TANGENT GATHER CONTAINER: " +
604 (*parameters_[i]->names)[j]);
605 ae_inargs.addGlobalEvaluationData(name, dxdpContainer);
606 } // end loop over the parameters
607 } // end if (not dxdp.is_null())
608 if (build_transient_support_)
609 {
610 // We need to cast away const because the object container requires
611 // non-const vectors.
612 auto dxdotdp = rcp_const_cast<VectorBase<Scalar>>
613 (inArgs.get_p(vIndex + num_param_vecs + tangent_space_.size()));
614 if (not dxdotdp.is_null())
615 {
616 auto dxdotdpBlock =
617 rcp_dynamic_cast<ProductVectorBase<Scalar>>(dxdotdp);
618 int numParams(parameters_[i]->scalar_value.size());
619 for (int j(0); j < numParams; ++j)
620 {
621 RCP<ROVGED> dxdotdpContainer = lof_->buildReadOnlyDomainContainer();
622 dxdotdpContainer->setOwnedVector(
623 dxdotdpBlock->getNonconstVectorBlock(j));
624 string name("DXDT TANGENT GATHER CONTAINER: " +
625 (*parameters_[i]->names)[j]);
626 ae_inargs.addGlobalEvaluationData(name, dxdotdpContainer);
627 } // end loop over the parameters
628 } // end if (not dxdotdp.is_null())
629 } // end if (build_transient_support_)
630 ++vIndex;
631 } // end if (not parameters_[i]->is_distributed)
632 } // end loop over the parameter vectors
633} // end of setupAssemblyInArgs()
634
635// Private functions overridden from ModelEvaulatorDefaultBase
636
637
638template <typename Scalar>
639Thyra::ModelEvaluatorBase::OutArgs<Scalar>
641{
642 typedef Thyra::ModelEvaluatorBase MEB;
643
644 if(require_out_args_refresh_) {
645 MEB::OutArgsSetup<Scalar> outArgs;
646 outArgs.setModelEvalDescription(this->description());
647 outArgs.set_Np_Ng(num_me_parameters_, responses_.size());
648 outArgs.setSupports(MEB::OUT_ARG_f);
649 outArgs.setSupports(MEB::OUT_ARG_W_op);
650
651 // add in dg/dx (if appropriate)
652 for(std::size_t i=0;i<responses_.size();i++) {
653 typedef panzer::Traits::Jacobian RespEvalT;
654
655 // check dg/dx and add it in if appropriate
656 Teuchos::RCP<panzer::ResponseBase> respJacBase
657 = responseLibrary_->getResponse<RespEvalT>(responses_[i]->name);
658 if(respJacBase!=Teuchos::null) {
659 // cast is guranteed to succeed because of check in addResponse
660 Teuchos::RCP<panzer::ResponseMESupportBase<RespEvalT> > resp
661 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<RespEvalT> >(respJacBase);
662
663 // class must supppot a derivative
664 if(resp->supportsDerivative()) {
665 outArgs.setSupports(MEB::OUT_ARG_DgDx,i,MEB::DerivativeSupport(MEB::DERIV_MV_GRADIENT_FORM));
666
667
668 for(std::size_t p=0;p<parameters_.size();p++) {
669 if(parameters_[p]->is_distributed && parameters_[p]->global_indexer!=Teuchos::null)
670 outArgs.setSupports(MEB::OUT_ARG_DgDp,i,p,MEB::DerivativeSupport(MEB::DERIV_MV_GRADIENT_FORM));
671 if(!parameters_[p]->is_distributed)
672 outArgs.setSupports(MEB::OUT_ARG_DgDp,i,p,MEB::DerivativeSupport(MEB::DERIV_MV_JACOBIAN_FORM));
673 }
674 }
675 }
676 }
677
678 // setup parameter support
679 for(std::size_t p=0;p<parameters_.size();p++) {
680
681 if(!parameters_[p]->is_distributed)
682 outArgs.setSupports(MEB::OUT_ARG_DfDp,p,MEB::DerivativeSupport(MEB::DERIV_MV_BY_COL));
683 else if(parameters_[p]->is_distributed && parameters_[p]->global_indexer!=Teuchos::null)
684 outArgs.setSupports(MEB::OUT_ARG_DfDp,p,MEB::DerivativeSupport(MEB::DERIV_LINEAR_OP));
685 }
686
687 prototypeOutArgs_ = outArgs;
688 }
689
690 // we don't need to build it anymore
691 require_out_args_refresh_ = false;
692
693 return prototypeOutArgs_;
694}
695
696template <typename Scalar>
697Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
699create_W_op() const
700{
701 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::create_W_op");
702 Teuchos::RCP<const ThyraObjFactory<Scalar> > tof
703 = Teuchos::rcp_dynamic_cast<const ThyraObjFactory<Scalar> >(lof_,true);
704
705 return tof->getThyraMatrix();
706}
707
708template <typename Scalar>
709Teuchos::RCP<const Thyra::LinearOpWithSolveFactoryBase<Scalar> >
711get_W_factory() const
712{
713 return solverFactory_;
714}
715
716template <typename Scalar>
717Teuchos::RCP<Thyra::LinearOpBase<Scalar> >
719create_DfDp_op(int p) const
720{
721 using Teuchos::RCP;
722 using Teuchos::rcp_dynamic_cast;
723
724 typedef Thyra::ModelEvaluatorBase MEB;
725
726 // The code below uses prototypeOutArgs_, so we need to make sure it is
727 // initialized before using it. This happens through createOutArgs(),
728 // however it may be allowable to call create_DfDp_op() before
729 // createOutArgs() is called. Thus we do this here if prototypeOutArgs_
730 // needs to be initialized.
731 //
732 // Previously this was handled in the TEUCHOS_ASSERT below through the call
733 // to Np(), however it isn't a good idea to include code in asserts that is
734 // required for proper execution (the asserts may be removed in an optimized
735 // build, for example).
736 if(require_out_args_refresh_) {
737 this->createOutArgs();
738 }
739
740 TEUCHOS_ASSERT(0<=p && p<Teuchos::as<int>(parameters_.size()));
741
742 // assert that DfDp is supported
743 const ParameterObject & po = *parameters_[p];
744
745 if(po.is_distributed && po.global_indexer!=Teuchos::null) {
746 TEUCHOS_ASSERT(prototypeOutArgs_.supports(MEB::OUT_ARG_DfDp,p).supports(MEB::DERIV_LINEAR_OP));
747
748 // for a distributed parameter, figure it out from the
749 // response library
750 RCP<Response_Residual<Traits::Jacobian> > response_jacobian
751 = rcp_dynamic_cast<Response_Residual<Traits::Jacobian> >(po.dfdp_rl->template getResponse<Traits::Jacobian>("RESIDUAL"));
752
753 return response_jacobian->allocateJacobian();
754 }
755 else if(!po.is_distributed) {
756 TEUCHOS_ASSERT(prototypeOutArgs_.supports(MEB::OUT_ARG_DfDp,p).supports(MEB::DERIV_MV_BY_COL));
757
758 // this is a scalar parameter (its easy to create!)
759 return Thyra::createMember(*get_f_space());
760 }
761
762 // shourld never get here
763 TEUCHOS_ASSERT(false);
764
765 return Teuchos::null;
766}
767
768template <typename Scalar>
770addParameter(const std::string & name,const Scalar & initialValue)
771{
772 Teuchos::Array<std::string> tmp_names;
773 tmp_names.push_back(name);
774
775 Teuchos::Array<Scalar> tmp_values;
776 tmp_values.push_back(initialValue);
777
778 return addParameter(tmp_names,tmp_values);
779}
780
781template <typename Scalar>
783addParameter(const Teuchos::Array<std::string> & names,
784 const Teuchos::Array<Scalar> & initialValues)
785{
786 using Teuchos::RCP;
787 using Teuchos::rcp;
788 using Teuchos::rcp_dynamic_cast;
789 using Teuchos::ptrFromRef;
790
791 TEUCHOS_ASSERT(names.size()==initialValues.size());
792
793 int parameter_index = parameters_.size();
794
795 // Create parameter object
796 RCP<ParameterObject> param = createScalarParameter(names,initialValues);
797 parameters_.push_back(param);
798
799 // Create vector space for parameter tangent vector
800 RCP< Thyra::VectorSpaceBase<double> > tan_space =
801 Thyra::multiVectorProductVectorSpace(x_space_, param->names->size());
802 tangent_space_.push_back(tan_space);
803
804 // The number of model evaluator parameters is the number of model parameters (parameters_.size()) plus a tangent
805 // vector for each scalar parameter (tangent_space_.size()) plus a tangent vector for xdot for each scalar parameter.
806 num_me_parameters_ += 2;
807 if (build_transient_support_)
808 ++num_me_parameters_;
809
810 require_in_args_refresh_ = true;
811 require_out_args_refresh_ = true;
812 this->resetDefaultBase();
813
814 return parameter_index;
815}
816
817template <typename Scalar>
819addDistributedParameter(const std::string & key,
820 const Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > & vs,
821 const Teuchos::RCP<GlobalEvaluationData> & ged,
822 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & initial,
823 const Teuchos::RCP<const GlobalIndexer> & ugi)
824{
825 distrParamGlobalEvaluationData_.addDataObject(key,ged);
826
827 int parameter_index = parameters_.size();
828 parameters_.push_back(createDistributedParameter(key,vs,initial,ugi));
829 ++num_me_parameters_;
830
831 require_in_args_refresh_ = true;
832 require_out_args_refresh_ = true;
833 this->resetDefaultBase();
834
835 return parameter_index;
836}
837
838template <typename Scalar>
840addNonParameterGlobalEvaluationData(const std::string & key,
841 const Teuchos::RCP<GlobalEvaluationData> & ged)
842{
843 nonParamGlobalEvaluationData_.addDataObject(key,ged);
844}
845
846template <typename Scalar>
848addFlexibleResponse(const std::string & responseName,
849 const std::vector<WorksetDescriptor> & wkst_desc,
850 const Teuchos::RCP<ResponseMESupportBuilderBase> & builder)
851{
852 // add a basic response, use x global indexer to define it
853 builder->setDerivativeInformation(lof_);
854
855 int respIndex = addResponse(responseName,wkst_desc,*builder);
856
857 // set the builder for this response
858 responses_[respIndex]->builder = builder;
859
860 return respIndex;
861}
862
863
864template <typename Scalar>
866applyDirichletBCs(const Teuchos::RCP<Thyra::VectorBase<Scalar> > & x,
867 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & f) const
868{
869 using Teuchos::RCP;
870 using Teuchos::ArrayRCP;
871 using Teuchos::Array;
872 using Teuchos::tuple;
873 using Teuchos::rcp_dynamic_cast;
874
875 // if neccessary build a ghosted container
876 if(Teuchos::is_null(ghostedContainer_)) {
877 ghostedContainer_ = lof_->buildGhostedLinearObjContainer();
878 lof_->initializeGhostedContainer(panzer::LinearObjContainer::X |
879 panzer::LinearObjContainer::F,*ghostedContainer_);
880 }
881
883 ae_inargs.container_ = lof_->buildLinearObjContainer(); // we use a new global container
884 ae_inargs.ghostedContainer_ = ghostedContainer_; // we can reuse the ghosted container
885 ae_inargs.alpha = 0.0;
886 ae_inargs.beta = 1.0;
887 //TODO: is this really needed?
888 ae_inargs.step_size = 0.0;
889 ae_inargs.stage_number = 1.0;
890 ae_inargs.evaluate_transient_terms = false;
891 ae_inargs.addGlobalEvaluationData(nonParamGlobalEvaluationData_);
892 ae_inargs.addGlobalEvaluationData(distrParamGlobalEvaluationData_);
893
894 // this is the tempory target
895 lof_->initializeContainer(panzer::LinearObjContainer::F,*ae_inargs.container_);
896
897 // here we are building a container, this operation is fast, simply allocating a struct
898 const RCP<panzer::ThyraObjContainer<Scalar> > thGlobalContainer =
899 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.container_);
900
901 TEUCHOS_ASSERT(!Teuchos::is_null(thGlobalContainer));
902
903 // Ghosted container objects are zeroed out below only if needed for
904 // a particular calculation. This makes it more efficient than
905 // zeroing out all objects in the container here.
906 const RCP<panzer::ThyraObjContainer<Scalar> > thGhostedContainer =
907 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.ghostedContainer_);
908 Thyra::assign(thGhostedContainer->get_f_th().ptr(),0.0);
909
910 // Set the solution vector (currently all targets require solution).
911 // In the future we may move these into the individual cases below.
912 // A very subtle (and fragile) point: A non-null pointer in global
913 // container triggers export operations during fill. Also, the
914 // introduction of the container is forcing us to cast away const on
915 // arguments that should be const. Another reason to redesign
916 // LinearObjContainer layers.
917 thGlobalContainer->set_x_th(x);
918
919 // evaluate dirichlet boundary conditions
920 RCP<panzer::LinearObjContainer> counter
921 = ae_tm_.template getAsObject<panzer::Traits::Residual>()->evaluateOnlyDirichletBCs(ae_inargs);
922
923 // allocate the result container
924 RCP<panzer::LinearObjContainer> result = lof_->buildLinearObjContainer(); // we use a new global container
925
926 // stuff the evaluate boundary conditions into the f spot of the counter ... the x is already filled
927 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(counter)->set_f_th(
928 thGlobalContainer->get_f_th());
929
930 // stuff the vector that needs applied dirichlet conditions in the the f spot of the result LOC
931 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(result)->set_f_th(f);
932
933 // use the linear object factory to apply the result
934 lof_->applyDirichletBCs(*counter,*result);
935}
936
937template <typename Scalar>
939evalModel_D2gDx2(int respIndex,
940 const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
941 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_x,
942 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & D2gDx2) const
943{
944#ifdef Panzer_BUILD_HESSIAN_SUPPORT
945
946 // set model parameters from supplied inArgs
947 setParameters(inArgs);
948
949 {
950 std::string responseName = responses_[respIndex]->name;
951 Teuchos::RCP<panzer::ResponseMESupportBase<panzer::Traits::Hessian> > resp
952 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Hessian> >(
953 responseLibrary_->getResponse<panzer::Traits::Hessian>(responseName));
954 resp->setDerivative(D2gDx2);
955 }
956
957 // setup all the assembly in arguments (this is parameters and
958 // x/x_dot). At this point with the exception of the one time dirichlet
959 // beta that is all thats neccessary.
961 setupAssemblyInArgs(inArgs,ae_inargs);
962
963 ae_inargs.beta = 1.0;
964
965 auto deltaXContainer = lof_->buildReadOnlyDomainContainer();
966 deltaXContainer->setOwnedVector(delta_x);
967 ae_inargs.addGlobalEvaluationData("DELTA_Solution Gather Container",deltaXContainer);
968
969 // evaluate responses
970 responseLibrary_->addResponsesToInArgs<panzer::Traits::Hessian>(ae_inargs);
971 responseLibrary_->evaluate<panzer::Traits::Hessian>(ae_inargs);
972
973 // reset parameters back to nominal values
974 resetParameters();
975#else
976 (void)respIndex;
977 (void)inArgs;
978 (void)delta_x;
979 (void)D2gDx2;
980 TEUCHOS_ASSERT(false);
981#endif
982}
983
984template <typename Scalar>
986evalModel_D2gDxDp(int respIndex,
987 int pIndex,
988 const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
989 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_p,
990 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & D2gDxDp) const
991{
992#ifdef Panzer_BUILD_HESSIAN_SUPPORT
993
994 // set model parameters from supplied inArgs
995 setParameters(inArgs);
996
997 {
998 std::string responseName = responses_[respIndex]->name;
999 Teuchos::RCP<panzer::ResponseMESupportBase<panzer::Traits::Hessian> > resp
1000 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Hessian> >(
1001 responseLibrary_->getResponse<panzer::Traits::Hessian>(responseName));
1002 resp->setDerivative(D2gDxDp);
1003 }
1004
1005 // setup all the assembly in arguments (this is parameters and
1006 // x/x_dot). At this point with the exception of the one time dirichlet
1007 // beta that is all thats neccessary.
1009 setupAssemblyInArgs(inArgs,ae_inargs);
1010
1011 ae_inargs.beta = 1.0;
1012 ae_inargs.second_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1013
1014 auto deltaPContainer = parameters_[pIndex]->dfdp_rl->getLinearObjFactory()->buildReadOnlyDomainContainer();
1015 deltaPContainer->setOwnedVector(delta_p);
1016 ae_inargs.addGlobalEvaluationData("DELTA_"+(*parameters_[pIndex]->names)[0],deltaPContainer);
1017
1018 // evaluate responses
1019 responseLibrary_->addResponsesToInArgs<panzer::Traits::Hessian>(ae_inargs);
1020 responseLibrary_->evaluate<panzer::Traits::Hessian>(ae_inargs);
1021
1022 // reset parameters back to nominal values
1023 resetParameters();
1024#else
1025 (void)respIndex;
1026 (void)pIndex;
1027 (void)inArgs;
1028 (void)delta_p;
1029 (void)D2gDxDp;
1030 TEUCHOS_ASSERT(false);
1031#endif
1032}
1033
1034template <typename Scalar>
1036evalModel_D2gDp2(int respIndex,
1037 int pIndex,
1038 const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
1039 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_p,
1040 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & D2gDp2) const
1041{
1042#ifdef Panzer_BUILD_HESSIAN_SUPPORT
1043
1044 // set model parameters from supplied inArgs
1045 setParameters(inArgs);
1046
1047 ResponseLibrary<Traits> & rLibrary = *parameters_[pIndex]->dgdp_rl;
1048
1049 {
1050 std::string responseName = responses_[respIndex]->name;
1051 Teuchos::RCP<panzer::ResponseMESupportBase<panzer::Traits::Hessian> > resp
1052 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Hessian> >(
1053 rLibrary.getResponse<panzer::Traits::Hessian>(responseName));
1054 resp->setDerivative(D2gDp2);
1055 }
1056
1057 // setup all the assembly in arguments (this is parameters and
1058 // x/x_dot). At this point with the exception of the one time dirichlet
1059 // beta that is all thats neccessary.
1061 setupAssemblyInArgs(inArgs,ae_inargs);
1062
1063 ae_inargs.gather_seeds.push_back(1.0); // this assumes that gather point is always the zero index of
1064 // gather seeds
1065 ae_inargs.first_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1066 ae_inargs.second_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1067
1068 auto deltaPContainer = parameters_[pIndex]->dfdp_rl->getLinearObjFactory()->buildReadOnlyDomainContainer();
1069 deltaPContainer->setOwnedVector(delta_p);
1070 ae_inargs.addGlobalEvaluationData("DELTA_"+(*parameters_[pIndex]->names)[0],deltaPContainer);
1071
1072 // evaluate responses
1073 rLibrary.addResponsesToInArgs<panzer::Traits::Hessian>(ae_inargs);
1074 rLibrary.evaluate<panzer::Traits::Hessian>(ae_inargs);
1075
1076 // reset parameters back to nominal values
1077 resetParameters();
1078#else
1079 (void)respIndex;
1080 (void)pIndex;
1081 (void)inArgs;
1082 (void)delta_p;
1083 (void)D2gDp2;
1084 TEUCHOS_ASSERT(false);
1085#endif
1086}
1087
1088template <typename Scalar>
1090evalModel_D2gDpDx(int respIndex,
1091 int pIndex,
1092 const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
1093 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_x,
1094 const Teuchos::RCP<Thyra::VectorBase<Scalar> > & D2gDpDx) const
1095{
1096#ifdef Panzer_BUILD_HESSIAN_SUPPORT
1097
1098 // set model parameters from supplied inArgs
1099 setParameters(inArgs);
1100
1101 ResponseLibrary<Traits> & rLibrary = *parameters_[pIndex]->dgdp_rl;
1102
1103 {
1104 std::string responseName = responses_[respIndex]->name;
1105 Teuchos::RCP<panzer::ResponseMESupportBase<panzer::Traits::Hessian> > resp
1106 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Hessian> >(
1107 rLibrary.getResponse<panzer::Traits::Hessian>(responseName));
1108 resp->setDerivative(D2gDpDx);
1109 }
1110
1111 // setup all the assembly in arguments (this is parameters and
1112 // x/x_dot). At this point with the exception of the one time dirichlet
1113 // beta that is all thats neccessary.
1115 setupAssemblyInArgs(inArgs,ae_inargs);
1116
1117 ae_inargs.gather_seeds.push_back(1.0); // this assumes that gather point is always the zero index of
1118 // gather seeds
1119 ae_inargs.first_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1120 ae_inargs.second_sensitivities_name = "";
1121
1122 auto deltaXContainer = lof_->buildReadOnlyDomainContainer();
1123 deltaXContainer->setOwnedVector(delta_x);
1124 ae_inargs.addGlobalEvaluationData("DELTA_Solution Gather Container",deltaXContainer);
1125
1126 // evaluate responses
1127 rLibrary.addResponsesToInArgs<panzer::Traits::Hessian>(ae_inargs);
1128 rLibrary.evaluate<panzer::Traits::Hessian>(ae_inargs);
1129
1130 // reset parameters back to nominal values
1131 resetParameters();
1132#else
1133 (void)respIndex;
1134 (void)pIndex;
1135 (void)inArgs;
1136 (void)delta_x;
1137 (void)D2gDpDx;
1138 TEUCHOS_ASSERT(false);
1139#endif
1140}
1141
1142template <typename Scalar>
1144evalModel_D2fDx2(const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
1145 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_x,
1146 const Teuchos::RCP<Thyra::LinearOpBase<Scalar> > & D2fDx2) const
1147{
1148#ifdef Panzer_BUILD_HESSIAN_SUPPORT
1149
1150 using Teuchos::RCP;
1151 using Teuchos::ArrayRCP;
1152 using Teuchos::Array;
1153 using Teuchos::tuple;
1154 using Teuchos::rcp_dynamic_cast;
1155
1156 typedef Thyra::ModelEvaluatorBase MEB;
1157
1158 // Transient or steady-state evaluation is determined by the x_dot
1159 // vector. If this RCP is null, then we are doing a steady-state
1160 // fill.
1161 bool is_transient = false;
1162 if (inArgs.supports(MEB::IN_ARG_x_dot ))
1163 is_transient = !Teuchos::is_null(inArgs.get_x_dot());
1164
1165 // Make sure construction built in transient support
1166 TEUCHOS_TEST_FOR_EXCEPTION(is_transient && !build_transient_support_, std::runtime_error,
1167 "ModelEvaluator was not built with transient support enabled!");
1168
1169 //
1170 // Get the output arguments
1171 //
1172 const RCP<Thyra::LinearOpBase<Scalar> > W_out = D2fDx2;
1173
1174 // setup all the assembly in arguments (this is parameters and
1175 // x/x_dot). At this point with the exception of the one time dirichlet
1176 // beta that is all thats neccessary.
1178 setupAssemblyInArgs(inArgs,ae_inargs);
1179
1180 auto deltaXContainer = lof_->buildReadOnlyDomainContainer();
1181 deltaXContainer->setOwnedVector(delta_x);
1182 ae_inargs.addGlobalEvaluationData("DELTA_Solution Gather Container",deltaXContainer);
1183
1184 // set model parameters from supplied inArgs
1185 setParameters(inArgs);
1186
1187 // handle application of the one time dirichlet beta in the
1188 // assembly engine. Note that this has to be set explicitly
1189 // each time because this badly breaks encapsulation. Essentially
1190 // we must work around the model evaluator abstraction!
1191 if(oneTimeDirichletBeta_on_) {
1192 ae_inargs.dirichlet_beta = oneTimeDirichletBeta_;
1193 ae_inargs.apply_dirichlet_beta = true;
1194
1195 oneTimeDirichletBeta_on_ = false;
1196 }
1197
1198 // here we are building a container, this operation is fast, simply allocating a struct
1199 const RCP<panzer::ThyraObjContainer<Scalar> > thGlobalContainer =
1200 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.container_);
1201 const RCP<panzer::ThyraObjContainer<Scalar> > thGhostedContainer =
1202 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.ghostedContainer_);
1203
1204 {
1205 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModel(D2fDx2)");
1206
1207 // this dummy nonsense is needed only for scattering dirichlet conditions
1208 RCP<Thyra::VectorBase<Scalar> > dummy_f = Thyra::createMember(f_space_);
1209 thGlobalContainer->set_f_th(dummy_f);
1210 thGlobalContainer->set_A_th(W_out);
1211
1212 // Zero values in ghosted container objects
1213 thGhostedContainer->initializeMatrix(0.0);
1214
1215 ae_tm_.template getAsObject<panzer::Traits::Hessian>()->evaluate(ae_inargs);
1216 }
1217
1218 // HACK: set A to null before calling responses to avoid touching the
1219 // the Jacobian after it has been properly assembled. Should be fixed
1220 // by using a modified version of ae_inargs instead.
1221 thGlobalContainer->set_A_th(Teuchos::null);
1222
1223 // TODO: Clearing all references prevented a seg-fault with Rythmos,
1224 // which is no longer used. Check if it's still needed.
1225 thGlobalContainer->set_x_th(Teuchos::null);
1226 thGlobalContainer->set_dxdt_th(Teuchos::null);
1227 thGlobalContainer->set_f_th(Teuchos::null);
1228 thGlobalContainer->set_A_th(Teuchos::null);
1229
1230 // reset parameters back to nominal values
1231 resetParameters();
1232#else
1233 (void)inArgs;
1234 (void)delta_x;
1235 (void)D2fDx2;
1236 TEUCHOS_ASSERT(false);
1237#endif
1238}
1239
1240template <typename Scalar>
1242evalModel_D2fDxDp(int pIndex,
1243 const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
1244 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_p,
1245 const Teuchos::RCP<Thyra::LinearOpBase<Scalar> > & D2fDxDp) const
1246{
1247#ifdef Panzer_BUILD_HESSIAN_SUPPORT
1248
1249 using Teuchos::RCP;
1250 using Teuchos::ArrayRCP;
1251 using Teuchos::Array;
1252 using Teuchos::tuple;
1253 using Teuchos::rcp_dynamic_cast;
1254
1255 typedef Thyra::ModelEvaluatorBase MEB;
1256
1257 // Transient or steady-state evaluation is determined by the x_dot
1258 // vector. If this RCP is null, then we are doing a steady-state
1259 // fill.
1260 bool is_transient = false;
1261 if (inArgs.supports(MEB::IN_ARG_x_dot ))
1262 is_transient = !Teuchos::is_null(inArgs.get_x_dot());
1263
1264 // Make sure construction built in transient support
1265 TEUCHOS_TEST_FOR_EXCEPTION(is_transient && !build_transient_support_, std::runtime_error,
1266 "ModelEvaluator was not built with transient support enabled!");
1267
1268 //
1269 // Get the output arguments
1270 //
1271 const RCP<Thyra::LinearOpBase<Scalar> > W_out = D2fDxDp;
1272
1273 // setup all the assembly in arguments (this is parameters and
1274 // x/x_dot). At this point with the exception of the one time dirichlet
1275 // beta that is all thats neccessary.
1277 setupAssemblyInArgs(inArgs,ae_inargs);
1278
1279 ae_inargs.second_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1280
1281 auto deltaPContainer = parameters_[pIndex]->dfdp_rl->getLinearObjFactory()->buildReadOnlyDomainContainer();
1282 deltaPContainer->setOwnedVector(delta_p);
1283 ae_inargs.addGlobalEvaluationData("DELTA_"+(*parameters_[pIndex]->names)[0],deltaPContainer);
1284
1285 // set model parameters from supplied inArgs
1286 setParameters(inArgs);
1287
1288 // handle application of the one time dirichlet beta in the
1289 // assembly engine. Note that this has to be set explicitly
1290 // each time because this badly breaks encapsulation. Essentially
1291 // we must work around the model evaluator abstraction!
1292 if(oneTimeDirichletBeta_on_) {
1293 ae_inargs.dirichlet_beta = oneTimeDirichletBeta_;
1294 ae_inargs.apply_dirichlet_beta = true;
1295
1296 oneTimeDirichletBeta_on_ = false;
1297 }
1298
1299 // here we are building a container, this operation is fast, simply allocating a struct
1300 const RCP<panzer::ThyraObjContainer<Scalar> > thGlobalContainer =
1301 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.container_);
1302 const RCP<panzer::ThyraObjContainer<Scalar> > thGhostedContainer =
1303 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.ghostedContainer_);
1304
1305 {
1306 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModel(D2fDxDp)");
1307
1308 // this dummy nonsense is needed only for scattering dirichlet conditions
1309 RCP<Thyra::VectorBase<Scalar> > dummy_f = Thyra::createMember(f_space_);
1310 thGlobalContainer->set_f_th(dummy_f);
1311 thGlobalContainer->set_A_th(W_out);
1312
1313 // Zero values in ghosted container objects
1314 thGhostedContainer->initializeMatrix(0.0);
1315
1316 ae_tm_.template getAsObject<panzer::Traits::Hessian>()->evaluate(ae_inargs);
1317 }
1318
1319 // HACK: set A to null before calling responses to avoid touching the
1320 // the Jacobian after it has been properly assembled. Should be fixed
1321 // by using a modified version of ae_inargs instead.
1322 thGlobalContainer->set_A_th(Teuchos::null);
1323
1324 // TODO: Clearing all references prevented a seg-fault with Rythmos,
1325 // which is no longer used. Check if it's still needed.
1326 thGlobalContainer->set_x_th(Teuchos::null);
1327 thGlobalContainer->set_dxdt_th(Teuchos::null);
1328 thGlobalContainer->set_f_th(Teuchos::null);
1329 thGlobalContainer->set_A_th(Teuchos::null);
1330
1331 // reset parameters back to nominal values
1332 resetParameters();
1333#else
1334 (void)pIndex;
1335 (void)inArgs;
1336 (void)delta_p;
1337 (void)D2fDxDp;
1338 TEUCHOS_ASSERT(false);
1339#endif
1340}
1341
1342template <typename Scalar>
1344evalModel_D2fDpDx(int pIndex,
1345 const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
1346 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_x,
1347 const Teuchos::RCP<Thyra::LinearOpBase<Scalar> > & D2fDpDx) const
1348{
1349#ifdef Panzer_BUILD_HESSIAN_SUPPORT
1350 using Teuchos::RCP;
1351 using Teuchos::rcp_dynamic_cast;
1352 using Teuchos::null;
1353
1354 // parameter is not distributed
1355 TEUCHOS_ASSERT(parameters_[pIndex]->is_distributed);
1356
1357 // parameter is distributed but has no global indexer.
1358 // thus the user doesn't want sensitivities!
1359 TEUCHOS_ASSERT(parameters_[pIndex]->dfdp_rl!=null);
1360
1361 ResponseLibrary<Traits> & rLibrary = *parameters_[pIndex]->dfdp_rl;
1362
1363 // get the response and tell it to fill the derivative operator
1364 RCP<Response_Residual<Traits::Hessian> > response_hessian =
1365 rcp_dynamic_cast<Response_Residual<Traits::Hessian> >(rLibrary.getResponse<Traits::Hessian>("RESIDUAL"));
1366 response_hessian->setHessian(D2fDpDx);
1367
1368 // setup all the assembly in arguments (this is parameters and x/x_dot).
1369 // make sure the correct seeding is performed
1371 setupAssemblyInArgs(inArgs,ae_inargs);
1372
1373 auto deltaXContainer = lof_->buildReadOnlyDomainContainer();
1374 deltaXContainer->setOwnedVector(delta_x);
1375 ae_inargs.addGlobalEvaluationData("DELTA_Solution Gather Container",deltaXContainer);
1376
1377 ae_inargs.gather_seeds.push_back(1.0); // this assumes that gather point is always the zero index of
1378 // gather seeds
1379 ae_inargs.first_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1380 ae_inargs.second_sensitivities_name = "";
1381
1382 rLibrary.addResponsesToInArgs<Traits::Hessian>(ae_inargs);
1383 rLibrary.evaluate<Traits::Hessian>(ae_inargs);
1384#else
1385 (void)pIndex;
1386 (void)inArgs;
1387 (void)delta_x;
1388 (void)D2fDpDx;
1389 TEUCHOS_ASSERT(false);
1390#endif
1391}
1392
1393template <typename Scalar>
1395evalModel_D2fDp2(int pIndex,
1396 const Thyra::ModelEvaluatorBase::InArgs<Scalar> & inArgs,
1397 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & delta_p,
1398 const Teuchos::RCP<Thyra::LinearOpBase<Scalar> > & D2fDp2) const
1399{
1400#ifdef Panzer_BUILD_HESSIAN_SUPPORT
1401 using Teuchos::RCP;
1402 using Teuchos::rcp_dynamic_cast;
1403 using Teuchos::null;
1404
1405 // parameter is not distributed
1406 TEUCHOS_ASSERT(parameters_[pIndex]->is_distributed);
1407
1408 // parameter is distributed but has no global indexer.
1409 // thus the user doesn't want sensitivities!
1410 TEUCHOS_ASSERT(parameters_[pIndex]->dfdp_rl!=null);
1411
1412 ResponseLibrary<Traits> & rLibrary = *parameters_[pIndex]->dfdp_rl;
1413
1414 // get the response and tell it to fill the derivative operator
1415 RCP<Response_Residual<Traits::Hessian> > response_hessian =
1416 rcp_dynamic_cast<Response_Residual<Traits::Hessian> >(rLibrary.getResponse<Traits::Hessian>("RESIDUAL"));
1417 response_hessian->setHessian(D2fDp2);
1418
1419 // setup all the assembly in arguments (this is parameters and x/x_dot).
1420 // make sure the correct seeding is performed
1422 setupAssemblyInArgs(inArgs,ae_inargs);
1423
1424 auto deltaPContainer = parameters_[pIndex]->dfdp_rl->getLinearObjFactory()->buildReadOnlyDomainContainer();
1425 deltaPContainer->setOwnedVector(delta_p);
1426 ae_inargs.addGlobalEvaluationData("DELTA_"+(*parameters_[pIndex]->names)[0],deltaPContainer);
1427
1428 ae_inargs.gather_seeds.push_back(1.0); // this assumes that gather point is always the zero index of
1429 // gather seeds
1430 ae_inargs.first_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1431 ae_inargs.second_sensitivities_name = (*parameters_[pIndex]->names)[0]; // distributed parameters have one name!
1432
1433 rLibrary.addResponsesToInArgs<Traits::Hessian>(ae_inargs);
1434 rLibrary.evaluate<Traits::Hessian>(ae_inargs);
1435#else
1436 (void)pIndex;
1437 (void)inArgs;
1438 (void)delta_p;
1439 (void)D2fDp2;
1440 TEUCHOS_ASSERT(false);
1441#endif
1442}
1443
1444template <typename Scalar>
1446evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1447 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
1448{
1449 evalModelImpl_basic(inArgs,outArgs);
1450
1451 // evaluate responses...uses the stored assembly arguments and containers
1452 if(required_basic_g(outArgs))
1453 evalModelImpl_basic_g(inArgs,outArgs);
1454
1455 // evaluate response derivatives
1456 if(required_basic_dgdx(outArgs))
1457 evalModelImpl_basic_dgdx(inArgs,outArgs);
1458
1459 // evaluate response derivatives to scalar parameters
1460 if(required_basic_dgdp_scalar(outArgs))
1461 evalModelImpl_basic_dgdp_scalar(inArgs,outArgs);
1462
1463 // evaluate response derivatives to distributed parameters
1464 if(required_basic_dgdp_distro(outArgs))
1465 evalModelImpl_basic_dgdp_distro(inArgs,outArgs);
1466
1467 if(required_basic_dfdp_scalar(outArgs)) {
1468 if (do_fd_dfdp_)
1469 evalModelImpl_basic_dfdp_scalar_fd(inArgs,outArgs);
1470 else
1471 evalModelImpl_basic_dfdp_scalar(inArgs,outArgs);
1472 }
1473
1474 if(required_basic_dfdp_distro(outArgs))
1475 evalModelImpl_basic_dfdp_distro(inArgs,outArgs);
1476}
1477
1478template <typename Scalar>
1480evalModelImpl_basic(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1481 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
1482{
1483 using Teuchos::RCP;
1484 using Teuchos::ArrayRCP;
1485 using Teuchos::Array;
1486 using Teuchos::tuple;
1487 using Teuchos::rcp_dynamic_cast;
1488
1489 typedef Thyra::ModelEvaluatorBase MEB;
1490
1491 // Transient or steady-state evaluation is determined by the x_dot
1492 // vector. If this RCP is null, then we are doing a steady-state
1493 // fill.
1494 bool is_transient = false;
1495 if (inArgs.supports(MEB::IN_ARG_x_dot ))
1496 is_transient = !Teuchos::is_null(inArgs.get_x_dot());
1497
1498 // Make sure construction built in transient support
1499 TEUCHOS_TEST_FOR_EXCEPTION(is_transient && !build_transient_support_, std::runtime_error,
1500 "ModelEvaluator was not built with transient support enabled!");
1501
1502 //
1503 // Get the output arguments
1504 //
1505 const RCP<Thyra::VectorBase<Scalar> > f_out = outArgs.get_f();
1506 const RCP<Thyra::LinearOpBase<Scalar> > W_out = outArgs.get_W_op();
1507
1508 // see if the user wants us to do anything
1509 if(Teuchos::is_null(f_out) && Teuchos::is_null(W_out) ) {
1510 return;
1511 }
1512
1513 // setup all the assembly in arguments (this is parameters and
1514 // x/x_dot). At this point with the exception of the one time dirichlet
1515 // beta that is all thats neccessary.
1517 setupAssemblyInArgs(inArgs,ae_inargs);
1518
1519 // set model parameters from supplied inArgs
1520 setParameters(inArgs);
1521
1522 // handle application of the one time dirichlet beta in the
1523 // assembly engine. Note that this has to be set explicitly
1524 // each time because this badly breaks encapsulation. Essentially
1525 // we must work around the model evaluator abstraction!
1526 if(oneTimeDirichletBeta_on_) {
1527 ae_inargs.dirichlet_beta = oneTimeDirichletBeta_;
1528 ae_inargs.apply_dirichlet_beta = true;
1529
1530 oneTimeDirichletBeta_on_ = false;
1531 }
1532
1533 // here we are building a container, this operation is fast, simply allocating a struct
1534 const RCP<panzer::ThyraObjContainer<Scalar> > thGlobalContainer =
1535 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.container_);
1536 const RCP<panzer::ThyraObjContainer<Scalar> > thGhostedContainer =
1537 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(ae_inargs.ghostedContainer_);
1538
1539 if (!Teuchos::is_null(f_out) && !Teuchos::is_null(W_out)) {
1540 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModel(f and J)");
1541
1542 // only add auxiliary global data if Jacobian is being formed
1543 ae_inargs.addGlobalEvaluationData(nonParamGlobalEvaluationData_);
1544
1545 // Set the targets
1546 thGlobalContainer->set_f_th(f_out);
1547 thGlobalContainer->set_A_th(W_out);
1548
1549 // Zero values in ghosted container objects
1550 Thyra::assign(thGhostedContainer->get_f_th().ptr(),0.0);
1551 thGhostedContainer->initializeMatrix(0.0);
1552
1553 ae_tm_.template getAsObject<panzer::Traits::Jacobian>()->evaluate(ae_inargs);
1554 }
1555 else if(!Teuchos::is_null(f_out) && Teuchos::is_null(W_out)) {
1556
1557 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModel(f)");
1558
1559 // don't add auxiliary global data if Jacobian is not computed.
1560 // this leads to zeroing of aux ops in special cases.
1561
1562 thGlobalContainer->set_f_th(f_out);
1563
1564 // Zero values in ghosted container objects
1565 Thyra::assign(thGhostedContainer->get_f_th().ptr(),0.0);
1566
1567 ae_tm_.template getAsObject<panzer::Traits::Residual>()->evaluate(ae_inargs);
1568 }
1569 else if(Teuchos::is_null(f_out) && !Teuchos::is_null(W_out)) {
1570
1571 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModel(J)");
1572
1573 // only add auxiliary global data if Jacobian is being formed
1574 ae_inargs.addGlobalEvaluationData(nonParamGlobalEvaluationData_);
1575
1576 // this dummy nonsense is needed only for scattering dirichlet conditions
1577 RCP<Thyra::VectorBase<Scalar> > dummy_f = Thyra::createMember(f_space_);
1578 thGlobalContainer->set_f_th(dummy_f);
1579 thGlobalContainer->set_A_th(W_out);
1580
1581 // Zero values in ghosted container objects
1582 thGhostedContainer->initializeMatrix(0.0);
1583
1584 ae_tm_.template getAsObject<panzer::Traits::Jacobian>()->evaluate(ae_inargs);
1585 }
1586
1587 // HACK: set A to null before calling responses to avoid touching the
1588 // the Jacobian after it has been properly assembled. Should be fixed
1589 // by using a modified version of ae_inargs instead.
1590 thGlobalContainer->set_A_th(Teuchos::null);
1591
1592 // TODO: Clearing all references prevented a seg-fault with Rythmos,
1593 // which is no longer used. Check if it's still needed.
1594 thGlobalContainer->set_x_th(Teuchos::null);
1595 thGlobalContainer->set_dxdt_th(Teuchos::null);
1596 thGlobalContainer->set_f_th(Teuchos::null);
1597 thGlobalContainer->set_A_th(Teuchos::null);
1598
1599 // reset parameters back to nominal values
1600 resetParameters();
1601
1602 const bool writeToFile = false;
1603 if (writeToFile && nonnull(W_out)) {
1604 const auto check_blocked = Teuchos::rcp_dynamic_cast<::Thyra::BlockedLinearOpBase<double> >(W_out,false);
1605 if (check_blocked) {
1606 const int numBlocks = check_blocked->productDomain()->numBlocks();
1607 const int rangeBlocks = check_blocked->productRange()->numBlocks();
1608 TEUCHOS_ASSERT(numBlocks == rangeBlocks); // not true for optimization
1609 for (int row=0; row < numBlocks; ++row) {
1610 for (int col=0; col < numBlocks; ++col) {
1611 using LO = panzer::LocalOrdinal;
1612 using GO = panzer::GlobalOrdinal;
1613 using NodeT = panzer::TpetraNodeType;
1614 const auto thyraTpetraOperator = Teuchos::rcp_dynamic_cast<::Thyra::TpetraLinearOp<double,LO,GO,NodeT>>(check_blocked->getNonconstBlock(row,col),true);
1615 const auto tpetraCrsMatrix = Teuchos::rcp_dynamic_cast<Tpetra::CrsMatrix<double,LO,GO,NodeT>>(thyraTpetraOperator->getTpetraOperator(),true);
1616 tpetraCrsMatrix->print(std::cout);
1617 std::stringstream ss;
1618 ss << "W_out_" << write_matrix_count_ << ".rank_" << tpetraCrsMatrix->getMap()->getComm()->getRank() << ".block_" << row << "_" << col << ".txt";
1619 std::fstream fs(ss.str().c_str(),std::fstream::out|std::fstream::trunc);
1620 Teuchos::FancyOStream fos(Teuchos::rcpFromRef(fs));
1621 tpetraCrsMatrix->describe(fos,Teuchos::VERB_EXTREME);
1622 fs.close();
1623 }
1624 }
1625 }
1626 else {
1627 using LO = panzer::LocalOrdinal;
1628 using GO = panzer::GlobalOrdinal;
1629 using NodeT = panzer::TpetraNodeType;
1630 const auto thyraTpetraOperator = Teuchos::rcp_dynamic_cast<::Thyra::TpetraLinearOp<double,LO,GO,NodeT>>(W_out,true);
1631 const auto tpetraCrsMatrix = Teuchos::rcp_dynamic_cast<Tpetra::CrsMatrix<double,LO,GO,NodeT>>(thyraTpetraOperator->getTpetraOperator(),true);
1632 tpetraCrsMatrix->print(std::cout);
1633 std::stringstream ss;
1634 ss << "W_out_" << write_matrix_count_ << ".rank_" << tpetraCrsMatrix->getMap()->getComm()->getRank() << ".txt";
1635 std::fstream fs(ss.str().c_str(),std::fstream::out|std::fstream::trunc);
1636 Teuchos::FancyOStream fos(Teuchos::rcpFromRef(fs));
1637 tpetraCrsMatrix->describe(fos,Teuchos::VERB_EXTREME);
1638 fs.close();
1639 }
1640 ++write_matrix_count_;
1641 }
1642
1643}
1644
1645template <typename Scalar>
1647evalModelImpl_basic_g(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1648 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
1649{
1650 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModelImpl_basic_g()");
1651 // optional sanity check
1652 // TEUCHOS_ASSERT(required_basic_g(outArgs));
1653
1654 // setup all the assembly in arguments (this is parameters and
1655 // x/x_dot). At this point with the exception of the one time dirichlet
1656 // beta that is all thats neccessary.
1658 setupAssemblyInArgs(inArgs,ae_inargs);
1659
1660 // set model parameters from supplied inArgs
1661 setParameters(inArgs);
1662
1663 for(std::size_t i=0;i<responses_.size();i++) {
1664 Teuchos::RCP<Thyra::VectorBase<Scalar> > vec = outArgs.get_g(i);
1665 if(vec!=Teuchos::null) {
1666 std::string responseName = responses_[i]->name;
1667 Teuchos::RCP<panzer::ResponseMESupportBase<panzer::Traits::Residual> > resp
1668 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Residual> >(
1669 responseLibrary_->getResponse<panzer::Traits::Residual>(responseName));
1670 resp->setVector(vec);
1671 }
1672 }
1673
1674 // evaluator responses
1675 responseLibrary_->addResponsesToInArgs<panzer::Traits::Residual>(ae_inargs);
1676 responseLibrary_->evaluate<panzer::Traits::Residual>(ae_inargs);
1677
1678 // reset parameters back to nominal values
1679 resetParameters();
1680}
1681
1682template <typename Scalar>
1683void
1685evalModelImpl_basic_dgdx(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1686 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
1687{
1688 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModelImpl_basic_dgdx()");
1689 typedef Thyra::ModelEvaluatorBase MEB;
1690
1691 // optional sanity check
1692 TEUCHOS_ASSERT(required_basic_dgdx(outArgs));
1693
1694 // set model parameters from supplied inArgs
1695 setParameters(inArgs);
1696
1697 for(std::size_t i=0;i<responses_.size();i++) {
1698 // get "Vector" out of derivative, if its something else, throw an exception
1699 MEB::Derivative<Scalar> deriv = outArgs.get_DgDx(i);
1700 if(deriv.isEmpty())
1701 continue;
1702
1703 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > vec = deriv.getMultiVector();
1704
1705 if(vec!=Teuchos::null) {
1706
1707 std::string responseName = responses_[i]->name;
1708 Teuchos::RCP<panzer::ResponseMESupportBase<panzer::Traits::Jacobian> > resp
1709 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Jacobian> >(
1710 responseLibrary_->getResponse<panzer::Traits::Jacobian>(responseName));
1711 resp->setDerivative(vec);
1712 }
1713 }
1714
1715 // setup all the assembly in arguments (this is parameters and
1716 // x/x_dot). At this point with the exception of the one time dirichlet
1717 // beta that is all thats neccessary.
1719 setupAssemblyInArgs(inArgs,ae_inargs);
1720
1721 // evaluate responses
1722 responseLibrary_->addResponsesToInArgs<panzer::Traits::Jacobian>(ae_inargs);
1723 responseLibrary_->evaluate<panzer::Traits::Jacobian>(ae_inargs);
1724
1725 // reset parameters back to nominal values
1726 resetParameters();
1727}
1728
1729template <typename Scalar>
1730void
1732evalModelImpl_basic_dgdp_scalar(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1733 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
1734{
1735 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModelImpl_basic_dgdp_scalar()");
1736 using Teuchos::RCP;
1737 using Teuchos::rcp;
1738 using Teuchos::rcp_dynamic_cast;
1739
1740 typedef Thyra::ModelEvaluatorBase MEB;
1741
1742 // optional sanity check
1743 TEUCHOS_ASSERT(required_basic_dgdp_scalar(outArgs));
1744
1745 // First find all of the active parameters for all responses
1746 std::vector<std::string> activeParameterNames;
1747 std::vector<int> activeParameters;
1748 int totalParameterCount = 0;
1749 for(std::size_t j=0; j<parameters_.size(); j++) {
1750
1751 // skip non-scalar parameters
1752 if(parameters_[j]->is_distributed)
1753 continue;
1754
1755 bool is_active = false;
1756 for(std::size_t i=0;i<responses_.size(); i++) {
1757
1758 MEB::Derivative<Scalar> deriv = outArgs.get_DgDp(i,j);
1759 if(deriv.isEmpty())
1760 continue;
1761
1762 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > vec = deriv.getMultiVector();
1763 if(vec!=Teuchos::null) {
1764 // get the response and tell it to fill the derivative vector
1765 std::string responseName = responses_[i]->name;
1766 RCP<panzer::ResponseMESupportBase<panzer::Traits::Tangent> > resp =
1767 rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Tangent> >(
1768 responseLibrary_->getResponse<panzer::Traits::Tangent>(responseName));
1769
1770 if (nonnull(resp)) {
1771 resp->setVector(vec);
1772 is_active = true;
1773 }
1774 }
1775 }
1776
1777 if (is_active) {
1778 for (std::size_t k=0; k<parameters_[j]->scalar_value.size(); k++) {
1779 std::string name = "PARAMETER_SENSITIVIES: "+(*parameters_[j]->names)[k];
1780 activeParameterNames.push_back(name);
1781 totalParameterCount++;
1782 }
1783 activeParameters.push_back(j);
1784 }
1785 }
1786
1787 // setup all the assembly in arguments
1789 setupAssemblyInArgs(inArgs,ae_inargs);
1790
1791 // add active parameter names to assembly in-args
1792 RCP<panzer::GlobalEvaluationData> ged_activeParameters =
1793 rcp(new panzer::ParameterList_GlobalEvaluationData(activeParameterNames));
1794 ae_inargs.addGlobalEvaluationData("PARAMETER_NAMES",ged_activeParameters);
1795
1796 // Initialize Fad components of all active parameters
1797 int paramIndex = 0;
1798 for (std::size_t ap=0; ap<activeParameters.size(); ++ap) {
1799 const int j = activeParameters[ap];
1800 for (unsigned int k=0; k < parameters_[j]->scalar_value.size(); k++) {
1801 panzer::Traits::FadType p(totalParameterCount, parameters_[j]->scalar_value[k].baseValue);
1802 p.fastAccessDx(paramIndex) = 1.0;
1803 parameters_[j]->scalar_value[k].family->template setValue<panzer::Traits::Tangent>(p);
1804 paramIndex++;
1805 }
1806 }
1807
1808 // make sure that the total parameter count and the total parameter index match up
1809 TEUCHOS_ASSERT(paramIndex==totalParameterCount);
1810
1811 // evaluate response tangent
1812 if(totalParameterCount>0) {
1813 responseLibrary_->addResponsesToInArgs<Traits::Tangent>(ae_inargs);
1814 responseLibrary_->evaluate<Traits::Tangent>(ae_inargs);
1815 }
1816}
1817
1818template <typename Scalar>
1819void
1821evalModelImpl_basic_dgdp_distro(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1822 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
1823{
1824 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModelImpl_basic_dgdp_distro()");
1825 typedef Thyra::ModelEvaluatorBase MEB;
1826
1827 // optional sanity check
1828 TEUCHOS_ASSERT(required_basic_dgdp_distro(outArgs));
1829
1830 // loop over parameters, and then build a dfdp_rl only if they are distributed
1831 // and the user has provided the UGI. Note that this may be overly expensive if they
1832 // don't actually want those sensitivites because memory will be allocated unneccesarily.
1833 // It would be good to do this "just in time", but for now this is sufficient.
1834 for(std::size_t p=0;p<parameters_.size();p++) {
1835
1836 // parameter is not distributed, a different path is
1837 // taken for those to compute dfdp
1838 if(!parameters_[p]->is_distributed)
1839 continue;
1840
1841 ResponseLibrary<Traits> & rLibrary = *parameters_[p]->dgdp_rl;
1842
1843 for(std::size_t r=0;r<responses_.size();r++) {
1844 // have derivatives been requested?
1845 MEB::Derivative<Scalar> deriv = outArgs.get_DgDp(r,p);
1846 if(deriv.isEmpty())
1847 continue;
1848
1849 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > vec = deriv.getMultiVector();
1850
1851 if(vec!=Teuchos::null) {
1852
1853 // get the response and tell it to fill the derivative vector
1854 std::string responseName = responses_[r]->name;
1855 Teuchos::RCP<panzer::ResponseMESupportBase<panzer::Traits::Jacobian> > resp
1856 = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Jacobian> >(
1857 rLibrary.getResponse<panzer::Traits::Jacobian>(responseName));
1858
1859 resp->setDerivative(vec);
1860 }
1861 }
1862
1863 // setup all the assembly in arguments (this is parameters and x/x_dot).
1864 // make sure the correct seeding is performed
1866 setupAssemblyInArgs(inArgs,ae_inargs);
1867
1868 ae_inargs.first_sensitivities_name = (*parameters_[p]->names)[0]; // distributed parameters have one name!
1869 ae_inargs.gather_seeds.push_back(1.0); // this assumes that gather point is always the zero index of
1870 // gather seeds
1871
1872 // evaluate responses
1873 rLibrary.addResponsesToInArgs<Traits::Jacobian>(ae_inargs);
1874 rLibrary.evaluate<Traits::Jacobian>(ae_inargs);
1875 }
1876}
1877
1878template <typename Scalar>
1879void
1881evalModelImpl_basic_dfdp_scalar(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1882 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
1883{
1884 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModelImpl_basic_dfdp_scalar()");
1885 using Teuchos::RCP;
1886 using Teuchos::rcp_dynamic_cast;
1887
1888 typedef Thyra::ModelEvaluatorBase MEB;
1889
1890 TEUCHOS_ASSERT(required_basic_dfdp_scalar(outArgs));
1891
1892 // setup all the assembly in arguments (this is parameters and
1893 // x/x_dot). At this point with the exception of the one time dirichlet
1894 // beta that is all thats neccessary.
1896 setupAssemblyInArgs(inArgs,ae_inargs);
1897
1898 // First: Fill the output vectors from the input arguments structure. Put them
1899 // in the global evaluation data container so they are correctly communicated.
1901
1902 std::vector<std::string> activeParameters;
1903
1904 int totalParameterCount = 0;
1905 for(std::size_t i=0; i < parameters_.size(); i++) {
1906 // skip non-scalar parameters
1907 if(parameters_[i]->is_distributed)
1908 continue;
1909
1910 // have derivatives been requested?
1911 MEB::Derivative<Scalar> deriv = outArgs.get_DfDp(i);
1912 if(deriv.isEmpty())
1913 continue;
1914
1915 // grab multivector, make sure its the right dimension
1916 Teuchos::RCP<Thyra::MultiVectorBase<Scalar> > mVec = deriv.getMultiVector();
1917 TEUCHOS_ASSERT(mVec->domain()->dim()==Teuchos::as<int>(parameters_[i]->scalar_value.size()));
1918
1919 for (std::size_t j=0; j < parameters_[i]->scalar_value.size(); j++) {
1920
1921 // build containers for each vector
1922 RCP<LOCPair_GlobalEvaluationData> loc_pair
1923 = Teuchos::rcp(new LOCPair_GlobalEvaluationData(lof_,LinearObjContainer::F));
1924 RCP<LinearObjContainer> globalContainer = loc_pair->getGlobalLOC();
1925
1926 // stuff target vector into global container
1927 RCP<Thyra::VectorBase<Scalar> > vec = mVec->col(j);
1928 RCP<panzer::ThyraObjContainer<Scalar> > thGlobalContainer =
1929 Teuchos::rcp_dynamic_cast<panzer::ThyraObjContainer<Scalar> >(globalContainer);
1930 thGlobalContainer->set_f_th(vec);
1931
1932 // add container into in args object
1933 std::string name = "PARAMETER_SENSITIVIES: "+(*parameters_[i]->names)[j];
1934 ae_inargs.addGlobalEvaluationData(name,loc_pair->getGhostedLOC());
1935 ae_inargs.addGlobalEvaluationData(name+"_pair",loc_pair);
1936
1937 activeParameters.push_back(name);
1938 totalParameterCount++;
1939 }
1940 }
1941
1942 // Second: For all parameters that require derivative sensitivities, put in a name
1943 // so that the scatter can realize which sensitivity vectors it needs to fill
1945
1946 RCP<GlobalEvaluationData> ged_activeParameters
1947 = Teuchos::rcp(new ParameterList_GlobalEvaluationData(activeParameters));
1948 ae_inargs.addGlobalEvaluationData("PARAMETER_NAMES",ged_activeParameters);
1949
1950 // Third: Now seed all the parameters in the parameter vector so that derivatives
1951 // can be properly computed.
1953
1954 int paramIndex = 0;
1955 for(std::size_t i=0; i < parameters_.size(); i++) {
1956 // skip non-scalar parameters
1957 if(parameters_[i]->is_distributed)
1958 continue;
1959
1960 // don't modify the parameter if its not needed
1961 MEB::Derivative<Scalar> deriv = outArgs.get_DfDp(i);
1962 if(deriv.isEmpty()) {
1963 // reinitialize values that should not have sensitivities computed (this is a precaution)
1964 for (unsigned int j=0; j < parameters_[i]->scalar_value.size(); j++) {
1965 Traits::FadType p = Traits::FadType(totalParameterCount,
1966 parameters_[i]->scalar_value[j].baseValue);
1967 parameters_[i]->scalar_value[j].family->template setValue<panzer::Traits::Tangent>(p);
1968 }
1969 continue;
1970 }
1971 else {
1972 // loop over each parameter in the vector, initializing the AD type
1973 for (unsigned int j=0; j < parameters_[i]->scalar_value.size(); j++) {
1974 Traits::FadType p = Traits::FadType(totalParameterCount,
1975 parameters_[i]->scalar_value[j].baseValue);
1976 p.fastAccessDx(paramIndex) = 1.0;
1977 parameters_[i]->scalar_value[j].family->template setValue<panzer::Traits::Tangent>(p);
1978 paramIndex++;
1979 }
1980 }
1981 }
1982
1983 // make sure that the total parameter count and the total parameter index match up
1984 TEUCHOS_ASSERT(paramIndex==totalParameterCount);
1985
1986 // Fourth: Actually evaluate the residual's sensitivity to the parameters
1988
1989 if(totalParameterCount>0) {
1990 PANZER_FUNC_TIME_MONITOR_DIFF("panzer::ModelEvaluator::evalModel(df/dp)",dfdp_eval);
1991 ae_tm_.getAsObject<panzer::Traits::Tangent>()->evaluate(ae_inargs);
1992 }
1993}
1994
1995template <typename Scalar>
1996void
1998evalModelImpl_basic_dfdp_scalar_fd(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
1999 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2000{
2001 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModelImpl_basic_dfdp_scalar_fd()");
2002
2003 using Teuchos::RCP;
2004 using Teuchos::rcp_dynamic_cast;
2005
2006 typedef Thyra::ModelEvaluatorBase MEB;
2007
2008 TEUCHOS_ASSERT(required_basic_dfdp_scalar(outArgs));
2009
2010 // First evaluate the model without df/dp for the base point
2011 // Maybe it would be better to set all outArgs and then remove the df/dp ones,
2012 // but I couldn't get that to work.
2013 MEB::OutArgs<Scalar> outArgs_base = this->createOutArgs();
2014 if (outArgs.get_f() == Teuchos::null)
2015 outArgs_base.set_f(Thyra::createMember(this->get_f_space()));
2016 else
2017 outArgs_base.set_f(outArgs.get_f());
2018 outArgs_base.set_W_op(outArgs.get_W_op());
2019 this->evalModel(inArgs, outArgs_base);
2020 RCP<const Thyra::VectorBase<Scalar> > f = outArgs_base.get_f();
2021 RCP<const Thyra::VectorBase<Scalar> > x = inArgs.get_x();
2022 RCP<const Thyra::VectorBase<Scalar> > x_dot;
2023 if (inArgs.supports(MEB::IN_ARG_x_dot))
2024 x_dot = inArgs.get_x_dot();
2025
2026 // Create in/out args for FD calculation
2027 RCP<Thyra::VectorBase<Scalar> > fd = Thyra::createMember(this->get_f_space());
2028 MEB::OutArgs<Scalar> outArgs_fd = this->createOutArgs();
2029 outArgs_fd.set_f(fd);
2030
2031 RCP<Thyra::VectorBase<Scalar> > xd = Thyra::createMember(this->get_x_space());
2032 RCP<Thyra::VectorBase<Scalar> > xd_dot;
2033 if (x_dot != Teuchos::null)
2034 xd_dot = Thyra::createMember(this->get_x_space());
2035 MEB::InArgs<Scalar> inArgs_fd = this->createInArgs();
2036 inArgs_fd.setArgs(inArgs); // This sets all inArgs that we don't override below
2037 inArgs_fd.set_x(xd);
2038 if (x_dot != Teuchos::null)
2039 inArgs_fd.set_x_dot(xd_dot);
2040
2041 const double h = fd_perturb_size_;
2042 for(std::size_t i=0; i < parameters_.size(); i++) {
2043
2044 // skip non-scalar parameters
2045 if(parameters_[i]->is_distributed)
2046 continue;
2047
2048 // have derivatives been requested?
2049 MEB::Derivative<Scalar> deriv = outArgs.get_DfDp(i);
2050 if(deriv.isEmpty())
2051 continue;
2052
2053 // grab multivector, make sure its the right dimension
2054 RCP<Thyra::MultiVectorBase<Scalar> > dfdp = deriv.getMultiVector();
2055 TEUCHOS_ASSERT(dfdp->domain()->dim()==Teuchos::as<int>(parameters_[i]->scalar_value.size()));
2056
2057 // Get parameter vector and tangent vectors
2058 RCP<const Thyra::VectorBase<Scalar> > p = inArgs.get_p(i);
2059 RCP<const Thyra::VectorBase<Scalar> > dx_v = inArgs.get_p(i+parameters_.size());
2060 RCP<const Thyra::MultiVectorBase<Scalar> > dx =
2061 rcp_dynamic_cast<const Thyra::DefaultMultiVectorProductVector<Scalar> >(dx_v,true)->getMultiVector();
2062 RCP<const Thyra::VectorBase<Scalar> > dx_dot_v;
2063 RCP<const Thyra::MultiVectorBase<Scalar> > dx_dot;
2064 if (x_dot != Teuchos::null) {
2065 dx_dot_v =inArgs.get_p(i+parameters_.size()+tangent_space_.size());
2066 dx_dot =
2067 rcp_dynamic_cast<const Thyra::DefaultMultiVectorProductVector<Scalar> >(dx_dot_v,true)->getMultiVector();
2068 }
2069
2070 // Create perturbed parameter vector
2071 RCP<Thyra::VectorBase<Scalar> > pd = Thyra::createMember(this->get_p_space(i));
2072 inArgs_fd.set_p(i,pd);
2073
2074 for (std::size_t j=0; j < parameters_[i]->scalar_value.size(); j++) {
2075
2076 // Perturb parameter vector
2077 Thyra::copy(*p, pd.ptr());
2078 Thyra::set_ele(j, Thyra::get_ele(*p,j)+h, pd.ptr());
2079
2080 // Perturb state vectors using tangents
2081 Thyra::V_VpStV(xd.ptr(), *x, h, *(dx)->col(j));
2082 if (x_dot != Teuchos::null)
2083 Thyra::V_VpStV(xd_dot.ptr(), *x_dot, h, *(dx_dot)->col(j));
2084
2085 // Evaluate perturbed residual
2086 Thyra::assign(fd.ptr(), 0.0);
2087 this->evalModel(inArgs_fd, outArgs_fd);
2088
2089 // FD calculation
2090 Thyra::V_StVpStV(dfdp->col(j).ptr(), 1.0/h, *fd, -1.0/h, *f);
2091
2092 // Reset parameter back to un-perturbed value
2093 parameters_[i]->scalar_value[j].family->setRealValueForAllTypes(Thyra::get_ele(*p,j));
2094
2095 }
2096 }
2097}
2098
2099template <typename Scalar>
2100void
2102evalModelImpl_basic_dfdp_distro(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs,
2103 const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2104{
2105 PANZER_FUNC_TIME_MONITOR("panzer::ModelEvaluator::evalModelImpl_basic_dfdp_distro()");
2106 using Teuchos::RCP;
2107 using Teuchos::rcp_dynamic_cast;
2108 using Teuchos::null;
2109
2110 typedef Thyra::ModelEvaluatorBase MEB;
2111
2112 TEUCHOS_ASSERT(required_basic_dfdp_distro(outArgs));
2113
2114 // loop over parameters, and then build a dfdp_rl only if they are distributed
2115 // and the user has provided the UGI. Note that this may be overly expensive if they
2116 // don't actually want those sensitivites because memory will be allocated unneccesarily.
2117 // It would be good to do this "just in time", but for now this is sufficient.
2118 for(std::size_t p=0;p<parameters_.size();p++) {
2119
2120 // parameter is not distributed, a different path is
2121 // taken for those to compute dfdp
2122 if(!parameters_[p]->is_distributed)
2123 continue;
2124
2125 // parameter is distributed but has no global indexer.
2126 // thus the user doesn't want sensitivities!
2127 if(parameters_[p]->dfdp_rl==null)
2128 continue;
2129
2130 // have derivatives been requested?
2131 MEB::Derivative<Scalar> deriv = outArgs.get_DfDp(p);
2132 if(deriv.isEmpty())
2133 continue;
2134
2135 ResponseLibrary<Traits> & rLibrary = *parameters_[p]->dfdp_rl;
2136
2137 // get the response and tell it to fill the derivative operator
2138 RCP<Response_Residual<Traits::Jacobian> > response_jacobian =
2139 rcp_dynamic_cast<Response_Residual<Traits::Jacobian> >(rLibrary.getResponse<Traits::Jacobian>("RESIDUAL"));
2140 response_jacobian->setJacobian(deriv.getLinearOp());
2141
2142 // setup all the assembly in arguments (this is parameters and x/x_dot).
2143 // make sure the correct seeding is performed
2145 setupAssemblyInArgs(inArgs,ae_inargs);
2146
2147 ae_inargs.first_sensitivities_name = (*parameters_[p]->names)[0]; // distributed parameters have one name!
2148 ae_inargs.gather_seeds.push_back(1.0); // this assumes that gather point is always the zero index of
2149 // gather seeds
2150 rLibrary.addResponsesToInArgs<Traits::Jacobian>(ae_inargs);
2151
2152 rLibrary.evaluate<Traits::Jacobian>(ae_inargs);
2153 }
2154}
2155
2156template <typename Scalar>
2158required_basic_g(const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2159{
2160 // determine if any of the outArgs are not null!
2161 bool activeGArgs = false;
2162 for(int i=0;i<outArgs.Ng();i++)
2163 activeGArgs |= (outArgs.get_g(i)!=Teuchos::null);
2164
2165 return activeGArgs | required_basic_dgdx(outArgs);
2166}
2167
2168template <typename Scalar>
2170required_basic_dgdx(const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2171{
2172 typedef Thyra::ModelEvaluatorBase MEB;
2173
2174 // determine if any of the outArgs are not null!
2175 bool activeGArgs = false;
2176 for(int i=0;i<outArgs.Ng();i++) {
2177 // no derivatives are supported
2178 if(outArgs.supports(MEB::OUT_ARG_DgDx,i).none())
2179 continue;
2180
2181 // this is basically a redundant computation
2182 activeGArgs |= (!outArgs.get_DgDx(i).isEmpty());
2183 }
2184
2185 return activeGArgs;
2186}
2187
2188template <typename Scalar>
2190required_basic_dgdp_scalar(const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2191{
2192 typedef Thyra::ModelEvaluatorBase MEB;
2193
2194 // determine if any of the outArgs are not null!
2195 bool activeGArgs = false;
2196 for(int i=0;i<outArgs.Ng();i++) {
2197 for(int p=0;p<Teuchos::as<int>(parameters_.size());p++) {
2198
2199 // only look at scalar parameters
2200 if(parameters_[p]->is_distributed)
2201 continue;
2202
2203 // no derivatives are supported
2204 if(outArgs.supports(MEB::OUT_ARG_DgDp,i,p).none())
2205 continue;
2206
2207 activeGArgs |= (!outArgs.get_DgDp(i,p).isEmpty());
2208 }
2209 }
2210
2211 return activeGArgs;
2212}
2213
2214template <typename Scalar>
2216required_basic_dgdp_distro(const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2217{
2218 typedef Thyra::ModelEvaluatorBase MEB;
2219
2220 // determine if any of the outArgs are not null!
2221 bool activeGArgs = false;
2222 for(int i=0;i<outArgs.Ng();i++) {
2223 for(int p=0;p<Teuchos::as<int>(parameters_.size());p++) {
2224
2225 // only look at distributed parameters
2226 if(!parameters_[p]->is_distributed)
2227 continue;
2228
2229 // no derivatives are supported
2230 if(outArgs.supports(MEB::OUT_ARG_DgDp,i,p).none())
2231 continue;
2232
2233 activeGArgs |= (!outArgs.get_DgDp(i,p).isEmpty());
2234 }
2235 }
2236
2237 return activeGArgs;
2238}
2239
2240template <typename Scalar>
2242required_basic_dfdp_scalar(const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2243{
2244 typedef Thyra::ModelEvaluatorBase MEB;
2245
2246 // determine if any of the outArgs are not null!
2247 bool activeFPArgs = false;
2248 for(int i=0;i<Teuchos::as<int>(parameters_.size());i++) {
2249
2250 // this is for scalar parameters only
2251 if(parameters_[i]->is_distributed)
2252 continue;
2253
2254 // no derivatives are supported
2255 if(outArgs.supports(MEB::OUT_ARG_DfDp,i).none())
2256 continue;
2257
2258 // this is basically a redundant computation
2259 activeFPArgs |= (!outArgs.get_DfDp(i).isEmpty());
2260 }
2261
2262 return activeFPArgs;
2263}
2264
2265template <typename Scalar>
2267required_basic_dfdp_distro(const Thyra::ModelEvaluatorBase::OutArgs<Scalar> &outArgs) const
2268{
2269 typedef Thyra::ModelEvaluatorBase MEB;
2270
2271 // determine if any of the outArgs are not null!
2272 bool activeFPArgs = false;
2273 for(int i=0;i<Teuchos::as<int>(parameters_.size());i++) {
2274
2275 // this is for scalar parameters only
2276 if(!parameters_[i]->is_distributed)
2277 continue;
2278
2279 // no derivatives are supported
2280 if(outArgs.supports(MEB::OUT_ARG_DfDp,i).none())
2281 continue;
2282
2283 // this is basically a redundant computation
2284 activeFPArgs |= (!outArgs.get_DfDp(i).isEmpty());
2285 }
2286
2287 return activeFPArgs;
2288}
2289
2290template <typename Scalar>
2293 const Teuchos::RCP<panzer::WorksetContainer> & wc,
2294 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
2295 const std::vector<panzer::BC> & bcs,
2296 const panzer::EquationSetFactory & eqset_factory,
2297 const panzer::BCStrategyFactory& bc_factory,
2299 const Teuchos::ParameterList& closure_models,
2300 const Teuchos::ParameterList& user_data,
2301 const bool write_graphviz_file,
2302 const std::string& graphviz_file_prefix)
2303{
2304 using Teuchos::RCP;
2305 using Teuchos::rcp;
2306 using Teuchos::null;
2307
2308 // loop over parameters, and then build a dfdp_rl only if they are distributed
2309 // and the user has provided the UGI. Note that this may be overly expensive if they
2310 // don't actually want those sensitivites because memory will be allocated unneccesarily.
2311 // It would be good to do this "just in time", but for now this is sufficient.
2312 for(std::size_t p=0;p<parameters_.size();p++) {
2313 // parameter is not distributed, a different path is
2314 // taken for those to compute dfdp
2315 if(!parameters_[p]->is_distributed)
2316 continue;
2317
2318 // parameter is distributed but has no global indexer.
2319 // thus the user doesn't want sensitivities!
2320 if(parameters_[p]->global_indexer==null)
2321 continue;
2322
2323 // build the linear object factory that has the correct sizing for
2324 // the sensitivity matrix (parameter sized domain, residual sized range)
2325 RCP<const LinearObjFactory<Traits> > param_lof = cloneWithNewDomain(*lof_,
2326 parameters_[p]->global_indexer);
2327
2328 // the user wants global sensitivities, hooray! Build and setup the response library
2329 RCP<ResponseLibrary<Traits> > rLibrary
2330 = Teuchos::rcp(new ResponseLibrary<Traits>(wc,lof_->getRangeGlobalIndexer(),
2331 param_lof,true));
2332 rLibrary->buildResidualResponseEvaluators(physicsBlocks,eqset_factory,bcs,bc_factory,
2333 cm_factory,closure_models,user_data,
2334 write_graphviz_file,graphviz_file_prefix);
2335
2336 // make sure parameter response library is correct
2337 parameters_[p]->dfdp_rl = rLibrary;
2338 }
2339}
2340
2341template <typename Scalar>
2344 const Teuchos::RCP<panzer::WorksetContainer> & wc,
2345 const std::vector<Teuchos::RCP<panzer::PhysicsBlock> >& physicsBlocks,
2346 const std::vector<panzer::BC>& /* bcs */,
2347 const panzer::EquationSetFactory & eqset_factory,
2348 const panzer::BCStrategyFactory& /* bc_factory */,
2350 const Teuchos::ParameterList& closure_models,
2351 const Teuchos::ParameterList& user_data,
2352 const bool write_graphviz_file,
2353 const std::string& graphviz_file_prefix)
2354{
2355 using Teuchos::RCP;
2356 using Teuchos::rcp;
2357 using Teuchos::null;
2358
2359 // loop over parameters, and then build a dfdp_rl only if they are distributed
2360 // and the user has provided the UGI. Note that this may be overly expensive if they
2361 // don't actually want those sensitivites because memory will be allocated unneccesarily.
2362 // It would be good to do this "just in time", but for now this is sufficient.
2363 for(std::size_t p=0;p<parameters_.size();p++) {
2364 // parameter is not distributed, a different path is
2365 // taken for those to compute dfdp
2366 if(!parameters_[p]->is_distributed)
2367 continue;
2368
2369 // parameter is distributed but has no global indexer.
2370 // thus the user doesn't want sensitivities!
2371 if(parameters_[p]->global_indexer==null)
2372 continue;
2373
2374 // extract the linear object factory that has the correct sizing for
2375 // the sensitivity vector
2376 RCP<const LinearObjFactory<Traits> > param_lof = parameters_[p]->dfdp_rl->getLinearObjFactory();
2377 RCP<const GlobalIndexer > param_ugi = parameters_[p]->global_indexer;
2378
2379 // the user wants global sensitivities, hooray! Build and setup the response library
2380 RCP<ResponseLibrary<Traits> > rLibrary
2381 = Teuchos::rcp(new ResponseLibrary<Traits>(wc,lof_->getRangeGlobalIndexer(), lof_));
2382
2383
2384 // build evaluators for all flexible responses
2385 for(std::size_t r=0;r<responses_.size();r++) {
2386 // only responses with a builder are non null!
2387 if(responses_[r]->builder==Teuchos::null)
2388 continue;
2389
2390 // set the current derivative information in the builder
2391 // responses_[r]->builder->setDerivativeInformationBase(param_lof,param_ugi);
2392 responses_[r]->builder->setDerivativeInformation(param_lof);
2393
2394 // add the response
2395 rLibrary->addResponse(responses_[r]->name,
2396 responses_[r]->wkst_desc,
2397 *responses_[r]->builder);
2398 }
2399
2400 rLibrary->buildResponseEvaluators(physicsBlocks,eqset_factory,
2401 cm_factory,closure_models,user_data,
2402 write_graphviz_file,graphviz_file_prefix);
2403
2404 // make sure parameter response library is correct
2405 parameters_[p]->dgdp_rl = rLibrary;
2406 }
2407}
2408
2409template <typename Scalar>
2411setOneTimeDirichletBeta(const Scalar & beta) const
2412{
2413 oneTimeDirichletBeta_on_ = true;
2414 oneTimeDirichletBeta_ = beta;
2415}
2416
2417template <typename Scalar>
2418Teuchos::RCP<typename panzer::ModelEvaluator<Scalar>::ParameterObject>
2420createScalarParameter(const Teuchos::Array<std::string> & in_names,
2421 const Teuchos::Array<Scalar> & in_values) const
2422{
2423 using Teuchos::RCP;
2424 using Teuchos::rcp;
2425 using Teuchos::rcp_dynamic_cast;
2426 using Teuchos::ptrFromRef;
2427
2428 TEUCHOS_ASSERT(in_names.size()==in_values.size());
2429
2430 // Check that the parameters are valid (i.e., they already exist in the parameter library)
2431 // std::size_t np = in_names.size();
2432 // for(std::size_t i=0;i<np;i++)
2433 // TEUCHOS_TEST_FOR_EXCEPTION(!global_data_->pl->isParameter(in_names[i]),
2434 // std::logic_error,
2435 // "Parameter \"" << in_names[i] << "\" does not exist in parameter library!");
2436
2437 RCP<ParameterObject> paramObj = rcp(new ParameterObject);
2438
2439 paramObj->names = rcp(new Teuchos::Array<std::string>(in_names));
2440 paramObj->is_distributed = false;
2441
2442 // register all the scalar parameters, setting initial
2443 for(int i=0;i<in_names.size();i++)
2444 registerScalarParameter(in_names[i],*global_data_->pl,in_values[i]);
2445
2446 paramObj->scalar_value = panzer::ParamVec();
2447 global_data_->pl->fillVector<panzer::Traits::Residual>(*paramObj->names, paramObj->scalar_value);
2448
2449 // build initial condition vector
2450 paramObj->space =
2451 Thyra::locallyReplicatedDefaultSpmdVectorSpace<Scalar>(
2452 rcp(new Teuchos::MpiComm<long int>(lof_->getComm().getRawMpiComm())),paramObj->names->size());
2453
2454 // fill vector with parameter values
2455 Teuchos::ArrayRCP<Scalar> data;
2456 RCP<Thyra::VectorBase<Scalar> > initial_value = Thyra::createMember(paramObj->space);
2457 RCP<Thyra::SpmdVectorBase<Scalar> > vec = rcp_dynamic_cast<Thyra::SpmdVectorBase<Scalar> >(initial_value);
2458 vec->getNonconstLocalData(ptrFromRef(data));
2459 for (unsigned int i=0; i < paramObj->scalar_value.size(); i++)
2460 data[i] = in_values[i];
2461
2462 paramObj->initial_value = initial_value;
2463
2464 return paramObj;
2465}
2466
2467template <typename Scalar>
2468Teuchos::RCP<typename panzer::ModelEvaluator<Scalar>::ParameterObject>
2470createDistributedParameter(const std::string & key,
2471 const Teuchos::RCP<const Thyra::VectorSpaceBase<Scalar> > & vs,
2472 const Teuchos::RCP<const Thyra::VectorBase<Scalar> > & initial,
2473 const Teuchos::RCP<const GlobalIndexer> & ugi) const
2474{
2475 using Teuchos::RCP;
2476 using Teuchos::rcp;
2477
2478 RCP<ParameterObject> paramObj = rcp(new ParameterObject);
2479
2480 paramObj->is_distributed = true;
2481 paramObj->names = rcp(new Teuchos::Array<std::string>());
2482 paramObj->names->push_back(key);
2483 paramObj->space = vs;
2484 paramObj->initial_value = initial;
2485
2486 paramObj->global_indexer = ugi;
2487
2488 return paramObj;
2489}
2490
2491template <typename Scalar>
2492void
2494setParameters(const Thyra::ModelEvaluatorBase::InArgs<Scalar> &inArgs) const
2495{
2496 for(std::size_t i=0; i < parameters_.size(); i++) {
2497
2498 // skip non-scalar parameters (for now)
2499 if(parameters_[i]->is_distributed)
2500 continue;
2501
2502 // set parameter values for given parameter vector for all evaluation types
2503 Teuchos::RCP<const Thyra::VectorBase<Scalar> > p = inArgs.get_p(i);
2504 if (p != Teuchos::null) {
2505 for (unsigned int j=0; j < parameters_[i]->scalar_value.size(); j++) {
2506 parameters_[i]->scalar_value[j].family->setRealValueForAllTypes(Thyra::get_ele(*p,j));
2507 }
2508 }
2509
2510 }
2511}
2512
2513template <typename Scalar>
2514void
2516resetParameters() const
2517{
2518 for(std::size_t i=0; i < parameters_.size(); i++) {
2519
2520 // skip non-scalar parameters (for now)
2521 if(parameters_[i]->is_distributed)
2522 continue;
2523
2524 // Reset each parameter back to its nominal
2525 for (unsigned int j=0; j < parameters_[i]->scalar_value.size(); j++) {
2526 parameters_[i]->scalar_value[j].family->setRealValueForAllTypes(Thyra::get_ele(*(parameters_[i]->initial_value),j));
2527 }
2528
2529 }
2530}
2531
2532#endif // __Panzer_ModelEvaluator_impl_hpp__
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we're performing.
Builder functor used with Sacado::mpl::TemplateManager to construct one panzer::AssemblyEngine<EvalT>...
void addGlobalEvaluationData(const std::string &key, const Teuchos::RCP< GlobalEvaluationData > &ged)
Teuchos::RCP< panzer::LinearObjContainer > ghostedContainer_
Teuchos::RCP< panzer::LinearObjContainer > container_
A PHX::TemplateManager holding one panzer::ClosureModelFactory<EvalT> per evaluation type in Traits::...
virtual void evalModelImpl_basic_dfdp_scalar_fd(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
void setOneTimeDirichletBeta(const Scalar &beta) const
virtual void evalModelImpl_basic_dgdp_scalar(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
void setupAssemblyInArgs(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, panzer::AssemblyEngineInArgs &ae_inargs) const
void setupModel(const Teuchos::RCP< panzer::WorksetContainer > &wc, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const std::vector< panzer::BC > &bcs, const panzer::EquationSetFactory &eqset_factory, const panzer::BCStrategyFactory &bc_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &volume_cm_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &bc_cm_factory, const Teuchos::ParameterList &closure_models, const Teuchos::ParameterList &user_data, bool writeGraph=false, const std::string &graphPrefix="", const Teuchos::ParameterList &me_params=Teuchos::ParameterList())
Thyra::ModelEvaluatorBase::OutArgs< Scalar > createOutArgsImpl() const override
bool required_basic_g(const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Does this set of out args require a simple response?
void evalModel_D2fDp2(int pIndex, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_x, const Teuchos::RCP< Thyra::LinearOpBase< Scalar > > &D2fDp2) const
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_DfDp_op(int i) const override
virtual void evalModelImpl_basic_dgdx(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > f_space_
void buildDistroParamDfDp_RL(const Teuchos::RCP< panzer::WorksetContainer > &wc, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const std::vector< panzer::BC > &bcs, const panzer::EquationSetFactory &eqset_factory, const panzer::BCStrategyFactory &bc_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const Teuchos::ParameterList &closure_models, const Teuchos::ParameterList &user_data, const bool write_graphviz_file=false, const std::string &graphviz_file_prefix="")
Teuchos::RCP< const Thyra::LinearOpWithSolveFactoryBase< Scalar > > get_W_factory() const override
void setParameters(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs) const
Teuchos::RCP< ParameterObject > createDistributedParameter(const std::string &key, const Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > &vs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &initial, const Teuchos::RCP< const GlobalIndexer > &ugi) const
panzer::AssemblyEngine_TemplateManager< panzer::Traits > ae_tm_
virtual void evalModelImpl_basic_dfdp_scalar(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
bool required_basic_dfdp_scalar(const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Are derivatives of the residual with respect to the scalar parameters in the out args?...
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > x_space_
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_p_space(int i) const override
virtual void evalModelImpl_basic_g(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Construct a simple response dicatated by this set of out args.
void evalModel_D2fDx2(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_x, const Teuchos::RCP< Thyra::LinearOpBase< Scalar > > &D2fDx2) const
bool required_basic_dgdx(const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Are their required responses in the out args? DgDx.
bool required_basic_dgdp_distro(const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Are their required responses in the out args? DgDp.
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_x_space() const override
virtual void evalModelImpl(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const override
void evalModel_D2fDpDx(int pIndex, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_x, const Teuchos::RCP< Thyra::LinearOpBase< Scalar > > &D2fDpDx) const
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_f_space() const override
void buildVolumeFieldManagers(const bool value)
virtual void evalModelImpl_basic_dgdp_distro(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
void evalModel_D2gDxDp(int rIndex, int pIndex, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_p, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &D2gDxDp) const
int addDistributedParameter(const std::string &name, const Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > &vs, const Teuchos::RCP< GlobalEvaluationData > &ged, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &initial, const Teuchos::RCP< const GlobalIndexer > &ugi=Teuchos::null)
bool required_basic_dgdp_scalar(const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Are their required responses in the out args? DgDp.
int addParameter(const std::string &name, const Scalar &initial)
Thyra::ModelEvaluatorBase::InArgs< Scalar > getNominalValues() const override
const std::string & get_g_name(int i) const
void buildDistroParamDgDp_RL(const Teuchos::RCP< panzer::WorksetContainer > &wc, const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > &physicsBlocks, const std::vector< panzer::BC > &bcs, const panzer::EquationSetFactory &eqset_factory, const panzer::BCStrategyFactory &bc_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const Teuchos::ParameterList &closure_models, const Teuchos::ParameterList &user_data, const bool write_graphviz_file=false, const std::string &graphviz_file_prefix="")
Teuchos::RCP< const Teuchos::Array< std::string > > get_p_names(int i) const override
Teuchos::ArrayView< const std::string > get_g_names(int i) const override
void applyDirichletBCs(const Teuchos::RCP< Thyra::VectorBase< Scalar > > &x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &f) const
Thyra::ModelEvaluatorBase::InArgs< Scalar > createInArgs() const override
int addFlexibleResponse(const std::string &responseName, const std::vector< WorksetDescriptor > &wkst_desc, const Teuchos::RCP< ResponseMESupportBuilderBase > &builder)
void evalModel_D2gDpDx(int rIndex, int pIndex, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &D2gDpDx) const
void buildBCFieldManagers(const bool value)
Teuchos::RCP< const panzer::LinearObjFactory< panzer::Traits > > lof_
virtual void evalModelImpl_basic_dfdp_distro(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
void evalModel_D2fDxDp(int pIndex, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_p, const Teuchos::RCP< Thyra::LinearOpBase< Scalar > > &D2fDxDp) const
void evalModel_D2gDx2(int rIndex, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &D2gDx2) const
virtual void evalModelImpl_basic(const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Evaluate a simple model, meaning a residual and a jacobian, no fancy stochastic galerkin or multipoin...
Teuchos::RCP< Thyra::LinearOpBase< Scalar > > create_W_op() const override
Teuchos::RCP< panzer::ResponseLibrary< panzer::Traits > > responseLibrary_
void evalModel_D2gDp2(int rIndex, int pIndex, const Thyra::ModelEvaluatorBase::InArgs< Scalar > &inArgs, const Teuchos::RCP< const Thyra::VectorBase< Scalar > > &delta_x, const Teuchos::RCP< Thyra::VectorBase< Scalar > > &D2gDp2) const
bool required_basic_dfdp_distro(const Thyra::ModelEvaluatorBase::OutArgs< Scalar > &outArgs) const
Are derivatives of the residual with respect to the distributed parameters in the out args?...
Teuchos::RCP< const Thyra::VectorSpaceBase< Scalar > > get_g_space(int i) const override
void addNonParameterGlobalEvaluationData(const std::string &name, const Teuchos::RCP< GlobalEvaluationData > &ged)
void initializeNominalValues() const
Initialize the nominal values with good starting conditions.
Teuchos::RCP< ParameterObject > createScalarParameter(const Teuchos::Array< std::string > &names, const Teuchos::Array< Scalar > &in_values) const
Teuchos::RCP< ResponseBase > getResponse(const std::string &responseName) const
void evaluate(const panzer::AssemblyEngineInArgs &input_args)
void addResponsesToInArgs(panzer::AssemblyEngineInArgs &input_args) const
Teuchos::RCP< const LinearObjFactory< panzer::Traits > > cloneWithNewDomain(const LinearObjFactory< panzer::Traits > &lof, const Teuchos::RCP< const GlobalIndexer > &dUgi)
Clone a linear object factory, but using a different domain.
Tpetra::KokkosCompat::KokkosDeviceWrapperNode< PHX::Device > TpetraNodeType
The Kokkos node type used to instantiate all Tpetra objects (Map, MultiVector, CrsGraph,...
Sacado::ScalarParameterVector< panzer::EvaluationTraits > ParamVec
A vector of named scalar parameter entries drawn from a ParamLib, e.g. for use as LOCA continuation/b...
void registerScalarParameter(const std::string name, panzer::ParamLib &pl, double realValue)
Interface for constructing a BCStrategy_TemplateManager.
Allocates and initializes an equation set template manager.
Teuchos::RCP< panzer::ResponseLibrary< panzer::Traits > > dfdp_rl
Teuchos::RCP< const GlobalIndexer > global_indexer
Evaluation type for computing second derivatives, using HessianType as the scalar type....
Evaluation type for computing the residual and its Jacobian, using FadType as the scalar type.
Evaluation type for computing the residual only, using RealType as the scalar type.
Evaluation type for computing directional derivatives (e.g. parameter sensitivities),...
Panzer's specialization of the Phalanx traits class.
PANZER_FADTYPE FadType
Sacado forward-mode AD scalar type used for the Jacobian and Tangent evaluation types.