Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
main_driver.cpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Panzer: A partial differential equation assembly
5 // engine for strongly coupled complex multiphysics systems
6 // Copyright (2011) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roger P. Pawlowski (rppawlo@sandia.gov) and
39 // Eric C. Cyr (eccyr@sandia.gov)
40 // ***********************************************************************
41 // @HEADER
42 
43 #include "Teuchos_ConfigDefs.hpp"
44 #include "Teuchos_RCP.hpp"
45 #include "Teuchos_TimeMonitor.hpp"
46 #include "Teuchos_DefaultComm.hpp"
47 #include "Teuchos_CommHelpers.hpp"
51 #include "Teuchos_FancyOStream.hpp"
52 #include "Teuchos_oblackholestream.hpp"
53 #include "Teuchos_Assert.hpp"
54 #include "Teuchos_as.hpp"
55 
56 #include "Panzer_NodeType.hpp"
57 
58 #include "Phalanx_KokkosUtilities.hpp"
59 
60 #include "Panzer_ConfigDefs.hpp"
63 #include "Panzer_PauseToAttach.hpp"
66 
67 #ifdef Panzer_BUILD_PAPI_SUPPORT
68 #include "Panzer_PAPI_Counter.hpp"
69 #endif
70 
71 #include "user_app_ClosureModel_Factory_TemplateBuilder.hpp"
72 #include "user_app_EquationSetFactory.hpp"
73 #include "user_app_BCStrategy_Factory.hpp"
77 
78 #include <Ioss_SerializeIO.h>
79 
80 #include <string>
81 #include <iostream>
82 
83 int main(int argc, char *argv[])
84 {
85  PHX::InitializeKokkosDevice();
86 
87  int status = 0;
88 
89  Teuchos::oblackholestream blackhole;
90  Teuchos::GlobalMPISession mpiSession(&argc, &argv, &blackhole);
91 
94  if (mpiSession.getNProc() > 1) {
95  out->setShowProcRank(true);
96  out->setOutputToRootOnly(0);
97  }
98 
99 #ifdef Panzer_BUILD_PAPI_SUPPORT
100  panzer::PAPICounter papi_counter("Panzer: Total Execution", mpiSession.getRank(), MPI_COMM_WORLD);
101  papi_counter.start();
102 #endif
103 
104  try {
105 
106  Teuchos::RCP<Teuchos::Time> total_time =
107  Teuchos::TimeMonitor::getNewTimer("User App: Total Time");
108 
109  Teuchos::TimeMonitor timer(*total_time);
110 
112 
113  // Parse the command line arguments
114  std::string input_file_name = "user_app.xml";
115  int exodus_io_num_procs = 0;
116  bool pauseToAttachOn = false;
117  bool fluxCalculation = false;
118  {
120 
121  clp.setOption("i", &input_file_name, "User_App input xml filename");
122  clp.setOption("exodus-io-num-procs", &exodus_io_num_procs, "Number of processes that can access the file system at the same time to read their portion of a sliced exodus file in parallel. Defaults to 0 - implies all processes for the run can access the file system at the same time.");
123  clp.setOption("pause-to-attach","disable-pause-to-attach", &pauseToAttachOn, "Call pause to attach, default is off.");
124  clp.setOption("flux-calc","disable-flux-calc", &fluxCalculation, "Enable the flux calculation.");
125 
127  clp.parse(argc,argv,&std::cerr);
128 
130  std::runtime_error, "Failed to parse command line!");
131  }
132 
133  if(pauseToAttachOn)
135 
136  TEUCHOS_ASSERT(exodus_io_num_procs <= comm->getSize());
137  if (exodus_io_num_procs != 0)
138  Ioss::SerializeIO::setGroupFactor(exodus_io_num_procs);
139 
140  // Parse the input file and broadcast to other processes
141  Teuchos::RCP<Teuchos::ParameterList> input_params = Teuchos::rcp(new Teuchos::ParameterList("User_App Parameters"));
142  Teuchos::updateParametersFromXmlFileAndBroadcast(input_file_name, input_params.ptr(), *comm);
143 
144  *out << *input_params << std::endl;
145 
146  Teuchos::ParameterList solver_factories = input_params->sublist("Solver Factories");
147  input_params->remove("Solver Factories");
148 
149  // Add in the application specific equation set factory
150  Teuchos::RCP<user_app::MyFactory> eqset_factory = Teuchos::rcp(new user_app::MyFactory);
151 
152  // Add in the application specific closure model factory
153  user_app::MyModelFactory_TemplateBuilder cm_builder;
155  cm_factory.buildObjects(cm_builder);
156 
157  // Add in the application specific bc factory
158  user_app::BCFactory bc_factory;
159 
160  // Create the global data
162 
163  // A GlobalStatistics closure model requires the comm to be set in the user data.
164  input_params->sublist("User Data").set("Comm", comm);
165 
166  // extract and then remove the volume responses
167  Teuchos::ParameterList responses = input_params->sublist("Responses");
168  input_params->remove("Responses");
169 
172 
176  std::vector<Teuchos::RCP<panzer::PhysicsBlock> > physicsBlocks;
178  std::map<int,std::string> responseIndexToName;
179  {
181 
182  me_factory.setParameterList(input_params);
183  me_factory.buildObjects(comm,global_data,eqset_factory,bc_factory,cm_factory);
184 
185  // add a volume response functional for each field
186  for(Teuchos::ParameterList::ConstIterator itr=responses.begin();itr!=responses.end();++itr) {
187  const std::string name = responses.name(itr);
188  TEUCHOS_ASSERT(responses.entry(itr).isList());
189  Teuchos::ParameterList & lst = Teuchos::getValue<Teuchos::ParameterList>(responses.entry(itr));
190 
191 
192  // parameterize the builder
194  builder.comm = MPI_COMM_WORLD; // good enough
195  builder.cubatureDegree = 2;
196  builder.requiresCellIntegral = lst.isType<bool>("Requires Cell Integral") ? lst.get<bool>("Requires Cell Integral"): false;
197  builder.quadPointField = lst.get<std::string>("Field Name");
198 
199  // add the respone
200  std::vector<std::string> eblocks;
201  panzer::StringTokenizer(eblocks,lst.get<std::string>("Element Blocks"),",",true);
202 
203  std::vector<panzer::WorksetDescriptor> wkst_descs;
204  for(std::size_t i=0;i<eblocks.size();i++)
205  wkst_descs.push_back(panzer::blockDescriptor(eblocks[i]));
206 
207  int respIndex = me_factory.addResponse(name,wkst_descs,builder);
208  responseIndexToName[respIndex] = name;
209  }
210 
211  // enusre all the responses are built
212  me_factory.buildResponses(cm_factory);
213 
214  physicsBlocks = me_factory.getPhysicsBlocks();
215  physics = me_factory.getPhysicsModelEvaluator();
216  rLibrary = me_factory.getResponseLibrary();
217  linObjFactory = me_factory.getLinearObjFactory();
218 
219  // Add in the application specific observer factories
220  {
221  // see if field coordinates are required, if so reset the workset container
222  // and set the coordinates to be associated with a field in the mesh
223  bool useCoordinateUpdate = false;
224  for(std::size_t p=0;p<physicsBlocks.size();p++) {
225  if(physicsBlocks[p]->getCoordinateDOFs().size()>0) {
226  useCoordinateUpdate = true;
227  break;
228  }
229  }
230 
231  // Rythmos
233  {
234  rof = Teuchos::rcp(new user_app::RythmosObserverFactory(stkIOResponseLibrary,rLibrary->getWorksetContainer(),useCoordinateUpdate));
235  // me_factory.setRythmosObserverFactory(rof);
236  }
237 
238  // NOX
240  {
241  nof = Teuchos::rcp(new user_app::NOXObserverFactory(stkIOResponseLibrary));
242 
243  Teuchos::RCP<Teuchos::ParameterList> observers_to_build =
244  Teuchos::parameterList(solver_factories.sublist("NOX Observers"));
245 
246  nof->setParameterList(observers_to_build);
247  // me_factory.setNOXObserverFactory(nof);
248  }
249 
250  // solver = me_factory.getResponseOnlyModelEvaluator();
251  solver = me_factory.buildResponseOnlyModelEvaluator(physics,global_data,Teuchos::null,nof.ptr(),rof.ptr());
252  }
253 
254  }
255 
256  // setup outputs to mesh on the stkIOResponseLibrary
258 
259  stkIOResponseLibrary->initialize(*rLibrary);
260 
261  // 1. Register correct aggregator and reserve response - this was done in the appropriate observer object
262 
263  // 2. Build volume field managers
264  {
265  Teuchos::ParameterList user_data(input_params->sublist("User Data"));
266  user_data.set<int>("Workset Size",input_params->sublist("Assembly").get<int>("Workset Size"));
267 
268  stkIOResponseLibrary->buildResponseEvaluators(physicsBlocks,
269  cm_factory,
270  input_params->sublist("Closure Models"),
271  user_data);
272  }
273 
274  // setup outputs to mesh on the fluxResponseLibrary
276 
279 
280  if(fluxCalculation) {
281  fluxResponseLibrary->initialize(*rLibrary);
282 
283  // build high-order flux response
284  {
286  builder.comm = MPI_COMM_WORLD;
287  builder.cubatureDegree = 2;
288 
289  std::vector<panzer::WorksetDescriptor> sidesets;
290  sidesets.push_back(panzer::sidesetVolumeDescriptor("eblock-0_0","left"));
291 
292  fluxResponseLibrary->addResponse("HO-Flux",sidesets,builder);
293  }
294 
295  {
296  Teuchos::ParameterList user_data(input_params->sublist("User Data"));
297  user_data.set<int>("Workset Size",input_params->sublist("Assembly").get<int>("Workset Size"));
298 
299  fluxResponseLibrary->buildResponseEvaluators(physicsBlocks,
300  *eqset_factory,
301  cm_factory,
302  input_params->sublist("Closure Models"),
303  user_data);
304  }
305 
306  {
308  = Teuchos::rcp_dynamic_cast<panzer::ResponseMESupportBase<panzer::Traits::Residual> >(fluxResponseLibrary->getResponse<panzer::Traits::Residual>("HO-Flux"),true);
309 
310  // allocate a vector
311  Teuchos::RCP<Epetra_Vector> vec = Teuchos::rcp(new Epetra_Vector(*resp->getMap()));
312  resp->setVector(vec);
313  }
314  }
315 
317 
318  // solve the system
319  {
320 
321  // Set inputs
322  Thyra::ModelEvaluatorBase::InArgs<double> inArgs = solver->createInArgs();
323  const Thyra::ModelEvaluatorBase::InArgs<double> inArgsNominal = solver->getNominalValues();
324 
325  // Set outputs
326  Thyra::ModelEvaluatorBase::OutArgs<double> outArgs = solver->createOutArgs();
327 
328  // Solution vector is returned as extra respons vector
329  Teuchos::RCP<Thyra::VectorBase<double> > gx = Thyra::createMember(*physics->get_x_space());
330  for(int i=0;i<outArgs.Ng()-1;i++)
331  outArgs.set_g(i,Teuchos::null);
332  outArgs.set_g(outArgs.Ng()-1,gx);
333 
334  // Now, solve the problem and return the responses
335  solver->evalModel(inArgs, outArgs);
336 
337  // get responses if there are any
339  if(physics->Ng()>0) {
340 
341  Thyra::ModelEvaluatorBase::InArgs<double> respInArgs = physics->createInArgs();
342  Thyra::ModelEvaluatorBase::OutArgs<double> respOutArgs = physics->createOutArgs();
343 
344  TEUCHOS_ASSERT(physics->Ng()==respOutArgs.Ng());
345 
346  respInArgs.set_x(gx);
347 
348  // set up response out args
349  for(int i=0;i<respOutArgs.Ng();i++) {
350  Teuchos::RCP<Thyra::VectorBase<double> > response = Thyra::createMember(*physics->get_g_space(i));
351  respOutArgs.set_g(i,response);
352  }
353 
354  // Now, solve the problem and return the responses
355  physics->evalModel(respInArgs, respOutArgs);
356 
357  // loop over out args for printing
358  for(int i=0;i<respOutArgs.Ng();i++) {
359  Teuchos::RCP<Thyra::VectorBase<double> > response = respOutArgs.get_g(i);
360 
361  TEUCHOS_ASSERT(response!=Teuchos::null); // should not be null!
362 
363  *out << "Response Value \"" << responseIndexToName[i] << "\": " << *response << std::endl;
364  }
365  }
366 
367  if(fluxCalculation) {
368  // initialize the assembly container
370  ae_inargs.container_ = linObjFactory->buildLinearObjContainer();
371  ae_inargs.ghostedContainer_ = linObjFactory->buildGhostedLinearObjContainer();
372  ae_inargs.alpha = 0.0;
373  ae_inargs.beta = 1.0;
374  ae_inargs.evaluate_transient_terms = false;
375 
376  // initialize the ghosted container
377  linObjFactory->initializeGhostedContainer(panzer::LinearObjContainer::X,*ae_inargs.ghostedContainer_);
378 
379  const Teuchos::RCP<panzer::EpetraLinearObjContainer> epGlobalContainer
380  = Teuchos::rcp_dynamic_cast<panzer::EpetraLinearObjContainer>(ae_inargs.container_,true);
381  epGlobalContainer->set_x_th(gx);
382 
383  // evaluate current on contacts
384  fluxResponseLibrary->addResponsesToInArgs<panzer::Traits::Residual>(ae_inargs);
385  fluxResponseLibrary->evaluate<panzer::Traits::Residual>(ae_inargs);
386 
387  // output current values
388  *out << "\nFlux values: \n";
389  {
390  std::string currentRespName = "HO-Flux";
391 
393  = Teuchos::rcp_dynamic_cast<panzer::Response_Functional<panzer::Traits::Residual> >(fluxResponseLibrary->getResponse<panzer::Traits::Residual>(currentRespName),true);
394 
395  *out << " " << currentRespName << " = " << resp->value << std::endl;
396  }
397  }
398  }
399  }
400  catch (std::exception& e) {
401  *out << "*********** Caught Exception: Begin Error Report ***********" << std::endl;
402  *out << e.what() << std::endl;
403  *out << "************ Caught Exception: End Error Report ************" << std::endl;
404  status = -1;
405  }
406  catch (std::string& msg) {
407  *out << "*********** Caught Exception: Begin Error Report ***********" << std::endl;
408  *out << msg << std::endl;
409  *out << "************ Caught Exception: End Error Report ************" << std::endl;
410  status = -1;
411  }
412  catch (...) {
413  *out << "*********** Caught Exception: Begin Error Report ***********" << std::endl;
414  *out << "Caught UNKOWN exception" << std::endl;
415  *out << "************ Caught Exception: End Error Report ************" << std::endl;
416  status = -1;
417  }
418 
419  Teuchos::TimeMonitor::summarize(*out,false,true,false);
420 
421 #ifdef Panzer_BUILD_PAPI_SUPPORT
422  papi_counter.stop();
423  papi_counter.report(std::cout);
424 #endif
425 
426  if (status == 0)
427  *out << "panzer::MainDriver run completed." << std::endl;
428 
429  PHX::FinalizeKokkosDevice();
430 
431  return status;
432 }
const std::string & name() const
ConstIterator end() const
int addResponse(const std::string &responseName, const std::vector< panzer::WorksetDescriptor > &wkstDesc, const BuilderT &builder)
basic_FancyOStream & setShowProcRank(const bool showProcRank)
T & get(const std::string &name, T def_value)
virtual void set_x_th(const Teuchos::RCP< Thyra::VectorBase< double > > &in)
ParameterList & set(std::string const &name, T const &value, std::string const &docString="", RCP< const ParameterEntryValidator > const &validator=null)
void buildObjects(const Teuchos::RCP< const Teuchos::Comm< int > > &comm, const Teuchos::RCP< panzer::GlobalData > &global_data, const Teuchos::RCP< const panzer::EquationSetFactory > &eqset_factory, const panzer::BCStrategyFactory &bc_factory, const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, bool meConstructionOn=true)
Builds the model evaluators for a panzer assembly.
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
void buildResponses(const panzer::ClosureModelFactory_TemplateManager< panzer::Traits > &cm_factory, const bool write_graphviz_file=false, const std::string &graphviz_file_prefix="")
Teuchos::RCP< panzer::GlobalData > createGlobalData(bool build_default_os, int print_process)
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Teuchos::RCP< panzer::LinearObjContainer > ghostedContainer_
Teuchos::RCP< panzer::GlobalData > global_data
const std::vector< Teuchos::RCP< panzer::PhysicsBlock > > & getPhysicsBlocks() const
static RCP< Time > getNewTimer(const std::string &name)
Teuchos::RCP< panzer::LinearObjFactory< panzer::Traits > > getLinearObjFactory() const
Get linear object factory used to build model evaluator.
Teuchos::RCP< panzer::LinearObjContainer > container_
bool remove(std::string const &name, bool throwIfNotExists=true)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
static void summarize(Ptr< const Comm< int > > comm, std::ostream &out=std::cout, const bool alwaysWriteLocal=false, const bool writeGlobalStats=true, const bool writeZeroTimers=true, const ECounterSetOp setOp=Intersection, const std::string &filter="", const bool ignoreZeroTimers=false)
Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > buildResponseOnlyModelEvaluator(const Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > &thyra_me, const Teuchos::RCP< panzer::GlobalData > &global_data, const Teuchos::RCP< Piro::RythmosSolver< ScalarT > > rythmosSolver=Teuchos::null, const Teuchos::Ptr< const panzer_stk_classic::NOXObserverFactory > &in_nox_observer_factory=Teuchos::null, const Teuchos::Ptr< const panzer_stk_classic::RythmosObserverFactory > &in_rythmos_observer_factory=Teuchos::null)
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
WorksetDescriptor sidesetVolumeDescriptor(const std::string &eBlock, const std::string &sideset)
Ptr< T > ptr() const
params_t::ConstIterator ConstIterator
EParseCommandLineReturn parse(int argc, char *argv[], std::ostream *errout=&std::cerr) const
ConstIterator begin() const
basic_FancyOStream & setOutputToRootOnly(const int rootRank)
const ParameterEntry & entry(ConstIterator i) const
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
Teuchos::RCP< const Teuchos::Comm< int > > comm
void pauseToAttach(MPI_Comm mpicomm)
WorksetDescriptor blockDescriptor(const std::string &eBlock)
ParameterList & sublist(const std::string &name, bool mustAlreadyExist=false, const std::string &docString="")
void StringTokenizer(std::vector< std::string > &tokens, const std::string &str, const std::string delimiters, bool trim)
Tokenize a string, put tokens in a vector.
int main(int argc, char *argv[])
Definition: main_driver.cpp:83
#define TEUCHOS_ASSERT(assertion_test)
Teuchos::RCP< Thyra::ModelEvaluator< ScalarT > > getPhysicsModelEvaluator()
void setParameterList(Teuchos::RCP< Teuchos::ParameterList > const &paramList)
Teuchos::RCP< panzer::ResponseLibrary< panzer::Traits > > getResponseLibrary()