Panzer  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Panzer_BlockedEpetraLinearObjFactory_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_BlockedEpetraLinearObjFactory_impl_hpp__
12 #define __Panzer_BlockedEpetraLinearObjFactory_impl_hpp__
13 
14 
15 // Epetra
16 #include "Epetra_CrsMatrix.h"
17 #include "Epetra_MpiComm.h"
18 #include "Epetra_MultiVector.h"
19 #include "Epetra_Vector.h"
20 
21 // EpetraExt
22 #include "EpetraExt_VectorIn.h"
23 #include "EpetraExt_VectorOut.h"
24 
25 // Panzer
31 #include "Panzer_HashUtils.hpp"
32 #include "Panzer_GlobalIndexer.hpp"
33 
34 // Thyra
35 #include "Thyra_DefaultBlockedLinearOp.hpp"
36 #include "Thyra_DefaultProductVector.hpp"
37 #include "Thyra_DefaultProductVectorSpace.hpp"
38 #include "Thyra_EpetraLinearOp.hpp"
39 #include "Thyra_EpetraThyraWrappers.hpp"
40 #include "Thyra_get_Epetra_Operator.hpp"
41 #include "Thyra_SpmdVectorBase.hpp"
42 #include "Thyra_VectorStdOps.hpp"
43 
44 using Teuchos::RCP;
45 
46 namespace panzer {
47 
48 // ************************************************************
49 // class BlockedEpetraLinearObjFactory
50 // ************************************************************
51 
52 template <typename Traits,typename LocalOrdinalT>
55  const Teuchos::RCP<const GlobalIndexer> & gidProvider,
56  bool useDiscreteAdjoint)
57  : useColGidProviders_(false), eComm_(Teuchos::null)
58  , rawMpiComm_(comm->getRawMpiComm())
59  , useDiscreteAdjoint_(useDiscreteAdjoint)
60 {
63 
65 
66  makeRoomForBlocks(rowDOFManagerContainer_->getFieldBlocks());
67 
68  // build and register the gather/scatter evaluators with
69  // the base class.
70  this->buildGatherScatterEvaluators(*this);
71 
73 }
74 
75 template <typename Traits,typename LocalOrdinalT>
78  const Teuchos::RCP<const GlobalIndexer> & gidProvider,
79  const Teuchos::RCP<const GlobalIndexer> & colGidProvider,
80  bool useDiscreteAdjoint)
81  : eComm_(Teuchos::null)
82  , rawMpiComm_(comm->getRawMpiComm())
83  , useDiscreteAdjoint_(useDiscreteAdjoint)
84 {
87 
89 
90  useColGidProviders_ = true;
91 
92  makeRoomForBlocks(rowDOFManagerContainer_->getFieldBlocks(),colDOFManagerContainer_->getFieldBlocks());
93 
94  // build and register the gather/scatter evaluators with
95  // the base class.
96  this->buildGatherScatterEvaluators(*this);
97 
99 }
100 
101 template <typename Traits,typename LocalOrdinalT>
103 { }
104 
105 // LinearObjectFactory functions
107 
108 template <typename Traits,typename LocalOrdinalT>
109 void
111 readVector(const std::string & identifier,LinearObjContainer & loc,int id) const
112 {
113  using Teuchos::RCP;
114  using Teuchos::rcp_dynamic_cast;
115  using Teuchos::dyn_cast;
117 
119 
120  // extract the vector from linear object container
122  switch(id) {
124  vec = eloc.get_x();
125  break;
127  vec = eloc.get_dxdt();
128  break;
130  vec = eloc.get_f();
131  break;
132  default:
133  TEUCHOS_ASSERT(false);
134  break;
135  };
136 
137  int blockRows = this->getBlockRowCount();
138  RCP<ProductVectorBase<double> > b_vec = Thyra::nonconstProductVectorBase(vec);
139 
140  // convert to Epetra then write out each vector to file
141  for(int i=0;i<blockRows;i++) {
142  RCP<Thyra::VectorBase<double> > x = b_vec->getNonconstVectorBlock(i);
143  RCP<Epetra_Vector> ex = Thyra::get_Epetra_Vector(*getMap(i),x);
144 
145  // build the file name from the identifier
146  std::stringstream ss;
147  ss << identifier << "-" << i << ".mm";
148 
149  // read in vector (wow the MM to Vector is a poorly designed interface!)
150  Epetra_Vector * ptr_ex = 0;
151  TEUCHOS_ASSERT(0==EpetraExt::MatrixMarketFileToVector(ss.str().c_str(),*getMap(i),ptr_ex));
152 
153  *ex = *ptr_ex;
154  delete ptr_ex;
155  }
156 }
157 
158 template <typename Traits,typename LocalOrdinalT>
159 void
161 writeVector(const std::string & identifier,const LinearObjContainer & loc,int id) const
162 {
163  using Teuchos::RCP;
164  using Teuchos::rcp_dynamic_cast;
165  using Teuchos::dyn_cast;
167 
169 
170  // extract the vector from linear object container
172  switch(id) {
174  vec = eloc.get_x();
175  break;
177  vec = eloc.get_dxdt();
178  break;
180  vec = eloc.get_f();
181  break;
182  default:
183  TEUCHOS_ASSERT(false);
184  break;
185  };
186 
187  int blockRows = this->getBlockRowCount();
188  RCP<const ProductVectorBase<double> > b_vec = Thyra::productVectorBase(vec);
189 
190  // convert to Epetra then write out each vector to file
191  for(int i=0;i<blockRows;i++) {
192  RCP<const Thyra::VectorBase<double> > x = b_vec->getVectorBlock(i);
193  RCP<const Epetra_Vector> ex = Thyra::get_Epetra_Vector(*getMap(i),x);
194 
195  // build the file name from the identifier
196  std::stringstream ss;
197  ss << identifier << "-" << i << ".mm";
198 
199  // write out vector
200  TEUCHOS_ASSERT(0==EpetraExt::VectorToMatrixMarketFile(ss.str().c_str(),*ex));
201  }
202 }
203 
204 template <typename Traits,typename LocalOrdinalT>
206 {
207  // if a "single field" DOFManager is used
208  if(!rowDOFManagerContainer_->containsBlockedDOFManager() && !colDOFManagerContainer_->containsBlockedDOFManager()) {
209  Teuchos::RCP<EpetraLinearObjContainer> container = Teuchos::rcp(new EpetraLinearObjContainer(getColMap(0),getMap(0)));
210 
211  return container;
212  }
213 
214  std::vector<Teuchos::RCP<const Epetra_Map> > blockMaps;
215  std::size_t blockDim = getBlockRowCount();
216  for(std::size_t i=0;i<blockDim;i++)
217  blockMaps.push_back(getMap(i));
218 
220  container->setMapsForBlocks(blockMaps);
221 
222  return container;
223 }
224 
225 template <typename Traits,typename LocalOrdinalT>
227 {
228  // if a "single field" DOFManager is used
229  if(!rowDOFManagerContainer_->containsBlockedDOFManager() && !colDOFManagerContainer_->containsBlockedDOFManager()) {
230  Teuchos::RCP<EpetraLinearObjContainer> container = Teuchos::rcp(new EpetraLinearObjContainer(getGhostedColMap(0),getGhostedMap(0)));
231 
232  return container;
233  }
234 
235  std::vector<Teuchos::RCP<const Epetra_Map> > blockMaps;
236  std::size_t blockDim = getBlockRowCount();
237  for(std::size_t i=0;i<blockDim;i++)
238  blockMaps.push_back(getGhostedMap(i));
239 
241  container->setMapsForBlocks(blockMaps);
242 
243  return container;
244 }
245 
246 template <typename Traits,typename LocalOrdinalT>
248  LinearObjContainer & out,int mem) const
249 {
250  using Teuchos::is_null;
251 
252  typedef LinearObjContainer LOC;
253  typedef BlockedEpetraLinearObjContainer BLOC;
254 
255  if( !rowDOFManagerContainer_->containsBlockedDOFManager()
256  && !colDOFManagerContainer_->containsBlockedDOFManager()) {
259 
260  // Operations occur if the GLOBAL container has the correct targets!
261  // Users set the GLOBAL continer arguments
262  if ( !is_null(e_in.get_x()) && !is_null(e_out.get_x()) && ((mem & LOC::X)==LOC::X))
263  globalToGhostEpetraVector(0,*e_in.get_x(),*e_out.get_x(),true);
264 
265  if ( !is_null(e_in.get_dxdt()) && !is_null(e_out.get_dxdt()) && ((mem & LOC::DxDt)==LOC::DxDt))
266  globalToGhostEpetraVector(0,*e_in.get_dxdt(),*e_out.get_dxdt(),true);
267 
268  if ( !is_null(e_in.get_f()) && !is_null(e_out.get_f()) && ((mem & LOC::F)==LOC::F))
269  globalToGhostEpetraVector(0,*e_in.get_f(),*e_out.get_f(),false);
270  }
271  else {
272  const BLOC & b_in = Teuchos::dyn_cast<const BLOC>(in);
273  BLOC & b_out = Teuchos::dyn_cast<BLOC>(out);
274 
275  // Operations occur if the GLOBAL container has the correct targets!
276  // Users set the GLOBAL continer arguments
277  if ( !is_null(b_in.get_x()) && !is_null(b_out.get_x()) && ((mem & LOC::X)==LOC::X))
278  globalToGhostThyraVector(b_in.get_x(),b_out.get_x(),true);
279 
280  if ( !is_null(b_in.get_dxdt()) && !is_null(b_out.get_dxdt()) && ((mem & LOC::DxDt)==LOC::DxDt))
281  globalToGhostThyraVector(b_in.get_dxdt(),b_out.get_dxdt(),true);
282 
283  if ( !is_null(b_in.get_f()) && !is_null(b_out.get_f()) && ((mem & LOC::F)==LOC::F))
284  globalToGhostThyraVector(b_in.get_f(),b_out.get_f(),false);
285  }
286 }
287 
288 template <typename Traits,typename LocalOrdinalT>
290  LinearObjContainer & out,int mem) const
291 {
292  using Teuchos::is_null;
293 
294  typedef LinearObjContainer LOC;
295  typedef BlockedEpetraLinearObjContainer BLOC;
296 
297  if( !rowDOFManagerContainer_->containsBlockedDOFManager()
298  && !colDOFManagerContainer_->containsBlockedDOFManager()) {
301 
302  // Operations occur if the GLOBAL container has the correct targets!
303  // Users set the GLOBAL continer arguments
304  if ( !is_null(e_in.get_x()) && !is_null(e_out.get_x()) && ((mem & LOC::X)==LOC::X))
305  ghostToGlobalEpetraVector(0,*e_in.get_x(),*e_out.get_x(),true);
306 
307  if ( !is_null(e_in.get_f()) && !is_null(e_out.get_f()) && ((mem & LOC::F)==LOC::F))
308  ghostToGlobalEpetraVector(0,*e_in.get_f(),*e_out.get_f(),false);
309 
310  if ( !is_null(e_in.get_A()) && !is_null(e_out.get_A()) && ((mem & LOC::Mat)==LOC::Mat))
311  ghostToGlobalEpetraMatrix(0,*e_in.get_A(),*e_out.get_A());
312  }
313  else {
314  const BLOC & b_in = Teuchos::dyn_cast<const BLOC>(in);
315  BLOC & b_out = Teuchos::dyn_cast<BLOC>(out);
316 
317  // Operations occur if the GLOBAL container has the correct targets!
318  // Users set the GLOBAL continer arguments
319  if ( !is_null(b_in.get_x()) && !is_null(b_out.get_x()) && ((mem & LOC::X)==LOC::X))
320  ghostToGlobalThyraVector(b_in.get_x(),b_out.get_x(),true);
321 
322  if ( !is_null(b_in.get_f()) && !is_null(b_out.get_f()) && ((mem & LOC::F)==LOC::F))
323  ghostToGlobalThyraVector(b_in.get_f(),b_out.get_f(),false);
324 
325  if ( !is_null(b_in.get_A()) && !is_null(b_out.get_A()) && ((mem & LOC::Mat)==LOC::Mat))
326  ghostToGlobalThyraMatrix(*b_in.get_A(),*b_out.get_A());
327  }
328 }
329 
330 template <typename Traits,typename LocalOrdinalT>
333  const LinearObjContainer & globalBCRows,
334  LinearObjContainer & ghostedObjs,
335  bool zeroVectorRows, bool adjustX) const
336 {
337  typedef ThyraObjContainer<double> TOC;
338 
339  using Teuchos::RCP;
340  using Teuchos::rcp_dynamic_cast;
341  using Thyra::LinearOpBase;
342  using Thyra::PhysicallyBlockedLinearOpBase;
343  using Thyra::VectorBase;
345  using Thyra::get_Epetra_Vector;
346  using Thyra::get_Epetra_Operator;
347 
348  int rBlockDim = getBlockRowCount();
349  int cBlockDim = getBlockColCount();
350 
351  // first cast to block LOCs
352  const TOC & b_localBCRows = Teuchos::dyn_cast<const TOC>(localBCRows);
353  const TOC & b_globalBCRows = Teuchos::dyn_cast<const TOC>(globalBCRows);
354  TOC & b_ghosted = Teuchos::dyn_cast<TOC>(ghostedObjs);
355 
356  TEUCHOS_ASSERT(b_localBCRows.get_f_th()!=Teuchos::null);
357  TEUCHOS_ASSERT(b_globalBCRows.get_f_th()!=Teuchos::null);
358 
359  // cast each component as needed to their product form
360  RCP<PhysicallyBlockedLinearOpBase<double> > A = rcp_dynamic_cast<PhysicallyBlockedLinearOpBase<double> >(b_ghosted.get_A_th());
361  if(A==Teuchos::null && b_ghosted.get_A_th()!=Teuchos::null) {
362  // assume it isn't physically blocked, for convenience physically block it
363  A = rcp_dynamic_cast<PhysicallyBlockedLinearOpBase<double> >(Thyra::nonconstBlock1x1(b_ghosted.get_A_th()));
364  }
365 
366  RCP<ProductVectorBase<double> > f = b_ghosted.get_f_th()==Teuchos::null
367  ? Teuchos::null
368  : Thyra::castOrCreateNonconstProductVectorBase(b_ghosted.get_f_th());
369  RCP<ProductVectorBase<double> > local_bcs = b_localBCRows.get_f_th()==Teuchos::null
370  ? Teuchos::null
371  : Thyra::castOrCreateNonconstProductVectorBase(b_localBCRows.get_f_th());
372  RCP<ProductVectorBase<double> > global_bcs = b_globalBCRows.get_f_th()==Teuchos::null
373  ? Teuchos::null
374  : Thyra::castOrCreateNonconstProductVectorBase(b_globalBCRows.get_f_th());
375 
376  if(adjustX) f = Thyra::castOrCreateNonconstProductVectorBase(b_ghosted.get_x_th());
377 
378  // sanity check!
379  if(A!=Teuchos::null) TEUCHOS_ASSERT(A->productRange()->numBlocks()==rBlockDim);
380  if(A!=Teuchos::null) TEUCHOS_ASSERT(A->productDomain()->numBlocks()==cBlockDim);
381  if(f!=Teuchos::null) TEUCHOS_ASSERT(f->productSpace()->numBlocks()==rBlockDim);
382  TEUCHOS_ASSERT(local_bcs->productSpace()->numBlocks()==rBlockDim);
383  TEUCHOS_ASSERT(global_bcs->productSpace()->numBlocks()==rBlockDim);
384 
385  for(int i=0;i<rBlockDim;i++) {
386  // grab epetra vector
387  RCP<const Epetra_Vector> e_local_bcs = get_Epetra_Vector(*getGhostedMap(i),local_bcs->getVectorBlock(i));
388  RCP<const Epetra_Vector> e_global_bcs = get_Epetra_Vector(*getGhostedMap(i),global_bcs->getVectorBlock(i));
389 
390  // pull out epetra values
391  RCP<VectorBase<double> > th_f = (f==Teuchos::null) ? Teuchos::null : f->getNonconstVectorBlock(i);
392  RCP<Epetra_Vector> e_f;
393  if(th_f==Teuchos::null)
394  e_f = Teuchos::null;
395  else
396  e_f = get_Epetra_Vector(*getGhostedMap(i),th_f);
397 
398  for(int j=0;j<cBlockDim;j++) {
399 
400  // pull out epetra values
401  RCP<LinearOpBase<double> > th_A = (A== Teuchos::null)? Teuchos::null : A->getNonconstBlock(i,j);
402 
403  // don't do anyting if opertor is null
405  if(th_A==Teuchos::null)
406  e_A = Teuchos::null;
407  else
408  e_A = rcp_dynamic_cast<Epetra_CrsMatrix>(get_Epetra_Operator(*th_A),true);
409 
410  // adjust Block operator
411  adjustForDirichletConditions(*e_local_bcs,*e_global_bcs,e_f.ptr(),e_A.ptr(),zeroVectorRows);
412 
413  e_f = Teuchos::null; // this is so we only adjust it once on the first pass
414  }
415  }
416 }
417 
418 template <typename Traits,typename LocalOrdinalT>
421  const Epetra_Vector & global_bcs,
422  const Teuchos::Ptr<Epetra_Vector> & f,
424  bool zeroVectorRows) const
425 {
426  if(f==Teuchos::null && A==Teuchos::null)
427  return;
428 
429  TEUCHOS_ASSERT(local_bcs.MyLength()==global_bcs.MyLength());
430  for(int i=0;i<local_bcs.MyLength();i++) {
431  if(global_bcs[i]==0.0)
432  continue;
433 
434  int numEntries = 0;
435  double * values = 0;
436  int * indices = 0;
437 
438  if(local_bcs[i]==0.0 || zeroVectorRows) {
439  // this boundary condition was NOT set by this processor
440 
441  // if they exist put 0.0 in each entry
442  if(!Teuchos::is_null(f))
443  (*f)[i] = 0.0;
444  if(!Teuchos::is_null(A)) {
445  A->ExtractMyRowView(i,numEntries,values,indices);
446  for(int c=0;c<numEntries;c++)
447  values[c] = 0.0;
448  }
449  }
450  else {
451  // this boundary condition was set by this processor
452 
453  double scaleFactor = global_bcs[i];
454 
455  // if they exist scale linear objects by scale factor
456  if(!Teuchos::is_null(f))
457  (*f)[i] /= scaleFactor;
458  if(!Teuchos::is_null(A)) {
459  A->ExtractMyRowView(i,numEntries,values,indices);
460  for(int c=0;c<numEntries;c++)
461  values[c] /= scaleFactor;
462  }
463  }
464  }
465 }
466 
467 template <typename Traits,typename LocalOrdinalT>
470  LinearObjContainer & result) const
471 {
472  using Teuchos::RCP;
473  using Teuchos::rcp_dynamic_cast;
474  using Teuchos::dyn_cast;
475 
476  typedef Thyra::ProductVectorBase<double> PVector;
477 
478  const ThyraObjContainer<double> & th_counter = dyn_cast<const ThyraObjContainer<double> >(counter);
480 
481  RCP<const PVector> count = Thyra::castOrCreateProductVectorBase(th_counter.get_f_th().getConst());
482  RCP<const PVector> f_in = Thyra::castOrCreateProductVectorBase(th_counter.get_f_th().getConst());
483  RCP<PVector> f_out = Thyra::castOrCreateNonconstProductVectorBase(th_result.get_f_th());
484 
485  int rBlockDim = getBlockRowCount();
486  for(int i=0;i<rBlockDim;i++) {
487 
488  Teuchos::ArrayRCP<const double> count_array,f_in_array;
489  Teuchos::ArrayRCP<double> f_out_array;
490 
491  rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(count->getVectorBlock(i),true)->getLocalData(Teuchos::ptrFromRef(count_array));
492  rcp_dynamic_cast<const Thyra::SpmdVectorBase<double> >(f_in->getVectorBlock(i),true)->getLocalData(Teuchos::ptrFromRef(f_in_array));
493  rcp_dynamic_cast<Thyra::SpmdVectorBase<double> >(f_out->getNonconstVectorBlock(i),true)->getNonconstLocalData(Teuchos::ptrFromRef(f_out_array));
494 
495  TEUCHOS_ASSERT(count_array.size()==f_in_array.size());
496  TEUCHOS_ASSERT(count_array.size()==f_out_array.size());
497 
498  for(Teuchos::ArrayRCP<double>::size_type j=0;j<count_array.size();++j) {
499  if(count_array[j]!=0.0)
500  f_out_array[j] = f_in_array[j];
501  }
502  }
503 }
504 
506 //
507 // buildReadOnlyDomainContainer()
508 //
510 template<typename Traits, typename LocalOrdinalT>
514 {
515  using std::vector;
516  using Teuchos::RCP;
517  using Teuchos::rcp;
521 
522  // If a "single field" DOFManager is used, return a single
523  // EpetraVector_ReadOnly_GlobalEvaluationData.
524  if (not colDOFManagerContainer_->containsBlockedDOFManager())
525  {
526  auto ged = rcp(new EVROGED);
527  ged->initialize(getGhostedColImport2(0), getGhostedColMap2(0),
528  getColMap(0));
529  return ged;
530  } // end if a "single field" DOFManager is used
531 
532  // Otherwise, return a BlockedVector_ReadOnly_GlobalEvaluationData.
533  vector<RCP<ROVGED>> gedBlocks;
534  for (int i(0); i < getBlockColCount(); ++i)
535  {
536  auto vecGed = rcp(new EVROGED);
537  vecGed->initialize(getGhostedColImport2(i), getGhostedColMap2(i),
538  getColMap(i));
539  gedBlocks.push_back(vecGed);
540  } // end loop over the blocks
541  auto ged = rcp(new BVROGED);
542  ged->initialize(getGhostedThyraDomainSpace2(), getThyraDomainSpace(),
543  gedBlocks);
544  return ged;
545 } // end of buildReadOnlyDomainContainer()
546 
548 //
549 // buildWriteDomainContainer()
550 //
552 template<typename Traits, typename LocalOrdinalT>
556 {
557  using std::vector;
558  using Teuchos::RCP;
559  using Teuchos::rcp;
563 
564  // If a "single field" DOFManager is used, return a single
565  // EpetraVector_Write_GlobalEvaluationData.
566  if (not colDOFManagerContainer_->containsBlockedDOFManager())
567  {
568  auto ged = rcp(new EVWGED);
569  ged->initialize(getGhostedColExport2(0), getGhostedColMap2(0),
570  getColMap(0));
571  return ged;
572  } // end if a "single field" DOFManager is used
573 
574  // Otherwise, return a BlockedVector_Write_GlobalEvaluationData.
575  vector<RCP<WVGED>> gedBlocks;
576  for (int i(0); i < getBlockColCount(); ++i)
577  {
578  auto vecGed = rcp(new EVWGED);
579  vecGed->initialize(getGhostedColExport2(i), getGhostedColMap2(i),
580  getColMap(i));
581  gedBlocks.push_back(vecGed);
582  } // end loop over the blocks
583  auto ged = rcp(new BVWGED);
584  ged->initialize(getGhostedThyraDomainSpace2(), getThyraDomainSpace(),
585  gedBlocks);
586  return ged;
587 } // end of buildWriteDomainContainer()
588 
589 template <typename Traits,typename LocalOrdinalT>
591 getComm() const
592 {
593  return *tComm_;
594 }
595 
596 template <typename Traits,typename LocalOrdinalT>
599 {
600  typedef ThyraObjContainer<double> TOC;
601 
602  TOC & toc = Teuchos::dyn_cast<TOC>(loc);
603  initializeContainer_internal(mem,toc);
604 }
605 
606 template <typename Traits,typename LocalOrdinalT>
609 {
610  typedef LinearObjContainer LOC;
611  typedef ThyraObjContainer<double> TOC;
612 
613  TOC & toc = Teuchos::dyn_cast<TOC>(loc);
614  initializeGhostedContainer_internal(mem,toc);
615 
616  if(rowDOFManagerContainer_->containsBlockedDOFManager()) {
617  typedef BlockedEpetraLinearObjContainer BLOC;
618 
619  BLOC & bloc = Teuchos::dyn_cast<BLOC>(loc);
620 
621  if((mem & LOC::F) == LOC::F)
622  bloc.setRequiresDirichletAdjustment(true);
623 
624  if((mem & LOC::Mat) == LOC::Mat)
625  bloc.setRequiresDirichletAdjustment(true);
626  }
627  else {
629 
630  if((mem & LOC::F) == LOC::F)
632 
633  if((mem & LOC::Mat) == LOC::Mat)
635  }
636 }
637 
638 // Generic methods
640 
641 template <typename Traits,typename LocalOrdinalT>
644 {
645  typedef LinearObjContainer LOC;
646 
647  loc.clear();
648 
649  if((mem & LOC::X) == LOC::X)
650  loc.set_x_th(getThyraDomainVector());
651 
652  if((mem & LOC::DxDt) == LOC::DxDt)
653  loc.set_dxdt_th(getThyraDomainVector());
654 
655  if((mem & LOC::F) == LOC::F)
656  loc.set_f_th(getThyraRangeVector());
657 
658  if((mem & LOC::Mat) == LOC::Mat)
659  loc.set_A_th(getThyraMatrix());
660 }
661 
662 template <typename Traits,typename LocalOrdinalT>
665 {
666  typedef LinearObjContainer LOC;
667 
668  loc.clear();
669 
670  if((mem & LOC::X) == LOC::X)
671  loc.set_x_th(getGhostedThyraDomainVector());
672 
673  if((mem & LOC::DxDt) == LOC::DxDt)
674  loc.set_dxdt_th(getGhostedThyraDomainVector());
675 
676  if((mem & LOC::F) == LOC::F)
677  loc.set_f_th(getGhostedThyraRangeVector());
678 
679  if((mem & LOC::Mat) == LOC::Mat)
680  loc.set_A_th(getGhostedThyraMatrix());
681 }
682 
683 template <typename Traits,typename LocalOrdinalT>
685 addExcludedPair(int rowBlock,int colBlock)
686 {
687  excludedPairs_.insert(std::make_pair(rowBlock,colBlock));
688 }
689 
690 template <typename Traits,typename LocalOrdinalT>
692 addExcludedPairs(const std::vector<std::pair<int,int> > & exPairs)
693 {
694  for(std::size_t i=0;i<exPairs.size();i++)
695  excludedPairs_.insert(exPairs[i]);
696 }
697 
698 template <typename Traits,typename LocalOrdinalT>
700 getGlobalIndexer(int i) const
701 {
702  return rowDOFManagerContainer_->getFieldDOFManagers()[i];
703 }
704 
705 template <typename Traits,typename LocalOrdinalT>
708 {
709  return colDOFManagerContainer_->getFieldDOFManagers()[i];
710 }
711 
713 //
714 // makeRoomForBlocks()
715 //
717 template<typename Traits, typename LocalOrdinalT>
718 void
721  std::size_t blockCnt,
722  std::size_t colBlockCnt)
723 {
724  maps_.resize(blockCnt);
725  ghostedMaps_.resize(blockCnt);
726  ghostedMaps2_.resize(blockCnt);
727  importers_.resize(blockCnt);
728  importers2_.resize(blockCnt);
729  exporters_.resize(blockCnt);
730  if (colBlockCnt > 0)
731  {
732  colMaps_.resize(colBlockCnt);
733  colGhostedMaps_.resize(colBlockCnt);
734  colGhostedMaps2_.resize(colBlockCnt);
735  colImporters_.resize(colBlockCnt);
736  colImporters2_.resize(colBlockCnt);
737  colExporters_.resize(colBlockCnt);
738  } // end if (colBlockCnt > 0)
739 } // end of makeRoomForBlocks()
740 
741 // Thyra methods
743 
744 template <typename Traits,typename LocalOrdinalT>
747 {
748  if(domainSpace_==Teuchos::null) {
749  if(colDOFManagerContainer_->containsBlockedDOFManager()) {
750  // loop over all vectors and build the vector space
751  std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<double> > > vsArray;
752  for(int i=0;i<getBlockColCount();i++)
753  vsArray.push_back(Thyra::create_VectorSpace(getColMap(i)));
754 
755  domainSpace_ = Thyra::productVectorSpace<double>(vsArray);
756  }
757  else {
758  // the domain space is not blocked (just an SPMD vector), build it from
759  // the zeroth column
760  domainSpace_ = Thyra::create_VectorSpace(getColMap(0));
761  }
762  }
763 
764  return domainSpace_;
765 }
766 
767 template <typename Traits,typename LocalOrdinalT>
770 {
771  if(rangeSpace_==Teuchos::null) {
772  if(rowDOFManagerContainer_->containsBlockedDOFManager()) {
773  // loop over all vectors and build the vector space
774  std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<double> > > vsArray;
775  for(int i=0;i<getBlockRowCount();i++)
776  vsArray.push_back(Thyra::create_VectorSpace(getMap(i)));
777 
778  rangeSpace_ = Thyra::productVectorSpace<double>(vsArray);
779  }
780  else {
781  // the range space is not blocked (just an SPMD vector), build it from
782  // the zeroth row
783  rangeSpace_ = Thyra::create_VectorSpace(getMap(0));
784  }
785  }
786 
787  return rangeSpace_;
788 }
789 
790 template <typename Traits,typename LocalOrdinalT>
793 {
795  Thyra::createMember<double>(*getThyraDomainSpace());
796  Thyra::assign(vec.ptr(),0.0);
797 
798  return vec;
799 }
800 
801 template <typename Traits,typename LocalOrdinalT>
804 {
806  Thyra::createMember<double>(*getThyraRangeSpace());
807  Thyra::assign(vec.ptr(),0.0);
808 
809  return vec;
810 }
811 
812 template <typename Traits,typename LocalOrdinalT>
815 {
816  // return a flat epetra matrix
817  if(!rowDOFManagerContainer_->containsBlockedDOFManager() &&
818  !colDOFManagerContainer_->containsBlockedDOFManager()) {
819  return Thyra::nonconstEpetraLinearOp(getEpetraMatrix(0,0));
820  }
821 
822  Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<double> > blockedOp = Thyra::defaultBlockedLinearOp<double>();
823 
824  // get the block dimension
825  std::size_t rBlockDim = getBlockRowCount();
826  std::size_t cBlockDim = getBlockColCount();
827 
828  // this operator will be square
829  blockedOp->beginBlockFill(rBlockDim,cBlockDim);
830 
831  // loop over each block
832  for(std::size_t i=0;i<rBlockDim;i++) {
833  for(std::size_t j=0;j<cBlockDim;j++) {
834  if(excludedPairs_.find(std::make_pair(i,j))==excludedPairs_.end()) {
835  // build (i,j) block matrix and add it to blocked operator
836  Teuchos::RCP<Thyra::LinearOpBase<double> > block = Thyra::nonconstEpetraLinearOp(getEpetraMatrix(i,j));
837  blockedOp->setNonconstBlock(i,j,block);
838  }
839  }
840  }
841 
842  // all done
843  blockedOp->endBlockFill();
844 
845  return blockedOp;
846 }
847 
849 //
850 // getGhostedThyraDomainSpace()
851 //
853 template<typename Traits, typename LocalOrdinalT>
857 {
858  using std::vector;
859  using Teuchos::RCP;
860  using Thyra::create_VectorSpace;
861  using Thyra::productVectorSpace;
863  if (ghostedDomainSpace_.is_null())
864  {
865  if (colDOFManagerContainer_->containsBlockedDOFManager())
866  {
867  // Loop over all vectors and build the vector space.
868  vector<RCP<const VectorSpaceBase<double>>> vsArray;
869  for (int i(0); i < getBlockColCount(); ++i)
870  vsArray.push_back(create_VectorSpace(getGhostedColMap(i)));
871  ghostedDomainSpace_ = productVectorSpace<double>(vsArray);
872  }
873  else // if (not colDOFManagerContainer_->containsBlockedDOFManager())
874  {
875  // The domain space is not blocked (that is, we're just dealing with a
876  // SPMD vector), so build it from the zeroth column.
877  ghostedDomainSpace_ = create_VectorSpace(getGhostedColMap(0));
878  } // end if (colDOFManagerContainer_->containsBlockedDOFManager()) or not
879  } // end if (ghostedDomainSpace_.is_null())
880  return ghostedDomainSpace_;
881 } // end of getGhostedThyraDomainSpace()
882 
884 //
885 // getGhostedThyraDomainSpace2()
886 //
888 template<typename Traits, typename LocalOrdinalT>
892 {
893  using std::vector;
894  using Teuchos::RCP;
895  using Thyra::create_VectorSpace;
896  using Thyra::productVectorSpace;
898  if (ghostedDomainSpace_.is_null())
899  {
900  if (colDOFManagerContainer_->containsBlockedDOFManager())
901  {
902  // Loop over all vectors and build the vector space.
903  vector<RCP<const VectorSpaceBase<double>>> vsArray;
904  for (int i(0); i < getBlockColCount(); ++i)
905  vsArray.push_back(create_VectorSpace(getGhostedColMap2(i)));
906  ghostedDomainSpace_ = productVectorSpace<double>(vsArray);
907  }
908  else // if (not colDOFManagerContainer_->containsBlockedDOFManager())
909  {
910  // The domain space is not blocked (that is, we're just dealing with a
911  // SPMD vector), so build it from the zeroth column.
912  ghostedDomainSpace_ = create_VectorSpace(getGhostedColMap2(0));
913  } // end if (colDOFManagerContainer_->containsBlockedDOFManager()) or not
914  } // end if (ghostedDomainSpace_.is_null())
915  return ghostedDomainSpace_;
916 } // end of getGhostedThyraDomainSpace2()
917 
918 template <typename Traits,typename LocalOrdinalT>
921 {
922  if(ghostedRangeSpace_==Teuchos::null) {
923  if(rowDOFManagerContainer_->containsBlockedDOFManager()) {
924  // loop over all vectors and build the vector space
925  std::vector<Teuchos::RCP<const Thyra::VectorSpaceBase<double> > > vsArray;
926  for(int i=0;i<getBlockRowCount();i++)
927  vsArray.push_back(Thyra::create_VectorSpace(getGhostedMap(i)));
928 
929  ghostedRangeSpace_ = Thyra::productVectorSpace<double>(vsArray);
930  }
931  else {
932  // the range space is not blocked (just an SPMD vector), build it from
933  // the zeroth row
934  ghostedRangeSpace_ = Thyra::create_VectorSpace(getGhostedMap(0));
935  }
936  }
937 
938  return ghostedRangeSpace_;
939 }
940 
941 template <typename Traits,typename LocalOrdinalT>
944 {
946  Thyra::createMember<double>(*getGhostedThyraDomainSpace());
947  Thyra::assign(vec.ptr(),0.0);
948 
949  return vec;
950 }
951 
952 template <typename Traits,typename LocalOrdinalT>
955 {
957  Thyra::createMember<double>(*getGhostedThyraRangeSpace());
958  Thyra::assign(vec.ptr(),0.0);
959 
960  return vec;
961 }
962 
963 template <typename Traits,typename LocalOrdinalT>
966 {
967  // return a flat epetra matrix
968  if(!rowDOFManagerContainer_->containsBlockedDOFManager() &&
969  !colDOFManagerContainer_->containsBlockedDOFManager()) {
970  return Thyra::nonconstEpetraLinearOp(getGhostedEpetraMatrix(0,0));
971  }
972 
973  Teuchos::RCP<Thyra::PhysicallyBlockedLinearOpBase<double> > blockedOp = Thyra::defaultBlockedLinearOp<double>();
974 
975  // get the block dimension
976  std::size_t rBlockDim = getBlockRowCount();
977  std::size_t cBlockDim = getBlockColCount();
978 
979  // this operator will be square
980  blockedOp->beginBlockFill(rBlockDim,cBlockDim);
981 
982  // loop over each block
983  for(std::size_t i=0;i<rBlockDim;i++) {
984  for(std::size_t j=0;j<cBlockDim;j++) {
985  if(excludedPairs_.find(std::make_pair(i,j))==excludedPairs_.end()) {
986  // build (i,j) block matrix and add it to blocked operator
987  Teuchos::RCP<Thyra::LinearOpBase<double> > block = Thyra::nonconstEpetraLinearOp(getGhostedEpetraMatrix(i,j));
988  blockedOp->setNonconstBlock(i,j,block);
989  }
990  }
991  }
992 
993  // all done
994  blockedOp->endBlockFill();
995 
996  return blockedOp;
997 }
998 
999 template <typename Traits,typename LocalOrdinalT>
1002  const Teuchos::RCP<Thyra::VectorBase<double> > & out,bool col) const
1003 {
1004  using Teuchos::RCP;
1005  using Teuchos::rcp_dynamic_cast;
1007  using Thyra::get_Epetra_Vector;
1008 
1009  std::size_t blockDim = col ? getBlockColCount() : getBlockRowCount();
1010 
1011  // get product vectors
1012  RCP<const ProductVectorBase<double> > prod_in = Thyra::castOrCreateProductVectorBase(in);
1013  RCP<ProductVectorBase<double> > prod_out = Thyra::castOrCreateNonconstProductVectorBase(out);
1014 
1015  TEUCHOS_ASSERT(prod_in->productSpace()->numBlocks()==(int) blockDim);
1016  TEUCHOS_ASSERT(prod_out->productSpace()->numBlocks()==(int) blockDim);
1017 
1018  for(std::size_t i=0;i<blockDim;i++) {
1019  // first get each Epetra vector
1021  RCP<Epetra_Vector> ep_out;
1022 
1023  if(not col) {
1024  ep_in = get_Epetra_Vector(*getGhostedMap(i),prod_in->getVectorBlock(i));
1025  ep_out = get_Epetra_Vector(*getMap(i),prod_out->getNonconstVectorBlock(i));
1026  } else {
1027  ep_in = get_Epetra_Vector(*getGhostedColMap(i),prod_in->getVectorBlock(i));
1028  ep_out = get_Epetra_Vector(*getColMap(i),prod_out->getNonconstVectorBlock(i));
1029  }
1030 
1031  // use Epetra to do global communication
1032  ghostToGlobalEpetraVector(i,*ep_in,*ep_out,col);
1033  }
1034 }
1035 
1036 template <typename Traits,typename LocalOrdinalT>
1039 {
1040  using Teuchos::RCP;
1041  using Teuchos::rcp_dynamic_cast;
1042  using Teuchos::dyn_cast;
1043  using Thyra::LinearOpBase;
1044  using Thyra::PhysicallyBlockedLinearOpBase;
1045  using Thyra::get_Epetra_Operator;
1046 
1047  // get the block dimension
1048  std::size_t rBlockDim = getBlockRowCount();
1049  std::size_t cBlockDim = getBlockColCount();
1050 
1051  // get product vectors
1052  const PhysicallyBlockedLinearOpBase<double> & prod_in = dyn_cast<const PhysicallyBlockedLinearOpBase<double> >(in);
1053  PhysicallyBlockedLinearOpBase<double> & prod_out = dyn_cast<PhysicallyBlockedLinearOpBase<double> >(out);
1054 
1055  TEUCHOS_ASSERT(prod_in.productRange()->numBlocks()==(int) rBlockDim);
1056  TEUCHOS_ASSERT(prod_in.productDomain()->numBlocks()==(int) cBlockDim);
1057  TEUCHOS_ASSERT(prod_out.productRange()->numBlocks()==(int) rBlockDim);
1058  TEUCHOS_ASSERT(prod_out.productDomain()->numBlocks()==(int) cBlockDim);
1059 
1060  for(std::size_t i=0;i<rBlockDim;i++) {
1061  for(std::size_t j=0;j<cBlockDim;j++) {
1062  if(excludedPairs_.find(std::make_pair(i,j))==excludedPairs_.end()) {
1063  // extract the blocks
1064  RCP<const LinearOpBase<double> > th_in = prod_in.getBlock(i,j);
1065  RCP<LinearOpBase<double> > th_out = prod_out.getNonconstBlock(i,j);
1066 
1067  // sanity check
1068  TEUCHOS_ASSERT(th_in!=Teuchos::null);
1069  TEUCHOS_ASSERT(th_out!=Teuchos::null);
1070 
1071  // get the epetra version of the blocks
1072  RCP<const Epetra_CrsMatrix> ep_in = rcp_dynamic_cast<const Epetra_CrsMatrix>(get_Epetra_Operator(*th_in),true);
1073  RCP<Epetra_CrsMatrix> ep_out = rcp_dynamic_cast<Epetra_CrsMatrix>(get_Epetra_Operator(*th_out),true);
1074 
1075  // use Epetra to do global communication
1076  ghostToGlobalEpetraMatrix(i,*ep_in,*ep_out);
1077  }
1078  }
1079  }
1080 }
1081 
1082 template <typename Traits,typename LocalOrdinalT>
1085  const Teuchos::RCP<Thyra::VectorBase<double> > & out,bool col) const
1086 {
1087  using Teuchos::RCP;
1088  using Teuchos::rcp_dynamic_cast;
1090  using Thyra::get_Epetra_Vector;
1091 
1092  std::size_t blockDim = col ? getBlockColCount() : getBlockRowCount();
1093 
1094  // get product vectors
1095  RCP<const ProductVectorBase<double> > prod_in = Thyra::castOrCreateProductVectorBase(in);
1096  RCP<ProductVectorBase<double> > prod_out = Thyra::castOrCreateNonconstProductVectorBase(out);
1097 
1098  TEUCHOS_ASSERT(prod_in->productSpace()->numBlocks()==(int) blockDim);
1099  TEUCHOS_ASSERT(prod_out->productSpace()->numBlocks()==(int) blockDim);
1100 
1101  for(std::size_t i=0;i<blockDim;i++) {
1102  // first get each Epetra vector
1103  RCP<const Epetra_Vector> ep_in;
1104  RCP<Epetra_Vector> ep_out;
1105 
1106  if(not col) {
1107  ep_in = get_Epetra_Vector(*getMap(i),prod_in->getVectorBlock(i));
1108  ep_out = get_Epetra_Vector(*getGhostedMap(i),prod_out->getNonconstVectorBlock(i));
1109  }
1110  else {
1111  ep_in = get_Epetra_Vector(*getColMap(i),prod_in->getVectorBlock(i));
1112  ep_out = get_Epetra_Vector(*getGhostedColMap(i),prod_out->getNonconstVectorBlock(i));
1113  }
1114 
1115  // use Epetra to do global communication
1116  globalToGhostEpetraVector(i,*ep_in,*ep_out,col);
1117  }
1118 }
1119 
1120 // Epetra methods
1122 
1123 template <typename Traits,typename LocalOrdinalT>
1125 ghostToGlobalEpetraVector(int i,const Epetra_Vector & in,Epetra_Vector & out,bool col) const
1126 {
1127  using Teuchos::RCP;
1128 
1129  // do the global distribution
1130  RCP<Epetra_Export> exporter = col ? getGhostedColExport(i) : getGhostedExport(i);
1131  out.PutScalar(0.0);
1132  int err = out.Export(in,*exporter,Add);
1133  TEUCHOS_ASSERT_EQUALITY(err,0);
1134 }
1135 
1136 template <typename Traits,typename LocalOrdinalT>
1139 {
1140  using Teuchos::RCP;
1141 
1142  // do the global distribution
1143  RCP<Epetra_Export> exporter = getGhostedExport(blockRow);
1144  out.PutScalar(0.0);
1145  int err = out.Export(in,*exporter,Add);
1146  TEUCHOS_ASSERT_EQUALITY(err,0);
1147 }
1148 
1149 template <typename Traits,typename LocalOrdinalT>
1151 globalToGhostEpetraVector(int i,const Epetra_Vector & in,Epetra_Vector & out,bool col) const
1152 {
1153  using Teuchos::RCP;
1154 
1155  // do the global distribution
1156  RCP<Epetra_Import> importer = col ? getGhostedColImport(i) : getGhostedImport(i);
1157  out.PutScalar(0.0);
1158  int err = out.Import(in,*importer,Insert);
1159  TEUCHOS_ASSERT_EQUALITY(err,0);
1160 }
1161 
1162 // get the map from the matrix
1163 template <typename Traits,typename LocalOrdinalT>
1165 getMap(int i) const
1166 {
1167  if(maps_[i]==Teuchos::null)
1168  maps_[i] = buildMap(i);
1169 
1170  return maps_[i];
1171 }
1172 
1173 // get the map from the matrix
1174 template <typename Traits,typename LocalOrdinalT>
1176 getColMap(int i) const
1177 {
1178  if(not useColGidProviders_)
1179  return getMap(i);
1180 
1181  if(colMaps_[i]==Teuchos::null)
1182  colMaps_[i] = buildColMap(i);
1183 
1184  return colMaps_[i];
1185 }
1186 
1188 //
1189 // getGhostedMap()
1190 //
1192 template<typename Traits, typename LocalOrdinalT>
1196  int i) const
1197 {
1198  if (ghostedMaps_[i].is_null())
1199  ghostedMaps_[i] = buildGhostedMap(i);
1200  return ghostedMaps_[i];
1201 } // end of getGhostedMap()
1202 
1204 //
1205 // getGhostedMap2()
1206 //
1208 template<typename Traits, typename LocalOrdinalT>
1212  int i) const
1213 {
1214  if (ghostedMaps2_[i].is_null())
1215  ghostedMaps2_[i] = buildGhostedMap2(i);
1216  return ghostedMaps2_[i];
1217 } // end of getGhostedMap2()
1218 
1220 //
1221 // getGhostedColMap()
1222 //
1224 template<typename Traits, typename LocalOrdinalT>
1228  int i) const
1229 {
1230  if (not useColGidProviders_)
1231  return getGhostedMap(i);
1232  if (colGhostedMaps_[i].is_null())
1233  colGhostedMaps_[i] = buildColGhostedMap(i);
1234  return colGhostedMaps_[i];
1235 } // end of getGhostedColMap()
1236 
1238 //
1239 // getGhostedColMap2()
1240 //
1242 template<typename Traits, typename LocalOrdinalT>
1246  int i) const
1247 {
1248  if (not useColGidProviders_)
1249  return getGhostedMap2(i);
1250  if (colGhostedMaps2_[i].is_null())
1251  colGhostedMaps2_[i] = buildColGhostedMap2(i);
1252  return colGhostedMaps2_[i];
1253 } // end of getGhostedColMap2()
1254 
1255 // get the graph of the crs matrix
1256 template <typename Traits,typename LocalOrdinalT>
1258 getGraph(int i,int j) const
1259 {
1260  typedef std::unordered_map<std::pair<int,int>,Teuchos::RCP<Epetra_CrsGraph>,panzer::pair_hash> GraphMap;
1261 
1262  GraphMap::const_iterator itr = graphs_.find(std::make_pair(i,j));
1263  Teuchos::RCP<Epetra_CrsGraph> graph;
1264  if(itr==graphs_.end()) {
1265  graph = buildGraph(i,j);
1266  graphs_[std::make_pair(i,j)] = graph;
1267  }
1268  else
1269  graph = itr->second;
1270 
1271  TEUCHOS_ASSERT(graph!=Teuchos::null);
1272  return graph;
1273 }
1274 
1275 template <typename Traits,typename LocalOrdinalT>
1277 getGhostedGraph(int i,int j) const
1278 {
1279  typedef std::unordered_map<std::pair<int,int>,Teuchos::RCP<Epetra_CrsGraph>,panzer::pair_hash> GraphMap;
1280 
1281  GraphMap::const_iterator itr = ghostedGraphs_.find(std::make_pair(i,j));
1282  Teuchos::RCP<Epetra_CrsGraph> ghostedGraph;
1283  if(itr==ghostedGraphs_.end()) {
1284  ghostedGraph = buildGhostedGraph(i,j,true);
1285  ghostedGraphs_[std::make_pair(i,j)] = ghostedGraph;
1286  }
1287  else
1288  ghostedGraph = itr->second;
1289 
1290  TEUCHOS_ASSERT(ghostedGraph!=Teuchos::null);
1291  return ghostedGraph;
1292 }
1293 
1295 //
1296 // getGhostedImport()
1297 //
1299 template<typename Traits, typename LocalOrdinalT>
1303  int i) const
1304 {
1305  using Teuchos::rcp;
1306  if (importers_[i].is_null())
1307  importers_[i] = rcp(new Epetra_Import(*getGhostedMap(i), *getMap(i)));
1308  return importers_[i];
1309 } // end of getGhostedImport()
1310 
1312 //
1313 // getGhostedImport2()
1314 //
1316 template<typename Traits, typename LocalOrdinalT>
1320  int i) const
1321 {
1322  using Teuchos::rcp;
1323  if (importers2_[i].is_null())
1324  importers2_[i] = rcp(new Epetra_Import(*getGhostedMap2(i), *getMap(i)));
1325  return importers2_[i];
1326 } // end of getGhostedImport2()
1327 
1329 //
1330 // getGhostedColImport()
1331 //
1333 template<typename Traits, typename LocalOrdinalT>
1337  int i) const
1338 {
1339  using Teuchos::rcp;
1340  if (not useColGidProviders_)
1341  return getGhostedImport(i);
1342  if (colImporters_[i].is_null())
1343  colImporters_[i] =
1344  rcp(new Epetra_Import(*getGhostedColMap(i), *getColMap(i)));
1345  return colImporters_[i];
1346 } // end of getGhostedColImport()
1347 
1349 //
1350 // getGhostedColImport2()
1351 //
1353 template<typename Traits, typename LocalOrdinalT>
1357  int i) const
1358 {
1359  using Teuchos::rcp;
1360  if (not useColGidProviders_)
1361  return getGhostedImport2(i);
1362  if (colImporters2_[i].is_null())
1363  colImporters2_[i] =
1364  rcp(new Epetra_Import(*getGhostedColMap2(i), *getColMap(i)));
1365  return colImporters2_[i];
1366 } // end of getGhostedColImport2()
1367 
1369 //
1370 // getGhostedExport()
1371 //
1373 template<typename Traits, typename LocalOrdinalT>
1377  int i) const
1378 {
1379  using Teuchos::rcp;
1380  if (exporters_[i].is_null())
1381  exporters_[i] = rcp(new Epetra_Export(*getGhostedMap(i), *getMap(i)));
1382  return exporters_[i];
1383 } // end of getGhostedExport()
1384 
1386 //
1387 // getGhostedExport2()
1388 //
1390 template<typename Traits, typename LocalOrdinalT>
1394  int i) const
1395 {
1396  using Teuchos::rcp;
1397  if (exporters_[i].is_null())
1398  exporters_[i] = rcp(new Epetra_Export(*getGhostedMap2(i), *getMap(i)));
1399  return exporters_[i];
1400 } // end of getGhostedExport2()
1401 
1403 //
1404 // getGhostedColExport()
1405 //
1407 template<typename Traits, typename LocalOrdinalT>
1411  int i) const
1412 {
1413  using Teuchos::rcp;
1414  if (not useColGidProviders_)
1415  return getGhostedExport(i);
1416  if (colExporters_[i].is_null())
1417  colExporters_[i] = rcp(new Epetra_Export(*getGhostedColMap(i),
1418  *getColMap(i)));
1419  return colExporters_[i];
1420 } // end of getGhostedColExport()
1421 
1423 //
1424 // getGhostedColExport2()
1425 //
1427 template<typename Traits, typename LocalOrdinalT>
1431  int i) const
1432 {
1433  using Teuchos::rcp;
1434  if (not useColGidProviders_)
1435  return getGhostedExport2(i);
1436  if (colExporters_[i].is_null())
1437  colExporters_[i] = rcp(new Epetra_Export(*getGhostedColMap2(i),
1438  *getColMap(i)));
1439  return colExporters_[i];
1440 } // end of getGhostedColExport2()
1441 
1442 template <typename Traits,typename LocalOrdinalT>
1444 buildMap(int i) const
1445 {
1446  std::vector<int> indices;
1447 
1448  // get the global indices
1449  getGlobalIndexer(i)->getOwnedIndicesAsInt(indices);
1450 
1451  return Teuchos::rcp(new Epetra_Map(-1,indices.size(),&indices[0],0,*eComm_));
1452 }
1453 
1454 template <typename Traits,typename LocalOrdinalT>
1456 buildColMap(int i) const
1457 {
1458  if(not useColGidProviders_)
1459  return buildMap(i);
1460 
1461  std::vector<int> indices;
1462 
1463  // get the global indices
1464  getColGlobalIndexer(i)->getOwnedIndicesAsInt(indices);
1465 
1466  return Teuchos::rcp(new Epetra_Map(-1,indices.size(),&indices[0],0,*eComm_));
1467 }
1468 
1470 //
1471 // buildGhostedMap()
1472 //
1474 template<typename Traits, typename LocalOrdinalT>
1478  int i) const
1479 {
1480  using std::vector;
1481  using Teuchos::rcp;
1482  vector<int> indices;
1483  getGlobalIndexer(i)->getOwnedAndGhostedIndicesAsInt(indices);
1484  return rcp(new Epetra_Map(-1, indices.size(), &indices[0], 0, *eComm_));
1485 } // end of buildGhostedMap()
1486 
1488 //
1489 // buildGhostedMap2()
1490 //
1492 template<typename Traits, typename LocalOrdinalT>
1496  int i) const
1497 {
1498  using std::vector;
1499  using Teuchos::rcp;
1500  vector<int> indices;
1501  getGlobalIndexer(i)->getGhostedIndicesAsInt(indices);
1502  return rcp(new Epetra_Map(-1, indices.size(), &indices[0], 0, *eComm_));
1503 } // end of buildGhostedMap2()
1504 
1506 //
1507 // buildColGhostedMap()
1508 //
1510 template<typename Traits, typename LocalOrdinalT>
1514  int i) const
1515 {
1516  using std::vector;
1517  using Teuchos::rcp;
1518  if (not useColGidProviders_)
1519  return buildGhostedMap(i);
1520  vector<int> indices;
1521  getColGlobalIndexer(i)->getOwnedAndGhostedIndicesAsInt(indices);
1522  return rcp(new Epetra_Map(-1, indices.size(), &indices[0], 0, *eComm_));
1523 } // end of buildColGhostedMap()
1524 
1526 //
1527 // buildColGhostedMap2()
1528 //
1530 template<typename Traits, typename LocalOrdinalT>
1534  int i) const
1535 {
1536  using std::vector;
1537  using Teuchos::rcp;
1538  if (not useColGidProviders_)
1539  return buildGhostedMap2(i);
1540  vector<int> indices;
1541  getColGlobalIndexer(i)->getGhostedIndicesAsInt(indices);
1542  return rcp(new Epetra_Map(-1, indices.size(), &indices[0], 0, *eComm_));
1543 } // end of buildColGhostedMap2()
1544 
1545 // get the graph of the crs matrix
1546 template <typename Traits,typename LocalOrdinalT>
1548 buildGraph(int i,int j) const
1549 {
1550  using Teuchos::RCP;
1551  using Teuchos::rcp;
1552 
1553  // build the map and allocate the space for the graph and
1554  // grab the ghosted graph
1555  RCP<Epetra_Map> map_i = getMap(i);
1556  RCP<Epetra_Map> map_j = getColMap(j);
1557 
1558  TEUCHOS_ASSERT(map_i!=Teuchos::null);
1559  TEUCHOS_ASSERT(map_j!=Teuchos::null);
1560 
1561  RCP<Epetra_CrsGraph> graph = rcp(new Epetra_CrsGraph(Copy,*map_i,0));
1562  RCP<Epetra_CrsGraph> oGraph = buildFilteredGhostedGraph(i,j);
1563  // this is the only place buildFilteredGhostedGraph is called. That is because
1564  // only the unghosted graph should reflect any of the filtering.
1565 
1566  // perform the communication to finish building graph
1567  RCP<Epetra_Export> exporter = getGhostedExport(i);
1568  int err = graph->Export( *oGraph, *exporter, Insert );
1569  TEUCHOS_ASSERT_EQUALITY(err,0);
1570  graph->FillComplete(*map_j,*map_i);
1571  graph->OptimizeStorage();
1572 
1573  return graph;
1574 }
1575 
1576 template <typename Traits,typename LocalOrdinalT>
1578 buildGhostedGraph(int i,int j,bool optimizeStorage) const
1579 {
1580  // build the map and allocate the space for the graph
1581  Teuchos::RCP<Epetra_Map> rowMap = getGhostedMap(i);
1582  Teuchos::RCP<Epetra_Map> colMap = getGhostedColMap(j);
1583  Teuchos::RCP<Epetra_CrsGraph> graph = Teuchos::rcp(new Epetra_CrsGraph(Copy,*rowMap,*colMap,0));
1584 
1585  std::vector<std::string> elementBlockIds;
1586 
1587  Teuchos::RCP<const GlobalIndexer> rowProvider, colProvider;
1588 
1589  rowProvider = getGlobalIndexer(i);
1590  colProvider = getColGlobalIndexer(j);
1591 
1592  rowProvider->getElementBlockIds(elementBlockIds); // each sub provider "should" have the
1593  // same element blocks
1594 
1595  const Teuchos::RCP<const ConnManager> conn_mgr = colProvider->getConnManager();
1596  const bool han = conn_mgr.is_null() ? false : conn_mgr->hasAssociatedNeighbors();
1597 
1598  // graph information about the mesh
1599  std::vector<std::string>::const_iterator blockItr;
1600  for(blockItr=elementBlockIds.begin();blockItr!=elementBlockIds.end();++blockItr) {
1601  std::string blockId = *blockItr;
1602 
1603  // grab elements for this block
1604  const std::vector<LocalOrdinalT> & elements = rowProvider->getElementBlock(blockId); // each sub provider "should" have the
1605  // same elements in each element block
1606 
1607  // get information about number of indicies
1608  std::vector<int> row_gids;
1609  std::vector<int> col_gids;
1610 
1611  // loop over the elemnts
1612  for(std::size_t elmt=0;elmt<elements.size();elmt++) {
1613  rowProvider->getElementGIDsAsInt(elements[elmt],row_gids);
1614  colProvider->getElementGIDsAsInt(elements[elmt],col_gids);
1615 
1616  if (han) {
1617  const std::vector<LocalOrdinalT>& aes = conn_mgr->getAssociatedNeighbors(elements[elmt]);
1618  for (typename std::vector<LocalOrdinalT>::const_iterator eit = aes.begin();
1619  eit != aes.end(); ++eit) {
1620  std::vector<int> other_col_gids;
1621  colProvider->getElementGIDsAsInt(*eit, other_col_gids);
1622  col_gids.insert(col_gids.end(), other_col_gids.begin(), other_col_gids.end());
1623  }
1624  }
1625 
1626  for(std::size_t row=0;row<row_gids.size();row++)
1627  graph->InsertGlobalIndices(row_gids[row],col_gids.size(),&col_gids[0]);
1628  }
1629  }
1630 
1631  // finish filling the graph: Make sure the colmap and row maps coincide to
1632  // minimize calls to LID lookups
1633  graph->FillComplete(*colMap,*rowMap);
1634  if(optimizeStorage)
1635  graph->OptimizeStorage();
1636 
1637  return graph;
1638 }
1639 
1640 template <typename Traits,typename LocalOrdinalT>
1642 buildFilteredGhostedGraph(int i,int j) const
1643 {
1644  using Teuchos::RCP;
1645  using Teuchos::rcp;
1646  using Teuchos::rcp_dynamic_cast;
1647 
1648  // figure out if the domain is filtered
1649  RCP<const Filtered_GlobalIndexer> filtered_ugi
1650  = rcp_dynamic_cast<const Filtered_GlobalIndexer>(getColGlobalIndexer(j));
1651 
1652  // domain is unfiltered, a filtered graph is just the original ghosted graph
1653  if(filtered_ugi==Teuchos::null)
1654  return buildGhostedGraph(i,j,true);
1655 
1656  // get all local indices that are active (i.e. unfiltered)
1657  std::vector<int> ghostedActive;
1658  filtered_ugi->getOwnedAndGhostedNotFilteredIndicator(ghostedActive);
1659 
1660  // This will build a new ghosted graph without optimized storage so entries can be removed.
1661  Teuchos::RCP<Epetra_CrsGraph> filteredGraph = buildGhostedGraph(i,j,false);
1662  // false implies that storage is not optimzied
1663 
1664  // remove filtered column entries
1665  for(int k=0;k<filteredGraph->NumMyRows();++k) {
1666  std::vector<int> removedIndices;
1667  int numIndices = 0;
1668  int * indices = 0;
1669  TEUCHOS_ASSERT(filteredGraph->ExtractMyRowView(k,numIndices,indices)==0);
1670 
1671  for(int m=0;m<numIndices;++m) {
1672  if(ghostedActive[indices[m]]==0)
1673  removedIndices.push_back(indices[m]);
1674  }
1675 
1676  TEUCHOS_ASSERT(filteredGraph->RemoveMyIndices(k,Teuchos::as<int>(removedIndices.size()),&removedIndices[0])==0);
1677  }
1678 
1679  // finish filling the graph
1680  Teuchos::RCP<Epetra_Map> rowMap = getGhostedMap(i);
1681  Teuchos::RCP<Epetra_Map> colMap = getGhostedColMap(j);
1682 
1683  TEUCHOS_ASSERT(filteredGraph->FillComplete(*colMap,*rowMap)==0);
1684  TEUCHOS_ASSERT(filteredGraph->OptimizeStorage()==0);
1685 
1686  return filteredGraph;
1687 }
1688 
1689 template <typename Traits,typename LocalOrdinalT>
1691 getEpetraMatrix(int i,int j) const
1692 {
1693  Teuchos::RCP<Epetra_CrsGraph> eGraph = getGraph(i,j);
1695  TEUCHOS_ASSERT(mat->Filled());
1696  return mat;
1697 }
1698 
1699 template <typename Traits,typename LocalOrdinalT>
1701 getGhostedEpetraMatrix(int i,int j) const
1702 {
1703  Teuchos::RCP<Epetra_CrsGraph> eGraph = getGhostedGraph(i,j);
1705  TEUCHOS_ASSERT(mat->Filled());
1706  return mat;
1707 }
1708 
1709 template <typename Traits,typename LocalOrdinalT>
1712 {
1713  return eComm_;
1714 }
1715 
1716 template <typename Traits,typename LocalOrdinalT>
1719 {
1720  return rowDOFManagerContainer_->getFieldBlocks();
1721 }
1722 
1723 template <typename Traits,typename LocalOrdinalT>
1726 {
1727  return colDOFManagerContainer_->getFieldBlocks();
1728 }
1729 
1730 }
1731 
1732 #endif // __Panzer_BlockedEpetraLinearObjFactory_impl_hpp__
RCP< const T > getConst() const
void getOwnedAndGhostedNotFilteredIndicator(std::vector< int > &indicator) const
virtual const Teuchos::RCP< Epetra_Map > buildColMap(int i) const
Build the i-th owned column map from the owned indices of the i-th (column) global indexer...
Teuchos::RCP< Epetra_CrsMatrix > getEpetraMatrix(int i, int j) const
Teuchos::RCP< Thyra::VectorBase< double > > getGhostedThyraDomainVector() const
Get a domain vector.
bool is_null(const boost::shared_ptr< T > &p)
virtual const Teuchos::RCP< Epetra_Export > getGhostedColExport(int j) const
get exporter for converting an overalapped object to a &quot;normal&quot; object
virtual const Teuchos::RCP< Epetra_Map > getGhostedColMap(int i) const
get the ghosted map from the matrix
virtual void adjustForDirichletConditions(const LinearObjContainer &localBCRows, const LinearObjContainer &globalBCRows, LinearObjContainer &ghostedObjs, bool zeroVectorRows=false, bool adjustX=false) const
const Teuchos::RCP< Epetra_Vector > get_x() const
virtual void writeVector(const std::string &identifier, const LinearObjContainer &loc, int id) const
void initializeContainer_internal(int mem, ThyraObjContainer< double > &loc) const
bool is_null(const std::shared_ptr< T > &p)
virtual const Teuchos::RCP< Epetra_Map > buildColGhostedMap2(int i) const
Build the i-th ghosted column map from the ghosted indices of the i-th (column) global indexer...
virtual void set_x_th(const Teuchos::RCP< Thyra::VectorBase< ScalarT > > &in)=0
const std::vector< Teuchos::RCP< GlobalIndexer > > & getFieldDOFManagers() const
T_To & dyn_cast(T_From &from)
Teuchos::RCP< Thyra::VectorBase< double > > getThyraDomainVector() const
Get a domain vector.
int NumMyRows() const
void ghostToGlobalThyraVector(const Teuchos::RCP< const Thyra::VectorBase< double > > &in, const Teuchos::RCP< Thyra::VectorBase< double > > &out, bool col) const
void initializeContainer(int, LinearObjContainer &loc) const
virtual const std::vector< panzer::LocalOrdinal > & getElementBlock(const std::string &blockId) const =0
virtual Teuchos::RCP< Thyra::VectorBase< ScalarT > > get_f_th() const =0
virtual void set_dxdt_th(const Teuchos::RCP< Thyra::VectorBase< ScalarT > > &in)=0
Teuchos::RCP< const GlobalIndexer > getColGlobalIndexer(int i) const
virtual const Teuchos::RCP< Epetra_Map > buildGhostedMap(int i) const
Build the i-th ghosted map from the owned and ghosted indices of the i-th global indexer.
virtual void getElementBlockIds(std::vector< std::string > &elementBlockIds) const =0
size_type size() const
const Teuchos::RCP< Epetra_CrsMatrix > get_A() const
This class encapsulates the needs of a gather operation to do a // halo exchange for blocked vectors...
virtual const Teuchos::RCP< const Epetra_Comm > getEpetraComm() const
get exporter for converting an overalapped object to a &quot;normal&quot; object
Teuchos::RCP< Thyra::LinearOpBase< double > > getThyraMatrix() const
Get a Thyra operator.
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getThyraRangeSpace() const
Get the range vector space (f)
Teuchos::RCP< Thyra::LinearOpBase< double > > getGhostedThyraMatrix() const
Get a Thyra operator.
virtual void getElementGIDsAsInt(panzer::LocalOrdinal localElmtId, std::vector< int > &gids, const std::string &blockIdHint="") const =0
Get the global IDs for a particular element. This function overwrites the gids variable.
virtual const Teuchos::RCP< Epetra_CrsGraph > getGhostedGraph(int i, int j) const
get the ghosted graph of the crs matrix
virtual const Teuchos::RCP< Epetra_CrsGraph > buildGraph(int i, int j) const
int ExtractMyRowView(int MyRow, int &NumEntries, double *&Values, int *&Indices) const
Teuchos::RCP< Thyra::VectorBase< double > > getGhostedThyraRangeVector() const
Get a range vector.
int PutScalar(double ScalarConstant)
virtual const std::vector< LocalOrdinal > & getAssociatedNeighbors(const LocalOrdinal &el) const =0
Teuchos::RCP< Epetra_CrsMatrix > getGhostedEpetraMatrix(int i, int j) const
PHX::MDField< ScalarT, panzer::Cell, panzer::IP > result
A field that will be used to build up the result of the integral we&#39;re performing.
virtual const Teuchos::RCP< Epetra_CrsGraph > buildFilteredGhostedGraph(int i, int j) const
virtual void globalToGhostContainer(const LinearObjContainer &container, LinearObjContainer &ghostContainer, int) const
int Export(const Epetra_SrcDistObject &A, const Epetra_Import &Importer, Epetra_CombineMode CombineMode, const Epetra_OffsetIndex *Indexor=0)
virtual const Teuchos::RCP< Epetra_Map > getMap(int i) const
get the map from the matrix
virtual const Teuchos::RCP< Epetra_Import > getGhostedImport2(int i) const
Get or create the i-th ghosted importer corresponding to the i-th ghosted map.
This class encapsulates the needs of a gather operation to do a halo exchange for blocked vectors...
Teuchos::RCP< const panzer::BlockedDOFManager > getGlobalIndexer() const
Teuchos::RCP< const DOFManagerContainer > colDOFManagerContainer_
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
virtual const Teuchos::RCP< Epetra_Map > getGhostedMap2(int i) const
Get or create the i-th ghosted map.
void initializeGhostedContainer_internal(int mem, ThyraObjContainer< double > &loc) const
Teuchos::RCP< const Teuchos::OpaqueWrapper< MPI_Comm > > rawMpiComm_
virtual const Teuchos::RCP< Epetra_Map > buildColGhostedMap(int i) const
Build the i-th ghosted column map from the owned and ghosted indices of the i-th (column) global inde...
virtual const Teuchos::RCP< Epetra_CrsGraph > buildGhostedGraph(int i, int j, bool optimizeStorage) const
BlockedEpetraLinearObjFactory(const Teuchos::RCP< const Teuchos::MpiComm< int > > &comm, const Teuchos::RCP< const GlobalIndexer > &gidProvider, bool useDiscreteAdjoint=false)
void addExcludedPairs(const std::vector< std::pair< int, int > > &exPairs)
exclude a vector of pairs from the matrix
virtual void set_f_th(const Teuchos::RCP< Thyra::VectorBase< ScalarT > > &in)=0
This class provides a boundary exchange communication mechanism for vectors.
virtual const Teuchos::RCP< Epetra_Import > getGhostedImport(int i) const
get importer for converting an overalapped object to a &quot;normal&quot; object
Ptr< T > ptr() const
void ghostToGlobalEpetraMatrix(int blockRow, const Epetra_CrsMatrix &in, Epetra_CrsMatrix &out) const
void makeRoomForBlocks(std::size_t blockCnt, std::size_t colBlockCnt=0)
Allocate the space in the std::vector objects so we can fill with appropriate Epetra data...
virtual Teuchos::RCP< const ConnManager > getConnManager() const =0
Returns the connection manager currently being used.
virtual const Teuchos::RCP< Epetra_Import > getGhostedColImport(int i) const
get importer for converting an overalapped object to a &quot;normal&quot; object
void addExcludedPair(int rowBlock, int colBlock)
exclude a block pair from the matrix
const Teuchos::RCP< Epetra_Vector > get_f() const
void ghostToGlobalEpetraVector(int i, const Epetra_Vector &in, Epetra_Vector &out, bool col) const
virtual const Teuchos::RCP< Epetra_Map > getColMap(int i) const
get the map from the matrix
This class provides a boundary exchange communication mechanism for vectors.
virtual const Teuchos::RCP< Epetra_Export > getGhostedColExport2(int i) const
Get or create the i-th ghosted column exporter corresponding to the i-th ghosted column map...
int InsertGlobalIndices(int GlobalRow, int NumIndices, int *Indices)
virtual const Teuchos::RCP< Epetra_Map > buildGhostedMap2(int i) const
Build the i-th ghosted map from the ghosted indices of the i-th global indexer.
int ExtractMyRowView(int LocalRow, int &NumIndices, int *&Indices) const
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getThyraDomainSpace() const
Get the domain vector space (x and dxdt)
virtual const Teuchos::RCP< Epetra_CrsGraph > getGraph(int i, int j) const
get the graph of the crs matrix
void initializeGhostedContainer(int, LinearObjContainer &loc) const
void ghostToGlobalThyraMatrix(const Thyra::LinearOpBase< double > &in, Thyra::LinearOpBase< double > &out) const
virtual const Teuchos::RCP< Epetra_Export > getGhostedExport(int j) const
get exporter for converting an overalapped object to a &quot;normal&quot; object
virtual const Teuchos::RCP< Epetra_Map > getGhostedColMap2(int i) const
Get or create the i-th ghosted column map.
void setMapsForBlocks(const std::vector< Teuchos::RCP< const Epetra_Map > > &blockMaps)
int VectorToMatrixMarketFile(const char *filename, const Epetra_Vector &A, const char *matrixName=0, const char *matrixDescription=0, bool writeHeader=true)
virtual const Teuchos::RCP< Epetra_Import > getGhostedColImport2(int i) const
Get or create the i-th ghosted column importer corresponding to the i-th ghosted column map...
int RemoveMyIndices(int LocalRow, int NumIndices, int *Indices)
Teuchos::RCP< Thyra::VectorBase< double > > getThyraRangeVector() const
Get a range vector.
virtual void set_A_th(const Teuchos::RCP< Thyra::LinearOpBase< ScalarT > > &in)=0
bool Filled() const
virtual const Teuchos::RCP< Epetra_Map > getGhostedMap(int i) const
get the ghosted map from the matrix
int MatrixMarketFileToVector(const char *filename, const Epetra_BlockMap &map, Epetra_Vector *&A)
virtual void readVector(const std::string &identifier, LinearObjContainer &loc, int id) const
virtual Teuchos::RCP< ReadOnlyVector_GlobalEvaluationData > buildReadOnlyDomainContainer() const
virtual Teuchos::RCP< LinearObjContainer > buildGhostedLinearObjContainer() const
virtual bool hasAssociatedNeighbors() const =0
void buildGatherScatterEvaluators(const BuilderT &builder)
virtual void applyDirichletBCs(const LinearObjContainer &counter, LinearObjContainer &result) const
#define TEUCHOS_ASSERT(assertion_test)
#define TEUCHOS_ASSERT_EQUALITY(val1, val2)
void globalToGhostEpetraVector(int i, const Epetra_Vector &in, Epetra_Vector &out, bool col) const
virtual Teuchos::RCP< WriteVector_GlobalEvaluationData > buildWriteDomainContainer() const
const Teuchos::RCP< Epetra_Vector > get_dxdt() const
virtual const Teuchos::RCP< Epetra_Map > buildMap(int i) const
Build the i-th owned map from the owned indices of the i-th global indexer.
virtual Teuchos::RCP< LinearObjContainer > buildLinearObjContainer() const
void globalToGhostThyraVector(const Teuchos::RCP< const Thyra::VectorBase< double > > &in, const Teuchos::RCP< Thyra::VectorBase< double > > &out, bool col) const
virtual void ghostToGlobalContainer(const LinearObjContainer &ghostContainer, LinearObjContainer &container, int) const
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getGhostedThyraRangeSpace() const
Get the range vector space (f)
Teuchos::RCP< const DOFManagerContainer > rowDOFManagerContainer_
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getGhostedThyraDomainSpace() const
Get the domain vector space (x and dxdt)
Teuchos::RCP< const Thyra::VectorSpaceBase< double > > getGhostedThyraDomainSpace2() const
Get or create the ghosted Thyra domain space.
virtual const Teuchos::RCP< Epetra_Export > getGhostedExport2(int i) const
Get or create the i-th ghosted exporter corresponding to the i-th ghosted map.
bool is_null() const