32#define fei_file "snl_fei_LinearSystem_General.cpp"
38 comm_(matrixGraph->getRowSpace()->getCommunicator()),
57 std::vector<int> offsets;
58 vecSpace->getGlobalIndexOffsets(offsets);
74 const char*
const* paramStrings)
76 if (numParams == 0 || paramStrings == NULL)
return(0);
91 numParams,paramStrings);
101 param =
snl_fei::getParam(
"BC_ENFORCEMENT_NO_COLUMN_MOD",numParams,paramStrings);
114 if (matred != NULL) {
119 if (lscmatrix != NULL) {
120 lscmatrix->
getMatrix()->parameters(numParams, (
char**)paramStrings);
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
155 static int counter = 0;
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);
212 if (globalAssemble) {
218 if (
rhs_.get() != NULL) {
224 unsigned counter = 0;
226 std::map<std::string,unsigned>::iterator
229 FEI_COUT <<
"fei::LinearSystem::loadComplete internal error, name "
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();
255 std::string bname_str = bname.str();
256 const char* bname_c_str = bname_str.c_str();
262 if (globalAssemble) {
267 int globalNumSlaveCRs =
matrixGraph_->getGlobalNumSlaveConstraints();
270 if (globalNumSlaveCRs > 0) {
271 FEI_COUT <<
", Global NslaveCRs: " << globalNumSlaveCRs;
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();
308 std::string bname_str = bname.str();
309 const char* bname_c_str = bname_str.c_str();
312 std::string xname_str = xname.str();
313 const char* xname_c_str = xname_str.c_str();
345 return( offset < 0 ?
false :
true);
350 std::vector<double>& bcVals)
const
361 for(
int i=0; i<num; ++i) {
362 bcEqns[i] = essbcs[i];
377 bool resolveConflictRequested,
378 bool bcs_trump_slaves)
391 int numSlaves = matrixGraph->getGlobalNumSlaveConstraints();
394 int numIndices = numSlaves>0 ?
395 reducer->getLocalReducedEqns().size() :
396 matrixGraph->getRowSpace()->getNumIndices_Owned();
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];
465 os <<
"essBCeqns["<<i<<
"]: "<<indices[i]<<
", "<<coefs[i]<<
FEI_ENDL;
474 if (returncode == 0) {
484 os <<
" implementBCs, essBCvalues_.size(): "<<
essBCvalues_->size()
485 <<
", allEssBCs.size(): " << allEssBCs.
size()<<
FEI_ENDL;
505 if (matred != NULL) {
511 if (lscmatrix == 0) {
515 int localsize =
matrixGraph_->getRowSpace()->getNumIndices_Owned();
518 localsize = reducer->getLocalReducedEqns().size();
522 bool zeroSharedRows =
false;
533 unsigned numBCRows = inner->getNumRows();
537 os <<
"#enforceEssentialBC_LinSysCore RemEssBCs to enforce: "
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]<<
") ";
574 int errcode = lscmatrix->
getMatrix()->enforceRemoteEssBCs(numEqns,
588 std::vector<double> ones(numEqns, 1.0);
590 return(lscmatrix->
getMatrix()->enforceEssentialBC(eqns, &ones[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++) {
640 eqn = reducer->translateFromReducedEqn(eqn);
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());
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) {
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];
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];
752 should_continue =
true;
755 while(nextBCeqn <= i) {
756 if (nextBCeqn == i) should_continue =
true;
758 if (nextBCeqnOffset < numBCeqns) {
759 nextBCeqn = bcEqns[nextBCeqnOffset];
768 if (should_continue)
continue;
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;
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) );
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;
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) );
std::vector< double > & getPackedCoefs()
unsigned getNumRows() const
SparseRowGraph & getGraph()
std::vector< int > & indices()
std::vector< double > & coefs()
int finalizeBCEqns(fei::Matrix &matrix, bool throw_if_bc_slave_conflict=false)
fei::SharedPtr< fei::MatrixGraph > matrixGraph_
fei::SharedPtr< fei::Matrix > matrix_
virtual int loadEssentialBCs(int numIDs, const int *IDs, int idType, int fieldID, int offsetIntoField, const double *prescribedValues)
LinearSystem(fei::SharedPtr< fei::MatrixGraph > &matrixGraph)
fei::SharedPtr< fei::Vector > soln_
fei::DirichletBCManager * dbcManager_
fei::SharedPtr< fei::Vector > rhs_
static LogManager & getLogManager()
const std::string & getOutputPath()
FEI_OSTREAM * output_stream_
OutputLevel output_level_
void setOutputLevel(OutputLevel olevel)
fei::SharedPtr< fei::Matrix > getTargetMatrix()
fei::SharedPtr< T > getMatrix()
virtual int copyOutRow(int row, int len, double *coefs, int *indices) const =0
virtual int getRowLength(int row, int &length) const =0
std::vector< int > rowNumbers
std::vector< int > packedColumnIndices
std::vector< int > rowOffsets
virtual int copyIn(int numValues, const int *indices, const double *values, int vectorIndex=0)=0
std::vector< double > & getMasterWeights()
int getConstraintID() const
void enforceEssentialBC_step_1(fei::CSVec &essBCs)
int implementBCs(bool applyBCs)
int loadComplete(bool applyBCs=true, bool globalAssemble=true)
fei::CSVec * essBCvalues_
LinearSystem_General(fei::SharedPtr< fei::MatrixGraph > &matrixGraph)
void enforceEssentialBC_step_2(fei::CSVec &essBCs)
int loadLagrangeConstraint(int constraintID, const double *weights, double rhsValue)
bool resolveConflictRequested_
bool explicitBCenforcement_
int setBCValuesOnVector(fei::Vector *vector)
bool eqnIsEssentialBC(int globalEqnIndex) const
void getConstrainedEqns(std::vector< int > &crEqns) const
void setName(const char *name)
int enforceEssentialBC_LinSysCore()
int parameters(int numParams, const char *const *paramStrings)
std::vector< double > dwork_
int loadEssentialBCs(int numIDs, const int *IDs, int idType, int fieldID, int offsetIntoField, const double *prescribedValues)
int loadPenaltyConstraint(int constraintID, const double *weights, double penaltyValue, double rhsValue)
void getEssentialBCs(std::vector< int > &bcEqns, std::vector< double > &bcVals) const
std::map< std::string, unsigned > named_loadcomplete_counter_
bool BCenforcement_no_column_mod_
std::vector< int > iwork_
int getMatrixRow(fei::Matrix *matrix, int row, std::vector< double > &coefs, std::vector< int > &indices)
virtual ~LinearSystem_General()
#define FEI_OSTRINGSTREAM
void global_union(MPI_Comm comm, const fei::FillableMat &localMatrix, fei::FillableMat &globalUnionMatrix)
void separate_BC_eqns(const fei::FillableMat &mat, std::vector< int > &bcEqns, std::vector< double > &bcVals)
void convert_ParameterSet_to_strings(const fei::ParameterSet *paramset, std::vector< std::string > ¶mStrings)
fei::OutputLevel string_to_output_level(const std::string &str)
void strings_to_char_ptrs(std::vector< std::string > &stdstrings, int &numStrings, const char **&charPtrs)
void put_entry(CSVec &vec, int eqn, double coef)
int localProc(MPI_Comm comm)
int binarySearch(const T &item, const T *list, int len)
int numProcs(MPI_Comm comm)
void get_row_numbers(const FillableMat &mat, std::vector< int > &rows)
void insertion_sort_with_companions(int len, int *array, T *companions)
int gatherRemoteEssBCs(fei::CSVec &essBCs, fei::SparseRowGraph *remoteGraph, fei::Matrix &matrix)
int resolveConflictingCRs(fei::MatrixGraph &matrixGraph, fei::Matrix &bcEqns, const std::vector< int > &bcEqnNumbers)
const char * getParam(const char *key, int numParams, const char *const *paramStrings)
const char * getParamValue(const char *key, int numParams, const char *const *paramStrings, char separator=' ')
int extractDirichletBCs(fei::DirichletBCManager *bcManager, fei::SharedPtr< fei::MatrixGraph > matrixGraph, fei::CSVec *essBCvalues, bool resolveConflictRequested, bool bcs_trump_slaves)