FEI  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FEI_Implementation.cpp
1 /*--------------------------------------------------------------------*/
2 /* Copyright 2005 Sandia Corporation. */
3 /* Under the terms of Contract DE-AC04-94AL85000, there is a */
4 /* non-exclusive license for use of this work by or on behalf */
5 /* of the U.S. Government. Export of this program may require */
6 /* a license from the United States Government. */
7 /*--------------------------------------------------------------------*/
8 
9 #include <fei_CommUtils.hpp>
10 #include <fei_iostream.hpp>
11 #include <fei_fstream.hpp>
12 #include <fei_sstream.hpp>
13 
14 #include <fei_utils.hpp>
15 
16 #include <fei_Data.hpp>
17 #include <fei_LinearSystemCore.hpp>
18 #include <fei_FiniteElementData.hpp>
19 
20 #include <fei_LibraryWrapper.hpp>
21 #include <fei_Filter.hpp>
22 
23 #include <fei_LinSysCoreFilter.hpp>
24 #include <fei_FEDataFilter.hpp>
25 
26 #include <SNL_FEI_Structure.hpp>
27 #include <fei_BlockDescriptor.hpp>
28 #include <fei_NodeDatabase.hpp>
29 #include <fei_ConnectivityTable.hpp>
30 #include <FEI_Implementation.hpp>
31 #include <snl_fei_Utils.hpp>
32 
33 #undef fei_file
34 #define fei_file "FEI_Implementation.cpp"
35 
36 #include <fei_ErrMacros.hpp>
37 
38 //------------------------------------------------------------------------------
40  MPI_Comm comm, int masterRank)
41  : wrapper_(libWrapper),
42  linSysCore_(NULL),
43  lscArray_(),
44  haveLinSysCore_(false),
45  haveFEData_(false),
46  problemStructure_(NULL),
47  filter_(NULL),
48  numInternalFEIs_(0),
49  internalFEIsAllocated_(false),
50  matrixIDs_(),
51  numRHSIDs_(),
52  rhsIDs_(),
53  IDsAllocated_(false),
54  matScalars_(),
55  matScalarsSet_(false),
56  rhsScalars_(),
57  rhsScalarsSet_(false),
58  index_soln_filter_(0),
59  index_current_filter_(0),
60  index_current_rhs_row_(0),
61  solveType_(-1),
62  setSolveTypeCalled_(false),
63  initPhaseIsComplete_(false),
64  aggregateSystemFormed_(false),
65  newMatrixDataLoaded_(0),
66  soln_fei_matrix_(NULL),
67  soln_fei_vector_(NULL),
68  comm_(comm),
69  masterRank_(0),
70  localRank_(0),
71  numProcs_(1),
72  outputLevel_(0),
73  solveCounter_(1),
74  debugOutput_(0),
75  dbgOStreamPtr_(NULL),
76  dbgFileOpened_(false),
77  dbgFStreamPtr_(NULL),
78  initTime_(0.0),
79  loadTime_(0.0),
80  solveTime_(0.0),
81  solnReturnTime_(0.0),
82  numParams_(0),
83  paramStrings_(NULL)
84 {
85  localRank_ = fei::localProc(comm);
86  numProcs_ = fei::numProcs(comm);
87 
88  problemStructure_ = new SNL_FEI_Structure(comm_);
89 
90  if (problemStructure_ == NULL) {
91  messageAbort("problemStructure allocation failed");
92  }
93 
94  //If we have a FiniteElementData instance as the underlying
95  //data receptacle and solver, then we'll set the shared-node-ownership rule
96  //to make sure shared nodes are owned by a proc which contains them in
97  //local elements.
98  haveFEData_ = wrapper_->haveFiniteElementData();
99  if (haveFEData_) {
100  haveFEData_ = true;
101  NodeCommMgr& nodeCommMgr = problemStructure_->getNodeCommMgr();
102  nodeCommMgr.setSharedOwnershipRule(NodeCommMgr::PROC_WITH_LOCAL_ELEM);
103  }
104 
105  haveLinSysCore_ = wrapper_->haveLinearSystemCore();
106  if (haveLinSysCore_) {
107  linSysCore_ = wrapper_->getLinearSystemCore();
108  lscArray_.push_back(linSysCore_);
109  }
110 
111  numInternalFEIs_ = 1;
112  matrixIDs_.resize(1);
113  matrixIDs_[0] = 0;
114  numRHSIDs_.resize(1);
115  numRHSIDs_[0] = 1;
116  rhsIDs_.resize(1);
117  rhsIDs_[0] = new int[1];
118  rhsIDs_[0][0] = 0;
119  rhsScalars_.resize(numInternalFEIs_);
120  for(int ii=0; ii<numInternalFEIs_; ii++) rhsScalars_[ii] = NULL;
121 
122  // and the time spent in the constructor is...
123 
124  return;
125 }
126 
127 //------------------------------------------------------------------------------
129 {
130  //
131  // Destructor function. Free allocated memory, etc.
132  //
133 
134  if (debugOutput_) {
135  (*dbgOStreamPtr_) << "FEI: destructor" << FEI_ENDL;
136  }
137 
138  if (soln_fei_matrix_) {
139  linSysCore_->destroyMatrixData(*soln_fei_matrix_);
140  delete soln_fei_matrix_;
141  soln_fei_matrix_ = NULL;
142  }
143 
144  if (soln_fei_vector_) {
145  linSysCore_->destroyVectorData(*soln_fei_vector_);
146  delete soln_fei_vector_;
147  soln_fei_vector_ = NULL;
148  }
149 
150  deleteIDs();
151 
152  if (internalFEIsAllocated_) {
153  for(int j=0; j<numInternalFEIs_; j++){
154  delete filter_[j];
155  }
156  delete [] filter_;
157  }
158 
159  deleteRHSScalars();
160 
161  internalFEIsAllocated_ = false;
162  numInternalFEIs_ = 0;
163 
164  delete problemStructure_;
165 
166  for(int k=0; k<numParams_; k++) delete [] paramStrings_[k];
167  delete [] paramStrings_;
168 
169  if (dbgFileOpened_ == true) {
170  dbgFStreamPtr_->close(); delete dbgFStreamPtr_;
171  }
172  else delete dbgOStreamPtr_;
173 }
174 
175 
176 //------------------------------------------------------------------------------
177 void FEI_Implementation::deleteIDs()
178 {
179  matrixIDs_.resize(0);
180  for(size_t i=0; i<rhsIDs_.size(); i++) {
181  delete [] rhsIDs_[i];
182  }
183  rhsIDs_.resize(0);
184  numRHSIDs_.resize(0);
185 }
186 
187 //------------------------------------------------------------------------------
188 void FEI_Implementation::deleteRHSScalars()
189 {
190  for(size_t i=0; i<rhsScalars_.size(); i++) {
191  delete [] rhsScalars_[i];
192  }
193  rhsScalars_.resize(0);
194 }
195 
196 //------------------------------------------------------------------------------
198 {
199  if (debugOutput_) {
200  (*dbgOStreamPtr_) << "FEI: setCurrentMatrix" << FEI_ENDL << "#matrix-id"
201  << FEI_ENDL<<matID<<FEI_ENDL;
202  }
203 
204  index_current_filter_ = -1;
205 
206  for(int i=0; i<numInternalFEIs_; i++){
207  if (matrixIDs_[i] == matID) index_current_filter_ = i;
208  }
209 
210  if (debugOutput_) {
211  (*dbgOStreamPtr_) << "#--- ID: " << matID
212  << ", ind: "<<index_current_filter_<<FEI_ENDL;
213  }
214 
215  //if matID wasn't found, return non-zero (error)
216  if (index_current_filter_ == -1) {
217  fei::console_out() << "FEI_Implementation::setCurrentMatrix: ERROR, invalid matrix ID "
218  << "supplied" << FEI_ENDL;
219  return(-1);
220  }
221 
222  debugOut("#FEI_Implementation leaving setCurrentMatrix");
223 
224  return(0);
225 }
226 
227 //------------------------------------------------------------------------------
228 int FEI_Implementation::getParameters(int& numParams, char**& paramStrings)
229 {
230  numParams = numParams_;
231  paramStrings = paramStrings_;
232  return(0);
233 }
234 
235 //------------------------------------------------------------------------------
237 {
238  if (debugOutput_) {
239  (*dbgOStreamPtr_) << "FEI: setCurrentRHS" << FEI_ENDL << "#rhs-id"
240  << FEI_ENDL<<rhsID<<FEI_ENDL;
241  }
242 
243  bool found = false;
244 
245  for(int j=0; j<numInternalFEIs_; j++){
246  int index = fei::searchList(rhsID, rhsIDs_[j], numRHSIDs_[j]);
247  if (index >= 0) {
248  index_current_rhs_row_ = j;
249  CHK_ERR( filter_[index_current_rhs_row_]->setCurrentRHS(rhsID) )
250  found = true;
251  break;
252  }
253  }
254 
255  if (!found) {
256  fei::console_out() << "FEI_Implementation::setCurrentRHS: ERROR, invalid RHS ID"
257  << FEI_ENDL;
258  ERReturn(-1);
259  }
260 
261  debugOut("#FEI_Implementation leaving setCurrentRHS");
262 
263  return(0);
264 }
265 
266 //------------------------------------------------------------------------------
268 {
269  if (debugOutput_) {
270  (*dbgOStreamPtr_)<<"FEI: setSolveType"<<FEI_ENDL;
271  (*dbgOStreamPtr_)<<solveType<<FEI_ENDL;
272  }
273 
274  solveType_ = solveType;
275 
276  if (solveType_ == FEI_SINGLE_SYSTEM) {
277  if (matrixIDs_.size() > 1) {
278  messageAbort("setSolveType: solve-type is FEI_SINGLE_SYSTEM, but setIDLists() has been called with numMatrices > 1.");
279  }
280  }
281  else if (solveType_ == FEI_EIGEN_SOLVE) {
282  }
283  else if (solveType_ == FEI_AGGREGATE_SUM) {
284  //solving a linear-combination of separately
285  //assembled matrices and rhs vectors
286  }
287  else if (solveType_ == FEI_AGGREGATE_PRODUCT) {
288  //solving a product of separately assembled
289  //matrices -- i.e., (C^T*M*C)x = rhs
290  }
291  else if (solveType_ == 4) {
292  //4 means we'll be doing a multi-level solution
293  }
294 
295  return(0);
296 }
297 
298 //------------------------------------------------------------------------------
299 int FEI_Implementation::setIDLists(int numMatrices, const int* matrixIDs,
300  int numRHSs, const int* rhsIDs)
301 {
302  if (debugOutput_) {
303  FEI_OSTREAM& os = *dbgOStreamPtr_;
304  os << "FEI: setIDLists" << FEI_ENDL
305  << "#num-matrices" << FEI_ENDL << numMatrices << FEI_ENDL
306  << "#matrixIDs" << FEI_ENDL;
307  int i;
308  for(i=0; i<numMatrices; ++i) os << matrixIDs[i] << " ";
309  os << FEI_ENDL << "#num-rhs's" << FEI_ENDL;
310  for(i=0; i<numRHSs; ++i) os << rhsIDs[i] << " ";
311  os << FEI_ENDL;
312  }
313 
314  deleteIDs();
315 
316  // We will try to assign the rhs's evenly over the matrices. i.e., give
317  // roughly equal numbers of rhs's to each matrix.
318 
319  //first, let's make sure we have at least 1 matrixID to which we can assign
320  //rhs's...
321  int myNumMatrices = numMatrices;
322  if (myNumMatrices == 0) myNumMatrices = 1;
323 
324  matrixIDs_.resize(myNumMatrices);
325 
326  if (rhsScalars_.size() != 0) deleteRHSScalars();
327 
328  numInternalFEIs_ = myNumMatrices;
329 
330  if (numMatrices == 0) {
331  matrixIDs_[0] = 0;
332  }
333  else {
334  for(int i=0; i<numMatrices; i++) matrixIDs_[i] = matrixIDs[i];
335  }
336 
337  int quotient = numRHSs/myNumMatrices;
338  int rem = numRHSs%numMatrices;
339 
340  //the allocateInternalFEIs function which will be called later from within
341  //initComplete(), takes a list of matrixIDs, and a list
342  //of numRHSsPerMatrix, and then a table of rhsIDs, where the table has a row
343  //for each matrixID. Each of those rows is a list of the rhsIDs assigned to
344  //the corresponding matrix. Is that clear???
345 
346  numRHSIDs_.resize(myNumMatrices);
347  rhsIDs_.resize(myNumMatrices);
348 
349  int offset = 0;
350  for(int i=0; i<myNumMatrices; i++) {
351  numRHSIDs_[i] = quotient;
352  if (i < rem) numRHSIDs_[i]++;
353 
354  rhsIDs_[i] = numRHSIDs_[i] > 0 ? new int[numRHSIDs_[i]] : NULL ;
355 
356  for(int j=0; j<numRHSIDs_[i]; j++) {
357  rhsIDs_[i][j] = rhsIDs[offset+j];
358  }
359 
360  offset += numRHSIDs_[i];
361  }
362 
363  return(0);
364 }
365 
366 //------------------------------------------------------------------------------
368  const int *fieldSizes,
369  const int *fieldIDs,
370  const int *fieldTypes)
371 {
372  CHK_ERR( problemStructure_->initFields(numFields, fieldSizes, fieldIDs, fieldTypes) );
373 
374  return(0);
375 }
376 
377 //------------------------------------------------------------------------------
378 int FEI_Implementation::initElemBlock(GlobalID elemBlockID,
379  int numElements,
380  int numNodesPerElement,
381  const int* numFieldsPerNode,
382  const int* const* nodalFieldIDs,
383  int numElemDofFieldsPerElement,
384  const int* elemDOFFieldIDs,
385  int interleaveStrategy)
386 {
387  CHK_ERR( problemStructure_->initElemBlock(elemBlockID,
388  numElements,
389  numNodesPerElement,
390  numFieldsPerNode,
391  nodalFieldIDs,
392  numElemDofFieldsPerElement,
393  elemDOFFieldIDs,
394  interleaveStrategy) );
395 
396  return(0);
397 }
398 
399 //------------------------------------------------------------------------------
400 int FEI_Implementation::initElem(GlobalID elemBlockID,
401  GlobalID elemID,
402  const GlobalID* elemConn)
403 {
404  CHK_ERR( problemStructure_->initElem(elemBlockID, elemID, elemConn) );
405 
406  return(0);
407 }
408 
409 //------------------------------------------------------------------------------
410 int FEI_Implementation::initSlaveVariable(GlobalID slaveNodeID,
411  int slaveFieldID,
412  int offsetIntoSlaveField,
413  int numMasterNodes,
414  const GlobalID* masterNodeIDs,
415  const int* masterFieldIDs,
416  const double* weights,
417  double rhsValue)
418 {
419  CHK_ERR( problemStructure_->initSlaveVariable(slaveNodeID, slaveFieldID,
420  offsetIntoSlaveField,
421  numMasterNodes, masterNodeIDs,
422  masterFieldIDs, weights, rhsValue));
423 
424  return(0);
425 }
426 
427 //------------------------------------------------------------------------------
429 {
430  debugOut("FEI: deleteMultCRs");
431 
432  CHK_ERR( problemStructure_->deleteMultCRs() );
433 
434  int err = -1;
435  if (internalFEIsAllocated_) {
436  err = filter_[index_current_filter_]->deleteMultCRs();
437  }
438 
439  return(err);
440 }
441 
442 //------------------------------------------------------------------------------
443 int FEI_Implementation::initSharedNodes(int numSharedNodes,
444  const GlobalID *sharedNodeIDs,
445  const int* numProcsPerNode,
446  const int *const *sharingProcIDs)
447 {
448  //
449  // In this function we simply accumulate the incoming data into
450  // internal arrays in the problemStructure_ object.
451  //
452  CHK_ERR( problemStructure_->initSharedNodes(numSharedNodes,
453  sharedNodeIDs,
454  numProcsPerNode,
455  sharingProcIDs));
456 
457  return(0);
458 }
459 
460 //------------------------------------------------------------------------------
462  const GlobalID* CRNodes,
463  const int *CRFields,
464  int& CRID)
465 {
466 //
467 // Store Lagrange Multiplier constraint data into internal structures, and
468 // return an identifier 'CRID' by which this constraint may be referred to
469 // later.
470 //
471 
472  CHK_ERR( problemStructure_->initCRMult(numCRNodes,
473  CRNodes,
474  CRFields,
475  CRID));
476 
477  return(0);
478 }
479 
480 //------------------------------------------------------------------------------
481 int FEI_Implementation::initCRPen(int numCRNodes,
482  const GlobalID* CRNodes,
483  const int *CRFields,
484  int& CRID)
485 {
486 //
487 // Store penalty constraint data and return an identifier 'CRID' by which the
488 // constraint may be referred to later.
489 //
490 
491  CHK_ERR( problemStructure_->initCRPen(numCRNodes,
492  CRNodes,
493  CRFields,
494  CRID));
495 
496  return(0);
497 }
498 
499 //------------------------------------------------------------------------------
501 {
502  bool generateGraph = !haveFEData_;
503 
504  CHK_ERR( problemStructure_->initComplete(generateGraph) );
505 
506  //now allocate one or more internal instances of Filter, depending on
507  //whether the user has indicated that they're doing an aggregate solve
508  //etc., via the functions setSolveType() and setIDLists().
509 
510  CHK_ERR( allocateInternalFEIs() );
511 
512  for(int i=0; i<numInternalFEIs_; ++i) {
513  CHK_ERR( filter_[i]->initialize() );
514  }
515 
516  problemStructure_->destroyMatIndices();
517 
518  initPhaseIsComplete_ = true;
519  return(0);
520 }
521 
522 //------------------------------------------------------------------------------
524 {
525 //
526 // This puts the value s throughout both the matrix and the vector.
527 //
528  if (!internalFEIsAllocated_) return(0);
529 
530  CHK_ERR( filter_[index_current_filter_]->resetSystem(s))
531 
532  return(0);
533 }
534 
535 //------------------------------------------------------------------------------
537 {
538  if (!internalFEIsAllocated_) return(0);
539 
540  CHK_ERR( filter_[index_current_filter_]->resetMatrix(s))
541 
542  return(0);
543 }
544 
545 //------------------------------------------------------------------------------
547 {
548  if (!internalFEIsAllocated_) return(0);
549 
550  CHK_ERR( filter_[index_current_filter_]->resetRHSVector(s))
551 
552  return(0);
553 }
554 
555 //------------------------------------------------------------------------------
557 {
558  if (!internalFEIsAllocated_) return(0);
559 
560  CHK_ERR( filter_[index_current_filter_]->resetInitialGuess(s))
561 
562  return(0);
563 }
564 
565 //------------------------------------------------------------------------------
567  const GlobalID *nodeIDs,
568  int fieldID,
569  const int* offsetsIntoField,
570  const double* prescribedValues)
571 {
572  if (!internalFEIsAllocated_)
573  notAllocatedAbort("FEI_Implementation::loadNodeBCs");
574 
575  int index = index_current_filter_;
576  if (solveType_ == 2) index = index_soln_filter_;
577 
578  CHK_ERR( filter_[index]->loadNodeBCs(numNodes,
579  nodeIDs, fieldID,
580  offsetsIntoField, prescribedValues));
581 
582  return(0);
583 }
584 
585 //------------------------------------------------------------------------------
587  const GlobalID *elemIDs,
588  int fieldID,
589  const double *const *alpha,
590  const double *const *beta,
591  const double *const *gamma)
592 {
593  if (!internalFEIsAllocated_)
594  notAllocatedAbort("FEI_Implementation::loadElemBCs");
595 
596  int index = index_current_filter_;
597  if (solveType_ == 2) index = index_soln_filter_;
598 
599  CHK_ERR( filter_[index]->loadElemBCs(numElems,
600  elemIDs, fieldID,
601  alpha, beta, gamma))
602 
603  return(0);
604 }
605 
606 //------------------------------------------------------------------------------
607 int FEI_Implementation::sumInElem(GlobalID elemBlockID,
608  GlobalID elemID,
609  const GlobalID* elemConn,
610  const double* const* elemStiffness,
611  const double* elemLoad,
612  int elemFormat)
613 {
614  if (!internalFEIsAllocated_) {
615  notAllocatedAbort("FEI_Implementation::sumInElem");
616  }
617 
618  CHK_ERR( filter_[index_current_filter_]->sumInElem(elemBlockID, elemID,
619  elemConn, elemStiffness,
620  elemLoad, elemFormat));
621 
622  newMatrixDataLoaded_ = 1;
623 
624  return(0);
625 }
626 
627 //------------------------------------------------------------------------------
628 int FEI_Implementation::sumInElemMatrix(GlobalID elemBlockID,
629  GlobalID elemID,
630  const GlobalID* elemConn,
631  const double* const* elemStiffness,
632  int elemFormat)
633 {
634  if (!internalFEIsAllocated_)
635  notAllocatedAbort("FEI_Implementation::sumInElemMatrix");
636 
637  CHK_ERR( filter_[index_current_filter_]->sumInElemMatrix(elemBlockID,
638  elemID, elemConn,
639  elemStiffness, elemFormat))
640 
641  newMatrixDataLoaded_ = 1;
642 
643 
644  return(0);
645 }
646 
647 //------------------------------------------------------------------------------
648 int FEI_Implementation::sumInElemRHS(GlobalID elemBlockID,
649  GlobalID elemID,
650  const GlobalID* elemConn,
651  const double* elemLoad)
652 {
653  if (!internalFEIsAllocated_)
654  notAllocatedAbort("FEI_Implementation::sumInElemRHS");
655 
656  CHK_ERR( filter_[index_current_rhs_row_]->sumInElemRHS(elemBlockID,
657  elemID, elemConn, elemLoad))
658 
659  newMatrixDataLoaded_ = 1;
660 
661  return(0);
662 }
663 
664 //------------------------------------------------------------------------------
666  int numCRNodes,
667  const GlobalID* CRNodes,
668  const int* CRFields,
669  const double* CRWeights,
670  double CRValue)
671 {
672  if (!internalFEIsAllocated_)
673  notAllocatedAbort("FEI_Implementation::loadCRMult");
674 
675  newMatrixDataLoaded_ = 1;
676 
677  CHK_ERR( filter_[index_current_filter_]->loadCRMult(CRID,
678  numCRNodes, CRNodes,
679  CRFields, CRWeights, CRValue));
680 
681  return(0);
682 }
683 
684 //------------------------------------------------------------------------------
686  int numCRNodes,
687  const GlobalID* CRNodes,
688  const int* CRFields,
689  const double* CRWeights,
690  double CRValue,
691  double penValue)
692 {
693  if (!internalFEIsAllocated_)
694  notAllocatedAbort("FEI_Implementation::loadCRPen");
695 
696  CHK_ERR( filter_[index_current_filter_]->loadCRPen(CRID,
697  numCRNodes, CRNodes,
698  CRFields, CRWeights,
699  CRValue, penValue))
700 
701  newMatrixDataLoaded_ = 1;
702 
703  return(0);
704 }
705 
706 //------------------------------------------------------------------------------
708  int fieldID,
709  int numIDs,
710  const GlobalID* IDs,
711  const double* rhsEntries)
712 {
713  if (!internalFEIsAllocated_)
714  notAllocatedAbort("FEI_Implementation::sumIntoRHS");
715 
716  CHK_ERR( filter_[index_current_rhs_row_]->sumIntoRHS(IDType, fieldID,
717  numIDs, IDs, rhsEntries) );
718  newMatrixDataLoaded_ = 1;
719 
720  return(0);
721 }
722 
723 //------------------------------------------------------------------------------
724 int FEI_Implementation::sumIntoMatrixDiagonal(int IDType,
725  int fieldID,
726  int numIDs,
727  const GlobalID* IDs,
728  const double* coefficients)
729 {
730  if (!internalFEIsAllocated_)
731  notAllocatedAbort("FEI_Implementation::sumIntoMatrixDiagonal");
732 
733  CHK_ERR( filter_[index_current_filter_]->sumIntoMatrixDiagonal(IDType, fieldID,
734  numIDs, IDs, coefficients) );
735  newMatrixDataLoaded_ = 1;
736 
737  return(0);
738 }
739 
740 //------------------------------------------------------------------------------
742  int fieldID,
743  int numIDs,
744  const GlobalID* IDs,
745  const double* rhsEntries)
746 {
747  if (!internalFEIsAllocated_)
748  notAllocatedAbort("FEI_Implementation::putIntoRHS");
749 
750  CHK_ERR( filter_[index_current_rhs_row_]->putIntoRHS(IDType, fieldID,
751  numIDs, IDs, rhsEntries) );
752  newMatrixDataLoaded_ = 1;
753 
754  return(0);
755 }
756 
757 //------------------------------------------------------------------------------
759  const int* IDs, const double* scalars)
760 {
761  for(int i=0; i<numScalars; i++){
762  std::vector<int>::iterator iter =
763  std::find(matrixIDs_.begin(), matrixIDs_.end(), IDs[i]);
764  if (iter != matrixIDs_.end()) {
765  int index = iter - matrixIDs_.begin();
766  matScalars_[index] = scalars[i];
767  }
768  else {
769  fei::console_out() << "FEI_Implementation::setMatScalars: ERROR, invalid ID supplied"
770  << FEI_ENDL;
771  return(1);
772  }
773  }
774 
775  aggregateSystemFormed_ = false;
776  matScalarsSet_ = true;
777 
778  return(0);
779 }
780 
781 //------------------------------------------------------------------------------
783  const int* IDs, const double* scalars)
784 {
785  for(int i=0; i<numScalars; i++){
786  bool found = false;
787 
788  for(int j=0; j<numInternalFEIs_; j++){
789  int index = fei::searchList(IDs[i], rhsIDs_[j], numRHSIDs_[j]);
790  if (index>=0) {
791  rhsScalars_[j][index] = scalars[i];
792  found = true;
793  break;
794  }
795  }
796 
797  if (!found) {
798  fei::console_out() << "FEI_Implementation::setRHSScalars: ERROR, invalid RHS ID supplied"
799  << FEI_ENDL;
800  return(1);
801  }
802  }
803 
804  aggregateSystemFormed_ = false;
805  rhsScalarsSet_ = true;
806 
807  return(0);
808 }
809 
810 //------------------------------------------------------------------------------
811 int FEI_Implementation::parameters(int numParams, const char *const* paramStrings)
812 {
813  // this function takes parameters and passes them to the internal
814  // fei objects.
815 
816  if (numParams == 0 || paramStrings == NULL) {
817  debugOut("#--- no parameters");
818  return(0);
819  }
820 
821  // merge these parameters with any others we may have, for later use.
822  snl_fei::mergeStringLists(paramStrings_, numParams_,
823  paramStrings, numParams);
824 
825  snl_fei::getIntParamValue("numMatrices", numParams,paramStrings, numInternalFEIs_);
826 
827  snl_fei::getIntParamValue("outputLevel", numParams,paramStrings, outputLevel_);
828 
829  const char* param = snl_fei::getParamValue("debugOutput",numParams,paramStrings);
830  if (param != NULL) {
831  setDebugOutput(param,"FEI_log");
832  }
833 
834  if (debugOutput_) {
835  (*dbgOStreamPtr_)<<"FEI: parameters"<<FEI_ENDL;
836  (*dbgOStreamPtr_)<<"#FEI_Implementation, num-params "<<FEI_ENDL
837  <<numParams<<FEI_ENDL;
838  (*dbgOStreamPtr_)<<"# "<<numParams<<" parameter lines follow:"<<FEI_ENDL;
839  for(int i=0; i<numParams; i++){
840  (*dbgOStreamPtr_)<<paramStrings[i]<<FEI_ENDL;
841  }
842  }
843 
844  if (haveLinSysCore_) {
845  linSysCore_->parameters(numParams, (char**)paramStrings);
846  }
847  if (haveFEData_) {
848  wrapper_->getFiniteElementData()->parameters(numParams, (char**)paramStrings);
849  }
850 
851  problemStructure_->parameters(numParams, paramStrings);
852 
853  if (internalFEIsAllocated_){
854  for(int i=0; i<numInternalFEIs_; i++){
855  CHK_ERR( filter_[i]->parameters(numParams, paramStrings) );
856  }
857  }
858 
859  debugOut("#FEI_Implementation leaving parameters method");
860 
861  return(0);
862 }
863 
864 //------------------------------------------------------------------------------
865 void FEI_Implementation::setDebugOutput(const char* path, const char* name)
866 {
867  //
868  //This function turns on debug output, and opens a file to put it in.
869  //
870  if (dbgFileOpened_) {
871  dbgFStreamPtr_->close();
872  }
873 
874  dbgFileOpened_ = false;
875  delete dbgOStreamPtr_;
876 
877  FEI_OSTRINGSTREAM osstr;
878  if (path != NULL) {
879  osstr << path << "/";
880  }
881  osstr << name << "." << numProcs_ << "." << localRank_;
882 
883  debugOutput_ = 1;
884  dbgFStreamPtr_ = new FEI_OFSTREAM(osstr.str().c_str(), IOS_APP);
885  if (!dbgFStreamPtr_ || dbgFStreamPtr_->bad()){
886  fei::console_out() << "couldn't open debug output file: " << osstr.str() << FEI_ENDL;
887  debugOutput_ = 0;
888  }
889 
890  if (debugOutput_) {
891  const char* version_str = NULL;
892  version(version_str);
893 
894  (*dbgFStreamPtr_) << version_str << FEI_ENDL;
895 
896  problemStructure_->setDbgOut(*dbgFStreamPtr_, path, "_0");
897  dbgOStreamPtr_ = dbgFStreamPtr_;
898  dbgOStreamPtr_->setf(IOS_SCIENTIFIC, IOS_FLOATFIELD);
899  dbgFileOpened_ = true;
900 
901  if (internalFEIsAllocated_) {
902  for(int i=0; i<numInternalFEIs_; ++i) {
903  filter_[i]->setLogStream(dbgOStreamPtr_);
904  }
905  }
906  }
907 }
908 
909 //------------------------------------------------------------------------------
911  bool globalAssemble)
912 {
913  (void)applyBCs;
914  (void)globalAssemble;
915 
916  buildLinearSystem();
917 
918  return(0);
919 }
920 
921 //------------------------------------------------------------------------------
922 int FEI_Implementation::residualNorm(int whichNorm, int numFields,
923  int* fieldIDs, double* norms)
924 {
925  buildLinearSystem();
926 
927  double residTime = 0.0;
928 
929  int err = filter_[index_soln_filter_]->residualNorm(whichNorm, numFields,
930  fieldIDs, norms, residTime);
931 
932  solveTime_ += residTime;
933 
934  return(err);
935 }
936 
937 //------------------------------------------------------------------------------
939 {
940  buildLinearSystem();
941 
942  double sTime = 0.0;
943 
944  int err = filter_[index_soln_filter_]->solve(status, sTime);
945 
946  solveTime_ += sTime;
947 
948  return(err);
949 }
950 
951 //------------------------------------------------------------------------------
952 int FEI_Implementation::iterations(int& itersTaken) const {
953  itersTaken = filter_[index_soln_filter_]->iterations();
954  return(0);
955 }
956 
957 //------------------------------------------------------------------------------
958 int FEI_Implementation::version(const char*& versionString)
959 {
960  versionString = fei::utils::version();
961  return(0);
962 }
963 
964 //------------------------------------------------------------------------------
966  double& loadTime,
967  double& solveTime,
968  double& solnReturnTime)
969 {
970  initTime = initTime_;
971  loadTime = loadTime_;
972  solveTime = solveTime_;
973  solnReturnTime = solnReturnTime_;
974 
975  return(0);
976 }
977 
978 //------------------------------------------------------------------------------
980  int numNodes,
981  const GlobalID *nodeIDs,
982  int *offsets,
983  double *results)
984 {
985  CHK_ERR(filter_[index_soln_filter_]->getBlockNodeSolution(elemBlockID,
986  numNodes,
987  nodeIDs,
988  offsets,
989  results))
990  return(0);
991 }
992 
993 //------------------------------------------------------------------------------
995  const GlobalID *nodeIDs,
996  int *offsets,
997  double *results)
998 {
999  CHK_ERR(filter_[index_soln_filter_]->getNodalSolution(numNodes,
1000  nodeIDs,
1001  offsets,
1002  results))
1003 
1004  return(0);
1005 }
1006 
1007 //------------------------------------------------------------------------------
1009  int fieldID,
1010  int numNodes,
1011  const GlobalID *nodeIDs,
1012  double *results)
1013 {
1014  CHK_ERR( filter_[index_soln_filter_]->getBlockFieldNodeSolution(elemBlockID,
1015  fieldID, numNodes,
1016  nodeIDs, results))
1017 
1018  return(0);
1019 }
1020 
1021 //------------------------------------------------------------------------------
1023  int numNodes,
1024  const GlobalID *nodeIDs,
1025  const int *offsets,
1026  const double *estimates)
1027 {
1028  CHK_ERR( filter_[index_soln_filter_]->putBlockNodeSolution(elemBlockID,
1029  numNodes, nodeIDs,
1030  offsets, estimates))
1031  return(0);
1032 }
1033 
1034 //------------------------------------------------------------------------------
1036  int fieldID,
1037  int numNodes,
1038  const GlobalID *nodeIDs,
1039  const double *estimates)
1040 {
1041  int err = filter_[index_soln_filter_]->putBlockFieldNodeSolution(elemBlockID,
1042  fieldID, numNodes,
1043  nodeIDs, estimates);
1044  return(err);
1045 }
1046 
1047 //------------------------------------------------------------------------------
1049  int numElems,
1050  const GlobalID *elemIDs,
1051  int& numElemDOFPerElement,
1052  double *results)
1053 {
1054  CHK_ERR( filter_[index_soln_filter_]->getBlockElemSolution(elemBlockID,
1055  numElems, elemIDs,
1056  numElemDOFPerElement,
1057  results))
1058  return(0);
1059 }
1060 
1061 //------------------------------------------------------------------------------
1063  int numElems,
1064  const GlobalID *elemIDs,
1065  int dofPerElem,
1066  const double *estimates)
1067 {
1068  CHK_ERR( filter_[index_soln_filter_]->putBlockElemSolution(elemBlockID,
1069  numElems, elemIDs,
1070  dofPerElem, estimates))
1071  return(0);
1072 }
1073 
1074 //------------------------------------------------------------------------------
1076 {
1077  numMultCRs = problemStructure_->getNumMultConstRecords();
1078  return(0);
1079 }
1080 
1081 //------------------------------------------------------------------------------
1083  int* multIDs)
1084 {
1085  if (numMultCRs > problemStructure_->getNumMultConstRecords()) return(-1);
1086 
1087  std::map<GlobalID,snl_fei::Constraint<GlobalID>*>::const_iterator
1088  cr_iter = problemStructure_->getMultConstRecords().begin(),
1089  cr_end = problemStructure_->getMultConstRecords().end();
1090  int i = 0;
1091  while(cr_iter != cr_end) {
1092  multIDs[i++] = (*cr_iter).first;
1093  ++cr_iter;
1094  }
1095 
1096  return(0);
1097 }
1098 
1099 //------------------------------------------------------------------------------
1101  const int* CRIDs,
1102  double* multipliers)
1103 {
1104  CHK_ERR( filter_[index_soln_filter_]->getCRMultipliers(numMultCRs,
1105  CRIDs, multipliers))
1106  return(0);
1107 }
1108 
1109 //------------------------------------------------------------------------------
1111  const int* CRIDs,
1112  const double *multEstimates)
1113 {
1114  return(
1115  filter_[index_soln_filter_]->putCRMultipliers(numMultCRs,
1116  CRIDs,
1117  multEstimates)
1118  );
1119 }
1120 
1121 //-----------------------------------------------------------------------------
1122 // some utility functions to aid in using the "put" functions for passing
1123 // an initial guess to the solver
1124 //-----------------------------------------------------------------------------
1125 
1126 //------------------------------------------------------------------------------
1128  int numElems,
1129  GlobalID* elemIDs)
1130 {
1131  //
1132  // return the list of element IDs for a given block... the length parameter
1133  // lenElemIDList should be used to check memory allocation for the calling
1134  // method, as the calling method should have gotten a copy of this param
1135  // from a call to getNumBlockElements before allocating memory for elemIDList
1136  //
1137  ConnectivityTable& connTable = problemStructure_->
1138  getBlockConnectivity(elemBlockID);
1139 
1140  std::map<GlobalID,int>& elemIDList = connTable.elemIDs;
1141  int len = elemIDList.size();
1142  if (len > numElems) len = numElems;
1143 
1144  fei::copyKeysToArray(elemIDList, len, elemIDs);
1145 
1146  return(FEI_SUCCESS);
1147 }
1148 
1149 //------------------------------------------------------------------------------
1151  int numNodes,
1152  GlobalID *nodeIDs)
1153 {
1154  //
1155  // similar comments as for getBlockElemIDList(), except for returning the
1156  // active node list
1157  //
1158  int numActiveNodes = problemStructure_->getNumActiveNodes();
1159  NodeDatabase& nodeDB = problemStructure_->getNodeDatabase();
1160 
1161  int blk_idx = problemStructure_->getIndexOfBlock(elemBlockID);
1162  int offset = 0;
1163  for(int i=0; i<numActiveNodes; i++) {
1164  const NodeDescriptor* node = NULL;
1165  nodeDB.getNodeAtIndex(i, node);
1166  if (node==NULL) continue;
1167  if (node->hasBlockIndex(blk_idx))
1168  nodeIDs[offset++] = node->getGlobalNodeID();
1169  if (offset == numNodes) break;
1170  }
1171 
1172  return(FEI_SUCCESS);
1173 }
1174 
1175 //------------------------------------------------------------------------------
1177  int& nodesPerElem) const
1178 {
1179  //
1180  // return the number of nodes associated with elements of a given block ID
1181  //
1182  BlockDescriptor* block = NULL;
1183  CHK_ERR( problemStructure_->getBlockDescriptor(blockID, block) );
1184 
1185  nodesPerElem = block->getNumNodesPerElement();
1186  return(FEI_SUCCESS);
1187 }
1188 
1189 //------------------------------------------------------------------------------
1190 int FEI_Implementation::getNumEqnsPerElement(GlobalID blockID, int& numEqns)
1191 const
1192 {
1193  //
1194  // return the number of eqns associated with elements of a given block ID
1195  //
1196  BlockDescriptor* block = NULL;
1197  CHK_ERR( problemStructure_->getBlockDescriptor(blockID, block) );
1198 
1199  numEqns = block->getNumEqnsPerElement();
1200  return(FEI_SUCCESS);
1201 }
1202 
1203 //------------------------------------------------------------------------------
1204 int FEI_Implementation::getNumSolnParams(GlobalID nodeID, int& numSolnParams)
1205 const {
1206  //
1207  // return the number of solution parameters at a given node
1208  //
1209  const NodeDescriptor* node = NULL;
1210  int err = problemStructure_->getNodeDatabase().getNodeWithID(nodeID, node);
1211 
1212  if (err != 0) {
1213  ERReturn(-1);
1214  }
1215 
1216  numSolnParams = node->getNumNodalDOF();
1217  return(0);
1218 }
1219 
1220 //------------------------------------------------------------------------------
1221 int FEI_Implementation::getNumElemBlocks(int& numElemBlocks) const
1222 {
1223  //
1224  // the number of element blocks
1225  //
1226  numElemBlocks = problemStructure_->getNumElemBlocks();
1227  return( 0 );
1228 }
1229 
1230 //------------------------------------------------------------------------------
1231 int FEI_Implementation::getNumBlockActNodes(GlobalID blockID, int& numNodes)
1232 const {
1233  //
1234  // return the number of active nodes associated with a given element block ID
1235  //
1236  BlockDescriptor* block = NULL;
1237  CHK_ERR( problemStructure_->getBlockDescriptor(blockID, block) );
1238 
1239  numNodes = block->getNumActiveNodes();
1240  return(FEI_SUCCESS);
1241 }
1242 
1243 //------------------------------------------------------------------------------
1244 int FEI_Implementation::getNumBlockActEqns(GlobalID blockID, int& numEqns)
1245 const {
1246 //
1247 // return the number of active equations associated with a given element
1248 // block ID
1249 //
1250  BlockDescriptor* block = NULL;
1251  CHK_ERR( problemStructure_->getBlockDescriptor(blockID, block) );
1252 
1253  numEqns = block->getTotalNumEqns();
1254  return(FEI_SUCCESS);
1255 }
1256 
1257 //------------------------------------------------------------------------------
1258 int FEI_Implementation::getNumBlockElements(GlobalID blockID, int& numElems) const {
1259 //
1260 // return the number of elements associated with a given elem blockID
1261 //
1262  BlockDescriptor* block = NULL;
1263  CHK_ERR( problemStructure_->getBlockDescriptor(blockID, block) );
1264 
1265  numElems = block->getNumElements();
1266  return(FEI_SUCCESS);
1267 }
1268 
1269 //------------------------------------------------------------------------------
1271  int& DOFPerElem) const
1272 {
1273  //
1274  // return the number of elem equations associated with a given elem blockID
1275  //
1276  BlockDescriptor* block = NULL;
1277  CHK_ERR( problemStructure_->getBlockDescriptor(blockID, block) );
1278 
1279  DOFPerElem = block->getNumElemDOFPerElement();
1280 
1281  return(FEI_SUCCESS);
1282 }
1283 
1284 //------------------------------------------------------------------------------
1286  int& numScalars)
1287 {
1288  //
1289  // return the number of scalars associated with a given fieldID
1290  //
1291 
1292  numScalars = problemStructure_->getFieldSize(fieldID);
1293  return(0);
1294 }
1295 
1296 //------------------------------------------------------------------------------
1297 int FEI_Implementation::getEqnNumbers(GlobalID ID, int idType,
1298  int fieldID, int& numEqns,
1299  int* eqnNumbers)
1300 {
1301  //
1302  // Translate from an ID/fieldID pair to a list of equation-numbers
1303  //
1304 
1305  return( problemStructure_->getEqnNumbers(ID, idType, fieldID,
1306  numEqns, eqnNumbers) );
1307 }
1308 
1309 //------------------------------------------------------------------------------
1311  int numNodes,
1312  const GlobalID* nodeIDs,
1313  double* results)
1314 {
1315  return( filter_[index_soln_filter_]->getNodalFieldSolution(fieldID, numNodes,
1316  nodeIDs, results) );
1317 }
1318 
1319 //------------------------------------------------------------------------------
1321 {
1322  numNodes = problemStructure_->getNodeDatabase().getNodeIDs().size();
1323  return( 0 );
1324 }
1325 
1326 //------------------------------------------------------------------------------
1328  GlobalID* nodeIDs,
1329  int lenNodeIDs)
1330 {
1331  std::map<GlobalID,int>& nodes =
1332  problemStructure_->getNodeDatabase().getNodeIDs();
1333  numNodes = nodes.size();
1334  int len = numNodes;
1335  if (lenNodeIDs < len) len = lenNodeIDs;
1336 
1337  fei::copyKeysToArray(nodes, len, nodeIDs);
1338 
1339  return( 0 );
1340 }
1341 
1342 //------------------------------------------------------------------------------
1344  int numNodes,
1345  const GlobalID* nodeIDs,
1346  const double* nodeData)
1347 {
1348  return( filter_[index_soln_filter_]->putNodalFieldData(fieldID, numNodes,
1349  nodeIDs, nodeData) );
1350 }
1351 
1352 //------------------------------------------------------------------------------
1353 void FEI_Implementation::buildLinearSystem()
1354 {
1355  //
1356  //Private function.
1357  //
1358  //At the point when this function is called, all matrix assembly has
1359  //already taken place, with the data having been directed into the
1360  //appropriate Filter instance in the filter_ list. Now it's
1361  //time to finalize the linear system (get A,x,b ready to give to a
1362  //solver), performing this list of last-minute tasks:
1363  //
1364  //1. Have each Filter instance exchangeRemoteEquations.
1365  //2. Aggregate the system (form a linear combination of LHS's and
1366  // RHS's) if solveType_==2.
1367  //3. call loadComplete to have the 'master' Filter instance
1368  // (filter_[index_soln_filter_]) enforce any boundary conditions
1369  // that have been loaded.
1370  //
1371  debugOut("# buildLinearSystem");
1372 
1373  //
1374  //figure out if new matrix-data was loaded on any processor.
1375  int anyDataLoaded = newMatrixDataLoaded_;
1376 #ifndef FEI_SER
1377  if (numProcs_ > 1) {
1378  if (MPI_Allreduce(&newMatrixDataLoaded_, &anyDataLoaded, 1, MPI_INT,
1379  MPI_SUM, comm_) != MPI_SUCCESS) voidERReturn
1380  }
1381 #endif
1382 
1383  if (anyDataLoaded) {
1384 #ifndef FEI_SER
1385  for(int i=0; i<numInternalFEIs_; i++) {
1386  filter_[i]->exchangeRemoteEquations();
1387  }
1388 #endif
1389  newMatrixDataLoaded_ = 0;
1390  }
1391 
1392  if (solveType_ == 2){
1393  //solveType_ == 2 means this is a linear-combination solve --
1394  //i.e., we're solving an aggregate system which is the sum of
1395  //several individual matrices and rhs's.
1396 
1397  if (!aggregateSystemFormed_) {
1398  if (!matScalarsSet_ || !rhsScalarsSet_) {
1399  FEI_COUT << "FEI_Implementation: WARNING: solveType_==2, aggregating system, but setMatScalars and/or setRHSScalars not yet called." << FEI_ENDL;
1400  }
1401 
1402  aggregateSystem();
1403  }
1404  }
1405 
1406  filter_[index_soln_filter_]->loadComplete();
1407 
1408  debugOut("# leaving buildLinearSystem");
1409 }
1410 
1411 //------------------------------------------------------------------------------
1412 int FEI_Implementation::aggregateSystem()
1413 {
1414  debugOut("# aggregateSystem");
1415  if (!haveLinSysCore_) ERReturn(-1);
1416 
1417  if (soln_fei_matrix_ == NULL) {
1418  soln_fei_matrix_ = new Data();
1419 
1420  CHK_ERR( lscArray_[index_soln_filter_]->
1421  copyOutMatrix(1.0, *soln_fei_matrix_) );
1422  }
1423 
1424  if (soln_fei_vector_ == NULL) {
1425  soln_fei_vector_ = new Data();
1426 
1427  CHK_ERR( lscArray_[index_soln_filter_]->
1428  setRHSID(rhsIDs_[index_soln_filter_][0]) );
1429 
1430  CHK_ERR( lscArray_[index_soln_filter_]->
1431  copyOutRHSVector(1.0, *soln_fei_vector_) );
1432  }
1433 
1434  Data tmp;
1435  Data tmpv;
1436 
1437  for(int i=0; i<numInternalFEIs_; i++){
1438 
1439  if (i == index_soln_filter_) {
1440  tmp.setTypeName(soln_fei_matrix_->getTypeName());
1441  tmp.setDataPtr(soln_fei_matrix_->getDataPtr());
1442  CHK_ERR( lscArray_[index_soln_filter_]->
1443  copyInMatrix(matScalars_[i], tmp) );
1444  }
1445  else {
1446  CHK_ERR( lscArray_[i]->getMatrixPtr(tmp) );
1447 
1448  CHK_ERR( lscArray_[index_soln_filter_]->
1449  sumInMatrix(matScalars_[i], tmp) );
1450  }
1451 
1452  for(int j=0; j<numRHSIDs_[i]; j++){
1453  if ((i == index_soln_filter_) && (j == 0)) {
1454  tmpv.setTypeName(soln_fei_vector_->getTypeName());
1455  tmpv.setDataPtr(soln_fei_vector_->getDataPtr());
1456  }
1457  else {
1458  CHK_ERR( lscArray_[i]->setRHSID(rhsIDs_[i][j]) );
1459  CHK_ERR( lscArray_[i]->getRHSVectorPtr(tmpv) );
1460  }
1461 
1462  if (i == index_soln_filter_) {
1463  CHK_ERR( lscArray_[index_soln_filter_]->
1464  copyInRHSVector(rhsScalars_[i][j], tmpv) );
1465  }
1466  else {
1467  CHK_ERR( lscArray_[index_soln_filter_]->
1468  sumInRHSVector(rhsScalars_[i][j], tmpv) );
1469  }
1470  }
1471  }
1472 
1473  aggregateSystemFormed_ = true;
1474 
1475  debugOut("# leaving aggregateSystem");
1476 
1477  return(0);
1478 }
1479 
1480 //==============================================================================
1481 int FEI_Implementation::allocateInternalFEIs(){
1482 //
1483 //This is a private FEI_Implementation function, to be called from within
1484 //setSolveType or the other overloading of allocateInternalFEIs.
1485 //Assumes that numInternalFEIs_ has already been set.
1486 //It is also safe to assume that problemStructure_->initComplete() has already
1487 //been called.
1488 //
1489 
1490  if (internalFEIsAllocated_) return(0);
1491 
1492  matScalars_.resize(numInternalFEIs_);
1493 
1494  if (rhsScalars_.size() != 0) deleteRHSScalars();
1495 
1496  rhsScalars_.resize(numInternalFEIs_);
1497 
1498  for(int i=0; i<numInternalFEIs_; i++){
1499  matScalars_[i] = 1.0;
1500 
1501  rhsScalars_[i] = new double[numRHSIDs_[i]];
1502 
1503  for(int j=0; j<numRHSIDs_[i]; j++){
1504  rhsScalars_[i][j] = 1.0;
1505  }
1506  }
1507 
1508  IDsAllocated_ = true;
1509 
1510  if (numInternalFEIs_ > 0) {
1511  index_soln_filter_ = 0;
1512  index_current_filter_ = 0;
1513  filter_ = new Filter*[numInternalFEIs_];
1514 
1515  if (haveLinSysCore_) {
1516  if (numRHSIDs_[0] == 0) {
1517  int dummyID = -1;
1518  linSysCore_->setNumRHSVectors(1, &dummyID);
1519  }
1520  else {
1521  linSysCore_->setNumRHSVectors(numRHSIDs_[0], rhsIDs_[0]);
1522  }
1523 
1524  for(int i=1; i<numInternalFEIs_; i++) {
1525  fei::SharedPtr<LinearSystemCore> lsc(linSysCore_->clone());
1526  lsc->parameters(numParams_, paramStrings_);
1527 
1528  if (numRHSIDs_[i] == 0) {
1529  int dummyID = -1;
1530  lsc->setNumRHSVectors(1, &dummyID);
1531  }
1532  else {
1533  lsc->setNumRHSVectors(numRHSIDs_[i], rhsIDs_[i]);
1534  }
1535 
1536  lscArray_.push_back(lsc);
1537  }
1538  }
1539 
1540  for(int i=0; i<numInternalFEIs_; i++){
1541 
1542  if (haveLinSysCore_) {
1543  filter_[i] = new LinSysCoreFilter(this, comm_, problemStructure_,
1544  lscArray_[i].get(), masterRank_);
1545  }
1546  else if (haveFEData_) {
1547  filter_[i] = new FEDataFilter(this, comm_, problemStructure_,
1548  wrapper_.get(), masterRank_);
1549  }
1550  else {
1551  fei::console_out() << "FEI_Implementation: ERROR, don't have LinearSystemCore"
1552  << " or FiniteElementData implementation..." << FEI_ENDL;
1553  ERReturn(-1);
1554  }
1555 
1556  filter_[i]->setLogStream(dbgOStreamPtr_);
1557 
1558  FEI_OSTRINGSTREAM osstr;
1559  osstr<<"internalFei "<< i;
1560  std::string osstr_str = osstr.str();
1561  const char* param = osstr_str.c_str();
1562  filter_[i]->parameters(1, &param);
1563 
1564  if (debugOutput_) {
1565  (*dbgOStreamPtr_)<<"#-- fei["<<i<<"]->setNumRHSVectors "
1566  <<numRHSIDs_[i]<<FEI_ENDL;
1567  }
1568 
1569  if (numRHSIDs_[i] == 0) {
1570  int dummyID = -1;
1571  filter_[i]->setNumRHSVectors(1, &dummyID);
1572  }
1573  else {
1574  filter_[i]->setNumRHSVectors(numRHSIDs_[i], rhsIDs_[i]);
1575  }
1576  }
1577 
1578  internalFEIsAllocated_ = true;
1579  }
1580  else {
1581  needParametersAbort("FEI_Implementation::allocateInternalFEIs");
1582  }
1583 
1584  return(0);
1585 }
1586 
1587 //==============================================================================
1588 void FEI_Implementation::debugOut(const char* msg) {
1589  if (debugOutput_) { (*dbgOStreamPtr_)<<msg<<FEI_ENDL; }
1590 }
1591 
1592 //==============================================================================
1593 void FEI_Implementation::debugOut(const char* msg, int whichFEI) {
1594  if (debugOutput_) {
1595  (*dbgOStreamPtr_)<<msg<<", -> fei["<<whichFEI<<"]"<<FEI_ENDL;
1596  }
1597 }
1598 
1599 //==============================================================================
1600 void FEI_Implementation::messageAbort(const char* msg){
1601 
1602  fei::console_out() << "FEI_Implementation: ERROR " << msg << " Aborting." << FEI_ENDL;
1603  MPI_Abort(comm_, -1);
1604 }
1605 
1606 //==============================================================================
1607 void FEI_Implementation::notAllocatedAbort(const char* name){
1608 
1609  fei::console_out() << name
1610  << FEI_ENDL << "ERROR, internal data structures not allocated."
1611  << FEI_ENDL << "'setIDLists' and/or 'setSolveType' must be called"
1612  << FEI_ENDL << "first to identify solveType and number of matrices"
1613  << FEI_ENDL << "to be assembled." << FEI_ENDL;
1614  MPI_Abort(comm_, -1);
1615 }
1616 
1617 //==============================================================================
1618 void FEI_Implementation::needParametersAbort(const char* name){
1619 
1620  fei::console_out() << name
1621  << FEI_ENDL << "FEI_Implementation: ERROR, numMatrices has not been specified."
1622  << FEI_ENDL << "FEI_Implementation: 'parameters' must be called up front with"
1623  << FEI_ENDL << "FEI_Implementation: the string 'numMatrices n' to specify that"
1624  << FEI_ENDL << "FEI_Implementation: n matrices will be assembled." << FEI_ENDL;
1625  MPI_Abort(comm_, -1);
1626 }
1627 
1628 //==============================================================================
1629 void FEI_Implementation::badParametersAbort(const char* name){
1630 
1631  fei::console_out() << name
1632  << FEI_ENDL << "FEI_Implementation: ERROR, inconsistent 'solveType' and"
1633  << FEI_ENDL << "FEI_Implementation: 'numMatrices' parameters specified."
1634  << FEI_ENDL << "FEI_Implementation: Aborting."
1635  << FEI_ENDL;
1636  MPI_Abort(comm_, -1);
1637 }
1638 
int getBlockNodeSolution(GlobalID elemBlockID, int numNodes, const GlobalID *nodeIDs, int *offsets, double *results)
int resetSystem(double s=0.0)
int putBlockFieldNodeSolution(GlobalID elemBlockID, int fieldID, int numNodes, const GlobalID *nodeIDs, const double *estimates)
int getParameters(int &numParams, char **&paramStrings)
int getFieldSize(int fieldID)
int setRHSScalars(int numScalars, const int *IDs, const double *scalars)
std::map< GlobalID, int > & getNodeIDs()
int getNodalFieldSolution(int fieldID, int numNodes, const GlobalID *nodeIDs, double *results)
int putBlockNodeSolution(GlobalID elemBlockID, int numNodes, const GlobalID *nodeIDs, const int *offsets, const double *estimates)
int sumInElem(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *const *elemStiffness, const double *elemLoad, int elemFormat)
int loadElemBCs(int numElems, const GlobalID *elemIDs, int fieldID, const double *const *alpha, const double *const *beta, const double *const *gamma)
FEI_Implementation(fei::SharedPtr< LibraryWrapper > libWrapper, MPI_Comm comm, int masterRank=0)
int loadNodeBCs(int numNodes, const GlobalID *nodeIDs, int fieldID, const int *offsetsIntoField, const double *prescribedValues)
int getNodalSolution(int numNodes, const GlobalID *nodeIDs, int *offsets, double *results)
int initSlaveVariable(GlobalID slaveNodeID, int slaveFieldID, int offsetIntoSlaveField, int numMasterNodes, const GlobalID *masterNodeIDs, const int *masterFieldIDs, const double *weights, double rhsValue)
int iterations(int &itersTaken) const
void setTypeName(const char *name)
Definition: fei_Data.hpp:28
int setIDLists(int numMatrices, const int *matrixIDs, int numRHSs, const int *rhsIDs)
int getBlockFieldNodeSolution(GlobalID elemBlockID, int fieldID, int numNodes, const GlobalID *nodeIDs, double *results)
int getNumElemBlocks(int &numElemBlocks) const
int solve(int &status)
int sumInElemMatrix(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *const *elemStiffness, int elemFormat)
int initCRPen(int numCRNodes, const GlobalID *CRNodes, const int *CRFields, int &CRID)
int version(const char *&versionString)
int initCRMult(int numCRNodes, const GlobalID *CRNodes, const int *CRFields, int &CRID)
int getEqnNumbers(GlobalID ID, int idType, int fieldID, int &numEqns, int *eqnNumbers)
int resetInitialGuess(double s=0.0)
int sumInElemRHS(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *elemLoad)
void copyKeysToArray(const MAP_TYPE &map_obj, unsigned lenList, int *list)
int sumIntoRHS(int IDType, int fieldID, int numIDs, const GlobalID *IDs, const double *rhsEntries)
int initElemBlock(GlobalID elemBlockID, int numElements, int numNodesPerElement, const int *numFieldsPerNode, const int *const *nodalFieldIDs, int numElemDofFieldsPerElement, const int *elemDOFFieldIDs, int interleaveStrategy)
int setSolveType(int solveType)
int getNumBlockActEqns(GlobalID blockID, int &numEqns) const
int loadComplete(bool applyBCs=true, bool globalAssemble=true)
int getBlockNodeIDList(GlobalID elemBlockID, int numNodes, GlobalID *nodeIDs)
int getBlockElemSolution(GlobalID elemBlockID, int numElems, const GlobalID *elemIDs, int &numElemDOFPerElement, double *results)
int initElem(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn)
int getCRMultIDList(int numMultCRs, int *multIDs)
virtual LinearSystemCore * clone()=0
int setCurrentRHS(int rhsID)
void getNodeAtIndex(int i, const NodeDescriptor *&node) const
int getNumEqnsPerElement(GlobalID blockID, int &numEqns) const
int getBlockElemIDList(GlobalID elemBlockID, int numElems, GlobalID *elemIDs)
int cumulative_cpu_times(double &initTime, double &loadTime, double &solveTime, double &solnReturnTime)
T * get() const
int putBlockElemSolution(GlobalID elemBlockID, int numElems, const GlobalID *elemIDs, int dofPerElem, const double *estimates)
int putNodalFieldData(int fieldID, int numNodes, const GlobalID *nodeIDs, const double *nodeData)
int parameters(int numParams, const char *const *paramStrings)
int initFields(int numFields, const int *fieldSizes, const int *fieldIDs, const int *fieldTypes=NULL)
virtual int setNumRHSVectors(int numRHSs, const int *rhsIDs)=0
void * getDataPtr() const
Definition: fei_Data.hpp:38
std::ostream & console_out()
void setDataPtr(void *ptr)
Definition: fei_Data.hpp:35
virtual int destroyVectorData(Data &data)=0
int getNumCRMultipliers(int &numMultCRs)
int getNumNodesPerElement(GlobalID blockID, int &nodesPerElem) const
const char * getTypeName() const
Definition: fei_Data.hpp:32
int putIntoRHS(int IDType, int fieldID, int numIDs, const GlobalID *IDs, const double *rhsEntries)
int localProc(MPI_Comm comm)
int loadCRPen(int CRID, int numCRNodes, const GlobalID *CRNodes, const int *CRFields, const double *CRWeights, double CRValue, double penValue)
int getCRMultipliers(int numCRs, const int *CRIDs, double *multipliers)
const char * version()
Definition: fei_utils.hpp:53
virtual int parameters(int numParams, const char *const *params)=0
int getNumBlockElements(GlobalID blockID, int &numElems) const
int resetMatrix(double s=0.0)
int initSharedNodes(int numSharedNodes, const GlobalID *sharedNodeIDs, const int *numProcsPerNode, const int *const *sharingProcIDs)
int getNumSolnParams(GlobalID nodeID, int &numSolnParams) const
int getNumLocalNodes(int &numNodes)
int loadCRMult(int CRID, int numCRNodes, const GlobalID *CRNodes, const int *CRFields, const double *CRWeights, double CRValue)
int getLocalNodeIDList(int &numNodes, GlobalID *nodeIDs, int lenNodeIDs)
int putCRMultipliers(int numMultCRs, const int *CRIDs, const double *multEstimates)
int setMatScalars(int numScalars, const int *IDs, const double *scalars)
int getNodeWithID(GlobalID nodeID, const NodeDescriptor *&node) const
int parameters(int numParams, const char *const *paramStrings)
int resetRHSVector(double s=0.0)
int getFieldSize(int fieldID, int &numScalars)
int residualNorm(int whichNorm, int numFields, int *fieldIDs, double *norms)
int getNumBlockElemDOF(GlobalID blockID, int &DOFPerElem) const
int searchList(const T &item, const T *list, int len)
virtual int destroyMatrixData(Data &data)=0
int getNumBlockActNodes(GlobalID blockID, int &numNodes) const
int numProcs(MPI_Comm comm)
int getIndexOfBlock(GlobalID blockID) const
int setCurrentMatrix(int matID)