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.
void addGlobalEvaluationData(const std::string &key, const Teuchos::RCP< GlobalEvaluationData > &ged)
Teuchos::RCP< panzer::LinearObjContainer > ghostedContainer_
Teuchos::RCP< panzer::LinearObjContainer > container_
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
Sacado::ScalarParameterVector< panzer::EvaluationTraits > ParamVec
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
PANZER_FADTYPE FadType