9 #include <fei_macros.hpp>
10 #include <fei_utils.hpp>
14 #include <snl_fei_LinearSystem_General.hpp>
15 #include <fei_MatrixReducer.hpp>
16 #include <fei_Matrix_Impl.hpp>
17 #include <fei_VectorSpace.hpp>
18 #include <fei_MatrixGraph.hpp>
19 #include <fei_SparseRowGraph.hpp>
20 #include <snl_fei_Constraint.hpp>
21 #include <fei_Record.hpp>
22 #include <fei_utils.hpp>
23 #include <fei_impl_utils.hpp>
24 #include <fei_LogManager.hpp>
26 #include <fei_DirichletBCRecord.hpp>
27 #include <fei_DirichletBCManager.hpp>
28 #include <fei_EqnBuffer.hpp>
29 #include <fei_LinSysCoreFilter.hpp>
32 #define fei_file "snl_fei_LinearSystem_General.cpp"
33 #include <fei_ErrMacros.hpp>
37 : fei::LinearSystem(matrixGraph),
38 comm_(matrixGraph->getRowSpace()->getCommunicator()),
40 resolveConflictRequested_(false),
41 bcs_trump_slaves_(false),
42 explicitBCenforcement_(false),
43 BCenforcement_no_column_mod_(false),
47 named_loadcomplete_counter_(),
50 dbgprefix_(
"LinSysG: ")
57 std::vector<int> offsets;
60 firstLocalOffset_ = offsets[localProc_];
61 lastLocalOffset_ = offsets[localProc_+1]-1;
74 const char*
const* paramStrings)
76 if (numParams == 0 || paramStrings == NULL)
return(0);
78 const char* param = snl_fei::getParam(
"name", numParams, paramStrings);
80 if (strlen(param) < 6) ERReturn(-1);
85 param = snl_fei::getParam(
"resolveConflict",numParams,paramStrings);
87 resolveConflictRequested_ =
true;
90 param = snl_fei::getParam(
"BCS_TRUMP_SLAVE_CONSTRAINTS",
91 numParams,paramStrings);
93 bcs_trump_slaves_ =
true;
96 param = snl_fei::getParam(
"EXPLICIT_BC_ENFORCEMENT",numParams,paramStrings);
98 explicitBCenforcement_ =
true;
101 param = snl_fei::getParam(
"BC_ENFORCEMENT_NO_COLUMN_MOD",numParams,paramStrings);
103 BCenforcement_no_column_mod_ =
true;
106 param = snl_fei::getParamValue(
"FEI_OUTPUT_LEVEL",numParams,paramStrings);
111 if (matrix_.get() != NULL) {
113 fei::MatrixReducer* matred =
dynamic_cast<fei::MatrixReducer*
>(matptr);
114 if (matred != NULL) {
115 matptr = matred->getTargetMatrix().get();
119 if (lscmatrix != NULL) {
131 const char** paramStrings = NULL;
132 std::vector<std::string> stdstrings;
136 int err = parameters(numParams, paramStrings);
138 delete [] paramStrings;
144 void snl_fei::LinearSystem_General::setName(
const char* name)
146 if (name == NULL)
return;
148 if (name_ == name)
return;
152 std::map<std::string,unsigned>::iterator
153 iter = named_loadcomplete_counter_.find(name_);
154 if (iter == named_loadcomplete_counter_.end()) {
155 static int counter = 0;
156 named_loadcomplete_counter_.insert(std::make_pair(name_, counter));
167 const double* prescribedValues)
169 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != 0) {
170 FEI_OSTREAM& os = *output_stream_;
171 os <<
"loadEssentialBCs, numIDs: "<<numIDs<<
", idType: " <<idType
172 <<
", fieldID: "<<fieldID<<
", offsetIntoField: "<<offsetIntoField<<FEI_ENDL;
176 offsetIntoField, prescribedValues);
184 const int* offsetsIntoField,
185 const double* prescribedValues)
187 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != 0) {
188 FEI_OSTREAM& os = *output_stream_;
189 for(
int i=0; i<numIDs; ++i) {
190 os <<
"loadEssentialBCs idType: " <<idType
191 <<
", fieldID: "<<fieldID<<
", ID: " << IDs[i]<<
", offsetIntoField: "<<offsetsIntoField[i]<<
", val: " << prescribedValues[i] << FEI_ENDL;
196 offsetsIntoField, prescribedValues);
203 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != 0) {
204 FEI_OSTREAM& os = *output_stream_;
205 os << dbgprefix_<<
"loadComplete"<<FEI_ENDL;
208 if (dbcManager_ == NULL) {
209 dbcManager_ =
new fei::DirichletBCManager(matrixGraph_->getRowSpace());
212 if (globalAssemble) {
214 if (matrix_.get() != NULL) {
215 CHK_ERR( matrix_->gatherFromOverlap() );
218 if (rhs_.get() != NULL) {
219 CHK_ERR( rhs_->gatherFromOverlap() );
224 unsigned counter = 0;
226 std::map<std::string,unsigned>::iterator
227 iter = named_loadcomplete_counter_.find(name_);
228 if (iter == named_loadcomplete_counter_.end()) {
229 FEI_COUT <<
"fei::LinearSystem::loadComplete internal error, name "
230 << name_ <<
" not found." << FEI_ENDL;
233 counter = iter->second++;
236 if (output_level_ >= fei::FULL_LOGS) {
238 if (opath ==
"") opath =
".";
240 FEI_OSTRINGSTREAM Aname;
241 FEI_OSTRINGSTREAM bname;
242 FEI_OSTRINGSTREAM xname;
243 Aname << opath <<
"/";
244 bname << opath <<
"/";
245 xname << opath <<
"/";
247 Aname <<
"A_"<<name_<<
".preBC.np"<<numProcs_<<
".slv"<<counter<<
".mtx";
249 bname <<
"b_"<<name_<<
".preBC.np"<<numProcs_<<
".slv"<<counter<<
".vec";
251 std::string Aname_str = Aname.str();
252 const char* Aname_c_str = Aname_str.c_str();
253 CHK_ERR( matrix_->writeToFile(Aname_c_str) );
255 std::string bname_str = bname.str();
256 const char* bname_c_str = bname_str.c_str();
257 CHK_ERR( rhs_->writeToFile(bname_c_str) );
260 CHK_ERR( implementBCs(applyBCs) );
262 if (globalAssemble) {
263 CHK_ERR( matrix_->globalAssemble() );
266 if (output_level_ == fei::STATS || output_level_ == fei::ALL) {
267 int globalNumSlaveCRs = matrixGraph_->getGlobalNumSlaveConstraints();
268 if (localProc_ == 0) {
269 FEI_COUT <<
"Global Neqns: " << matrix_->getGlobalNumRows();
270 if (globalNumSlaveCRs > 0) {
271 FEI_COUT <<
", Global NslaveCRs: " << globalNumSlaveCRs;
273 FEI_COUT << FEI_ENDL;
277 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
278 FEI_OSTREAM& os = *output_stream_;
279 os << dbgprefix_<<
"Neqns=" << matrix_->getGlobalNumRows();
280 int globalNumSlaveCRs = matrixGraph_->getGlobalNumSlaveConstraints();
281 if (globalNumSlaveCRs > 0) {
282 os <<
", Global NslaveCRs=" << globalNumSlaveCRs;
287 if (output_level_ >= fei::MATRIX_FILES) {
289 if (opath ==
"") opath =
".";
291 FEI_OSTRINGSTREAM Aname;
292 FEI_OSTRINGSTREAM bname;
293 FEI_OSTRINGSTREAM xname;
294 Aname << opath <<
"/";
295 bname << opath <<
"/";
296 xname << opath <<
"/";
298 Aname <<
"A_" <<name_<<
".np"<<numProcs_<<
".slv" << counter <<
".mtx";
300 bname <<
"b_" <<name_<<
".np"<<numProcs_<<
".slv" << counter <<
".vec";
302 xname <<
"x0_" <<name_<<
".np"<<numProcs_<<
".slv" << counter <<
".vec";
304 std::string Aname_str = Aname.str();
305 const char* Aname_c_str = Aname_str.c_str();
306 CHK_ERR( matrix_->writeToFile(Aname_c_str) );
308 std::string bname_str = bname.str();
309 const char* bname_c_str = bname_str.c_str();
310 CHK_ERR( rhs_->writeToFile(bname_c_str) );
312 std::string xname_str = xname.str();
313 const char* xname_c_str = xname_str.c_str();
314 CHK_ERR( soln_->writeToFile(xname_c_str) );
323 if (essBCvalues_ == NULL) {
327 if (essBCvalues_->size() == 0) {
331 CHK_ERR( vector->
copyIn(essBCvalues_->size(),
332 &(essBCvalues_->indices())[0],
333 &(essBCvalues_->coefs())[0]) );
341 if (essBCvalues_ == NULL)
return(
false);
343 std::vector<int>& indices = essBCvalues_->indices();
345 return( offset < 0 ?
false :
true);
350 std::vector<double>& bcVals)
const
354 if (essBCvalues_ == NULL)
return;
356 int num = essBCvalues_->size();
359 int* essbcs = &(essBCvalues_->indices())[0];
360 double* vals = &(essBCvalues_->coefs())[0];
361 for(
int i=0; i<num; ++i) {
362 bcEqns[i] = essbcs[i];
370 matrixGraph_->getConstrainedIndices(crEqns);
374 int extractDirichletBCs(fei::DirichletBCManager* bcManager,
377 bool resolveConflictRequested,
378 bool bcs_trump_slaves)
394 int numIndices = numSlaves>0 ?
395 reducer->getLocalReducedEqns().size() :
398 bool zeroSharedRows =
false;
402 bcEqns_reducer.
reset(
new fei::MatrixReducer(reducer, bcEqns));
406 *bcEqns : *bcEqns_reducer;
408 CHK_ERR( bcManager->finalizeBCEqns(bcEqns_mat, bcs_trump_slaves) );
410 if (resolveConflictRequested) {
412 std::vector<int> bcEqnNumbers;
414 CHK_ERR( snl_fei::resolveConflictingCRs(*matrixGraph, bcEqns_mat,
418 std::vector<int> essEqns;
419 std::vector<double> values;
421 std::map<int,fei::FillableMat*>& remotes = bcEqns->getRemotelyOwnedMatrices();
422 std::map<int,fei::FillableMat*>::iterator
423 it = remotes.begin(),
424 it_end = remotes.end();
425 for(; it!=it_end; ++it) {
426 fei::impl_utils::separate_BC_eqns( *(it->second), essEqns, values);
431 fei::impl_utils::separate_BC_eqns( *(bcEqns->getMatrix()), essEqns, values);
433 if (essEqns.size() > 0) {
434 int* essEqnsPtr = &essEqns[0];
435 double* valuesPtr = &values[0];
437 for(
unsigned i=0; i<essEqns.size(); ++i) {
438 int eqn = essEqnsPtr[i];
439 double value = valuesPtr[i];
440 fei::put_entry(*essBCvalues, eqn, value);
448 int snl_fei::LinearSystem_General::implementBCs(
bool applyBCs)
450 if (essBCvalues_ != NULL) {
456 CHK_ERR( extractDirichletBCs(dbcManager_, matrixGraph_,
457 essBCvalues_, resolveConflictRequested_,
458 bcs_trump_slaves_) );
460 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
461 FEI_OSTREAM& os = *output_stream_;
462 std::vector<int>& indices = essBCvalues_->indices();
463 std::vector<double>& coefs= essBCvalues_->coefs();
464 for(
size_t i=0; i<essBCvalues_->size(); ++i) {
465 os <<
"essBCeqns["<<i<<
"]: "<<indices[i]<<
", "<<coefs[i]<<FEI_ENDL;
473 int returncode = enforceEssentialBC_LinSysCore();
474 if (returncode == 0) {
479 if (!BCenforcement_no_column_mod_) {
480 fei::impl_utils::global_union(comm_, *essBCvalues_, allEssBCs);
482 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
483 FEI_OSTREAM& os = *output_stream_;
484 os <<
" implementBCs, essBCvalues_.size(): "<<essBCvalues_->size()
485 <<
", allEssBCs.size(): " << allEssBCs.size()<<FEI_ENDL;
489 if (essBCvalues_->size() > 0) {
490 enforceEssentialBC_step_1(*essBCvalues_);
493 if (!BCenforcement_no_column_mod_ && allEssBCs.size() > 0) {
494 enforceEssentialBC_step_2(allEssBCs);
501 int snl_fei::LinearSystem_General::enforceEssentialBC_LinSysCore()
504 fei::MatrixReducer* matred =
dynamic_cast<fei::MatrixReducer*
>(matptr);
505 if (matred != NULL) {
506 matptr = matred->getTargetMatrix().get();
511 if (lscmatrix == 0) {
515 int localsize = matrixGraph_->getRowSpace()->getNumIndices_Owned();
517 if (matrixGraph_->getGlobalNumSlaveConstraints() > 0) {
518 localsize = reducer->getLocalReducedEqns().size();
522 bool zeroSharedRows =
false;
527 matrixGraph_->getRemotelyOwnedGraphRows();
529 if (!BCenforcement_no_column_mod_) {
530 CHK_ERR( snl_fei::gatherRemoteEssBCs(*essBCvalues_, remoteGraph.
get(), *matrix) );
533 unsigned numBCRows = inner->getNumRows();
535 if (output_stream_ != NULL && output_level_ >= fei::BRIEF_LOGS) {
536 FEI_OSTREAM& os = *output_stream_;
537 os <<
"#enforceEssentialBC_LinSysCore RemEssBCs to enforce: "
538 << numBCRows << FEI_ENDL;
541 if (numBCRows > 0 && !BCenforcement_no_column_mod_) {
542 std::vector<int*> colIndices(numBCRows);
543 std::vector<double*> coefs(numBCRows);
544 std::vector<int> colIndLengths(numBCRows);
549 int numEqns = csrmat.getNumRows();
553 for(
int i=0; i<numEqns; ++i) {
555 coefs[i] = &(csrmat.getPackedCoefs()[rowOffsets[i]]);
556 colIndLengths[i] = rowOffsets[i+1] - rowOffsets[i];
559 int** colInds = &colIndices[0];
560 int* colIndLens = &colIndLengths[0];
561 double** BCcoefs = &coefs[0];
563 if (output_stream_ != NULL && output_level_ > fei::BRIEF_LOGS) {
564 FEI_OSTREAM& os = *output_stream_;
565 for(
int i=0; i<numEqns; ++i) {
566 os <<
"remBCeqn: " << eqns[i] <<
", inds/coefs: ";
567 for(
int j=0; j<colIndLens[i]; ++j) {
568 os <<
"("<<colInds[i][j]<<
","<<BCcoefs[i][j]<<
") ";
584 int numEqns = essBCvalues_->size();
586 int* eqns = &(essBCvalues_->indices())[0];
587 double* bccoefs = &(essBCvalues_->coefs())[0];
588 std::vector<double> ones(numEqns, 1.0);
598 void snl_fei::LinearSystem_General::enforceEssentialBC_step_1(
fei::CSVec& essBCs)
618 int numEqns = essBCs.size();
619 int* eqns = &(essBCs.indices())[0];
620 double* bcCoefs = &(essBCs.coefs())[0];
622 std::vector<double> coefs;
623 std::vector<int> indices;
626 bool haveSlaves = reducer.
get()!=NULL;
629 for(
int i=0; i<numEqns; i++) {
640 eqn = reducer->translateFromReducedEqn(eqn);
643 if (eqn < firstLocalOffset_ || eqn > lastLocalOffset_)
continue;
646 double bcValue = bcCoefs[i];
647 int err = rhs_->copyIn(1, &eqn, &bcValue);
649 FEI_OSTRINGSTREAM osstr;
650 osstr <<
"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: "
651 <<
"err="<<err<<
" returned from rhs_->copyIn row="<<eqn;
652 throw std::runtime_error(osstr.str());
655 err = getMatrixRow(matrix_.get(), eqn, coefs, indices);
656 if (err != 0 || indices.size() < 1) {
660 int rowLen = indices.size();
661 int* indPtr = &indices[0];
664 for(
int j=0; j<rowLen; j++) {
665 if (indPtr[j] == eqn) coefs[j] = 1.0;
669 double* coefPtr = &coefs[0];
671 err = matrix_->copyIn(1, &eqn, rowLen, indPtr, &coefPtr);
673 FEI_OSTRINGSTREAM osstr;
674 osstr <<
"snl_fei::LinearSystem_General::enforceEssentialBC_step_1 ERROR: "
675 <<
"err="<<err<<
" returned from matrix_->copyIn row="<<eqn;
676 throw std::runtime_error(osstr.str());
680 catch(std::runtime_error& exc) {
681 FEI_OSTRINGSTREAM osstr;
682 osstr <<
"fei::LinearSystem::enforceEssentialBC: ERROR, caught exception: "
684 throw std::runtime_error(osstr.str());
689 void snl_fei::LinearSystem_General::enforceEssentialBC_step_2(
fei::CSVec& essBCs)
709 int numBCeqns = essBCs.size();
714 int* bcEqns = &(essBCs.indices())[0];
715 double* bcCoefs = &(essBCs.coefs())[0];
718 bool haveSlaves = reducer.
get()!=NULL;
720 for(
int i=0; i<numBCeqns; ++i) {
721 bcEqns[i] = reducer->translateFromReducedEqn(bcEqns[i]);
725 int firstBCeqn = bcEqns[0];
726 int lastBCeqn = bcEqns[numBCeqns-1];
728 std::vector<double> coefs;
729 std::vector<int> indices;
733 int nextBCeqnOffset = 0;
734 int nextBCeqn = bcEqns[nextBCeqnOffset];
736 for(
int i=firstLocalOffset_; i<=lastLocalOffset_; ++i) {
738 if (reducer->isSlaveEqn(i))
continue;
741 bool should_continue =
false;
742 if (i >= nextBCeqn) {
743 if (i == nextBCeqn) {
745 if (nextBCeqnOffset < numBCeqns) {
746 nextBCeqn = bcEqns[nextBCeqnOffset];
749 nextBCeqn = lastLocalOffset_+1;
752 should_continue =
true;
755 while(nextBCeqn <= i) {
756 if (nextBCeqn == i) should_continue =
true;
758 if (nextBCeqnOffset < numBCeqns) {
759 nextBCeqn = bcEqns[nextBCeqnOffset];
762 nextBCeqn = lastLocalOffset_+1;
768 if (should_continue)
continue;
770 int err = getMatrixRow(matrix_.get(), i, coefs, indices);
771 if (err != 0 || indices.size() < 1) {
775 int numIndices = indices.size();
776 int* indicesPtr = &indices[0];
777 double* coefsPtr = &coefs[0];
778 bool modifiedCoef =
false;
782 if (indicesPtr[0] > lastBCeqn || indicesPtr[numIndices-1] < firstBCeqn) {
789 for(
int j=0; j<numIndices; ++j) {
790 int idx = indicesPtr[j];
794 value -= bcCoefs[offset]*coefsPtr[j];
802 err = matrix_->copyIn(1, &i, numIndices, indicesPtr, &coefsPtr);
804 FEI_OSTRINGSTREAM osstr;
805 osstr <<
"snl_fei::LinearSystem_General::enforceEssentialBC_step_2 ERROR: "
806 <<
"err="<<err<<
" returned from matrix_->copyIn, row="<<i;
807 throw std::runtime_error(osstr.str());
811 const double fei_eps = 1.e-49;
812 if (std::abs(value) > fei_eps) {
813 rhs_->sumIn(1, &i, &value);
815 if (output_level_ >= fei::FULL_LOGS && output_stream_ != 0) {
816 FEI_OSTREAM& os = *output_stream_;
817 os <<
"enfEssBC_step2: rhs["<<i<<
"] += "<<value<<FEI_ENDL;
824 int snl_fei::LinearSystem_General::getMatrixRow(
fei::Matrix* matrix,
int row,
825 std::vector<double>& coefs,
826 std::vector<int>& indices)
836 if ((
int)coefs.size() != len) {
839 if ((
int)indices.size() != len) {
843 CHK_ERR( matrix->
copyOutRow(row, len, &coefs[0], &indices[0]));
850 const double *weights,
853 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
854 FEI_OSTREAM& os = *output_stream_;
855 os <<
"loadLagrangeConstraint crID: "<<constraintID<<FEI_ENDL;
859 matrixGraph_->getLagrangeConstraint(constraintID);
864 CHK_ERR( matrixGraph_->getConstraintConnectivityIndices(cr, iwork_) );
868 cr_weights.resize(iwork_.size());
869 for(
unsigned i=0; i<iwork_.size(); ++i) {
870 cr_weights.push_back(weights[i]);
881 int numIndices = iwork_.size();
882 int* indicesPtr = &(iwork_[0]);
884 CHK_ERR( matrix_->sumIn(1, &crEqn, numIndices, indicesPtr, &weights) );
886 CHK_ERR( rhs_->sumIn(1, &crEqn, &rhsValue) );
889 for(
int k=0; k<numIndices; ++k) {
890 double* thisWeight = (
double*)(&(weights[k]));
891 CHK_ERR( matrix_->sumIn(1, &(indicesPtr[k]), 1, &crEqn, &thisWeight) );
899 const double *weights,
903 if (output_level_ >= fei::BRIEF_LOGS && output_stream_ != NULL) {
904 FEI_OSTREAM& os = *output_stream_;
905 os <<
"loadPenaltyConstraint crID: "<<constraintID<<FEI_ENDL;
909 matrixGraph_->getPenaltyConstraint(constraintID);
914 CHK_ERR( matrixGraph_->getConstraintConnectivityIndices(cr, iwork_) );
918 int numIndices = iwork_.size();
919 int* indicesPtr = &(iwork_[0]);
922 std::vector<double> coefs(numIndices);
923 double* coefPtr = &coefs[0];
924 for(
int i=0; i<numIndices; ++i) {
925 for(
int j=0; j<numIndices; ++j) {
926 coefPtr[j] = weights[i]*weights[j]*penaltyValue;
928 CHK_ERR( matrix_->sumIn(1, &(indicesPtr[i]), numIndices, indicesPtr,
931 double rhsCoef = weights[i]*penaltyValue*rhsValue;
932 CHK_ERR( rhs_->sumIn(1, &(indicesPtr[i]), &rhsCoef) );
void strings_to_char_ptrs(std::vector< std::string > &stdstrings, int &numStrings, const char **&charPtrs)
virtual int getGlobalNumSlaveConstraints() const =0
virtual int loadEssentialBCs(int numIDs, const int *IDs, int idType, int fieldID, int offsetIntoField, const double *prescribedValues)
int loadEssentialBCs(int numIDs, const int *IDs, int idType, int fieldID, int offsetIntoField, const double *prescribedValues)
void convert_ParameterSet_to_strings(const fei::ParameterSet *paramset, std::vector< std::string > ¶mStrings)
virtual int copyIn(int numValues, const int *indices, const double *values, int vectorIndex=0)=0
int setBCValuesOnVector(fei::Vector *vector)
const std::string & getOutputPath()
fei::OutputLevel string_to_output_level(const std::string &str)
virtual fei::SharedPtr< fei::Reducer > getReducer()=0
std::vector< int > rowNumbers
int parameters(int numParams, const char *const *paramStrings)
void insertion_sort_with_companions(int len, int *array, T *companions)
int loadPenaltyConstraint(int constraintID, const double *weights, double penaltyValue, double rhsValue)
int loadComplete(bool applyBCs=true, bool globalAssemble=true)
virtual int enforceEssentialBC(int *globalEqn, double *alpha, double *gamma, int len)=0
void getConstrainedEqns(std::vector< int > &crEqns) const
void get_row_numbers(const FillableMat &mat, std::vector< int > &rows)
std::vector< int > packedColumnIndices
std::vector< int > rowOffsets
LinearSystem_General(fei::SharedPtr< fei::MatrixGraph > &matrixGraph)
int getGlobalIndex(int idType, int ID, int fieldID, int fieldOffset, int whichComponentOfField, int &globalIndex)
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
int binarySearch(const T &item, const T *list, int len)
std::vector< double > & getMasterWeights()
int getConstraintID() const
void getEssentialBCs(std::vector< int > &bcEqns, std::vector< double > &bcVals) const
bool eqnIsEssentialBC(int globalEqnIndex) const
virtual int getRowLength(int row, int &length) const =0
fei::SharedPtr< T > getMatrix()
virtual ~LinearSystem_General()
int loadLagrangeConstraint(int constraintID, const double *weights, double rhsValue)
void getGlobalIndexOffsets(std::vector< int > &globalOffsets) const
int localProc(MPI_Comm comm)
static LogManager & getLogManager()
virtual int parameters(int numParams, const char *const *params)=0
virtual int enforceRemoteEssBCs(int numEqns, int *globalEqns, int **colIndices, int *colIndLen, double **coefs)=0
virtual int copyOutRow(int row, int len, double *coefs, int *indices) const =0
int numProcs(MPI_Comm comm)
int getNumIndices_Owned() const