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