32 #define fei_file "snl_fei_LinearSystem_General.cpp"
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;
74 const char*
const* paramStrings)
76 if (numParams == 0 || paramStrings == NULL)
return(0);
87 resolveConflictRequested_ =
true;
91 numParams,paramStrings);
93 bcs_trump_slaves_ =
true;
98 explicitBCenforcement_ =
true;
101 param =
snl_fei::getParam(
"BC_ENFORCEMENT_NO_COLUMN_MOD",numParams,paramStrings);
103 BCenforcement_no_column_mod_ =
true;
111 if (matrix_.get() != NULL) {
114 if (matred != NULL) {
119 if (lscmatrix != NULL) {
131 const char** paramStrings = NULL;
132 std::vector<std::string> stdstrings;
136 int err =
parameters(numParams, paramStrings);
138 delete [] paramStrings;
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)
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)
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);
205 os << dbgprefix_<<
"loadComplete"<<
FEI_ENDL;
208 if (dbcManager_ == NULL) {
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++;
238 if (opath ==
"") opath =
".";
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() );
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;
279 os << dbgprefix_<<
"Neqns=" << matrix_->getGlobalNumRows();
280 int globalNumSlaveCRs = matrixGraph_->getGlobalNumSlaveConstraints();
281 if (globalNumSlaveCRs > 0) {
282 os <<
", Global NslaveCRs=" << globalNumSlaveCRs;
289 if (opath ==
"") opath =
".";
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) {
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);
377 bool resolveConflictRequested,
378 bool bcs_trump_slaves)
394 int numIndices = numSlaves>0 ?
398 bool zeroSharedRows =
false;
406 *bcEqns : *bcEqns_reducer;
410 if (resolveConflictRequested) {
412 std::vector<int> bcEqnNumbers;
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) {
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];
450 if (essBCvalues_ != NULL) {
457 essBCvalues_, resolveConflictRequested_,
458 bcs_trump_slaves_) );
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_) {
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);
505 if (matred != NULL) {
511 if (lscmatrix == 0) {
515 int localsize = matrixGraph_->getRowSpace()->getNumIndices_Owned();
517 if (matrixGraph_->getGlobalNumSlaveConstraints() > 0) {
522 bool zeroSharedRows =
false;
527 matrixGraph_->getRemotelyOwnedGraphRows();
529 if (!BCenforcement_no_column_mod_) {
537 os <<
"#enforceEssentialBC_LinSysCore RemEssBCs to enforce: "
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);
553 for(
int i=0; i<numEqns; ++i) {
556 colIndLengths[i] = rowOffsets[i+1] - rowOffsets[i];
559 int** colInds = &colIndices[0];
560 int* colIndLens = &colIndLengths[0];
561 double** BCcoefs = &coefs[0];
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);
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++) {
643 if (eqn < firstLocalOffset_ || eqn > lastLocalOffset_)
continue;
646 double bcValue = bcCoefs[i];
647 int err = rhs_->copyIn(1, &eqn, &bcValue);
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);
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) {
682 osstr <<
"fei::LinearSystem::enforceEssentialBC: ERROR, caught exception: "
684 throw std::runtime_error(osstr.str());
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) {
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) {
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);
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);
817 os <<
"enfEssBC_step2: rhs["<<i<<
"] += "<<value<<
FEI_ENDL;
825 std::vector<double>& coefs,
826 std::vector<int>& indices)
836 if ((
int)coefs.size() != len) {
839 if ((
int)indices.size() != len) {
850 const double *weights,
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,
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)
int getMatrixRow(fei::Matrix *matrix, int row, std::vector< double > &coefs, std::vector< int > &indices)
int extractDirichletBCs(fei::DirichletBCManager *bcManager, fei::SharedPtr< fei::MatrixGraph > matrixGraph, fei::CSVec *essBCvalues, bool resolveConflictRequested, bool bcs_trump_slaves)
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()
unsigned getNumRows() const
void enforceEssentialBC_step_2(fei::CSVec &essBCs)
fei::OutputLevel string_to_output_level(const std::string &str)
std::vector< int > & indices()
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)
int gatherRemoteEssBCs(fei::CSVec &essBCs, fei::SparseRowGraph *remoteGraph, fei::Matrix &matrix)
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)
void put_entry(CSVec &vec, int eqn, double coef)
int getGlobalIndex(int idType, int ID, int fieldID, int fieldOffset, int whichComponentOfField, int &globalIndex)
int implementBCs(bool applyBCs)
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
void global_union(MPI_Comm comm, const fei::FillableMat &localMatrix, fei::FillableMat &globalUnionMatrix)
int binarySearch(const T &item, const T *list, int len)
std::vector< double > & getMasterWeights()
int getConstraintID() const
int enforceEssentialBC_LinSysCore()
void setName(const char *name)
int finalizeBCEqns(fei::Matrix &matrix, bool throw_if_bc_slave_conflict=false)
int resolveConflictingCRs(fei::MatrixGraph &matrixGraph, fei::Matrix &bcEqns, const std::vector< int > &bcEqnNumbers)
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()
void enforceEssentialBC_step_1(fei::CSVec &essBCs)
virtual ~LinearSystem_General()
const char * getParam(const char *key, int numParams, const char *const *paramStrings)
fei::SharedPtr< fei::Matrix > getTargetMatrix()
int loadLagrangeConstraint(int constraintID, const double *weights, double rhsValue)
SparseRowGraph & getGraph()
void getGlobalIndexOffsets(std::vector< int > &globalOffsets) const
int translateFromReducedEqn(int reduced_eqn) const
void separate_BC_eqns(const fei::FillableMat &mat, std::vector< int > &bcEqns, std::vector< double > &bcVals)
std::vector< int > & getLocalReducedEqns()
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
unsigned getNumRows() const
bool isSlaveEqn(int unreducedEqn) const
std::vector< double > & getPackedCoefs()
#define FEI_OSTRINGSTREAM
const char * getParamValue(const char *key, int numParams, const char *const *paramStrings, char separator=' ')
virtual int copyOutRow(int row, int len, double *coefs, int *indices) const =0
int numProcs(MPI_Comm comm)
std::vector< double > & coefs()
int getNumIndices_Owned() const