9 #include <fei_macros.hpp> 
   15 #include <snl_fei_Utils.hpp> 
   16 #include "fei_Record.hpp" 
   17 #include <fei_MatrixGraph.hpp> 
   18 #include <fei_SparseRowGraph.hpp> 
   19 #include <fei_Matrix_Impl.hpp> 
   20 #include <fei_ParameterSet.hpp> 
   22 #include <fei_CommUtils.hpp> 
   23 #include <fei_TemplateUtils.hpp> 
   24 #include <fei_CSVec.hpp> 
   25 #include <fei_chk_mpi.hpp> 
   28 #define fei_file "snl_fei_Utils.cpp" 
   29 #include <fei_ErrMacros.hpp> 
   32 const char* snl_fei::getParam(
const char* key,
 
   34             const char* 
const* paramStrings)
 
   37   return( getParam(key, numParams, paramStrings, foundOffset) );
 
   41 const char* snl_fei::getParamValue(
const char* key,
 
   43            const char* 
const* paramStrings,
 
   46   const char* param = getParam(key, numParams, paramStrings);
 
   48   return( param != NULL ? skipSeparator(param, separator) : NULL );
 
   52 const char* snl_fei::getParamValue(
const char* key,
 
   54            const char* 
const* paramStrings,
 
   58   const char* param = getParam(key, numParams, paramStrings, foundOffset);
 
   60   return( param != NULL ? skipSeparator(param, separator) : NULL );
 
   64 int snl_fei::getIntParamValue(
const char* key,
 
   66             const char*
const* params,
 
   69   const char* tempstr = getParamValue(key, numParams, params);
 
   70   if (tempstr==NULL) 
return(-1);
 
   72   std::string strg(tempstr);
 
   73   FEI_ISTRINGSTREAM isstr(strg);
 
   75   return( isstr.fail() ? -1 : 0 );
 
   79 int snl_fei::getDoubleParamValue(
const char* key,
 
   81          const char*
const* params,
 
   84   const char* tempstr = getParamValue(key, numParams, params);
 
   85   if (tempstr==NULL) 
return(-1);
 
   87   std::string strg(tempstr);
 
   88   FEI_ISTRINGSTREAM isstr(strg);
 
   90   return( isstr.fail() ? -1 : 0 );
 
   94 int snl_fei::getDoubleParamValue(
const char* key,
 
   95          std::vector<std::string>& params,
 
   98   const char* tempstr = getParamValue(key, params);
 
   99   if (tempstr==NULL) 
return(-1);
 
  101   std::string strg(tempstr);
 
  102   FEI_ISTRINGSTREAM isstr(strg);
 
  104   return( isstr.fail() ? -1 : 0 );
 
  108 const char* snl_fei::getParam(
const char* key,
 
  110             const char* 
const* paramStrings,
 
  113   const char* returnPtr = NULL;
 
  119   if (key == NULL || paramStrings == NULL || numParams == 0) {
 
  123   unsigned keyLen = strlen(key);
 
  125   for(
int i=numParams-1; i>=0; --i) {
 
  126     const char* paramStr = paramStrings[i];
 
  129     if (paramStr == NULL) 
continue;
 
  131     unsigned paramStr_len = leading_substring_length(paramStr);
 
  132     if (paramStr_len != keyLen) 
continue;
 
  134     if (strncmp(key, paramStr, keyLen) == 0) {
 
  135       returnPtr = paramStr;
 
  145 const char* snl_fei::getParam(
const char* key,
 
  146             std::vector<std::string>& params,
 
  149   std::vector<std::string>::iterator
 
  150     p_iter = params.begin(),
 
  151     p_end = params.end();
 
  154   for(; p_iter != p_end; ++p_iter, ++offset) {
 
  155     std::string& pstr = *p_iter;
 
  156     int ssize = pstr.size();
 
  157     if (ssize < 1) 
continue;
 
  159     std::string::size_type i = pstr.find(key);
 
  161       foundOffset = offset;
 
  162       return( pstr.c_str() );
 
  170 const char* snl_fei::getParamValue(
const char* key,
 
  171            std::vector<std::string>& params,
 
  175   return( skipSeparator( getParam(key, params, offset), separator) );
 
  179 void snl_fei::separate_string(
const char* input_string,
 
  180             const char* substring,
 
  181             const char*& before_substring,
 
  182             int& len_before_substring,
 
  183             const char*& after_substring,
 
  184             int& len_after_substring)
 
  186   if (input_string == NULL) {
 
  187     before_substring = NULL;
 
  188     len_before_substring = 0;
 
  189     after_substring = NULL;
 
  190     len_after_substring = 0;
 
  194   int len_input_string = strlen(input_string);
 
  195   before_substring = input_string;
 
  197   if (substring == NULL) {
 
  198     len_before_substring = len_input_string;
 
  199     after_substring = NULL;
 
  200     len_after_substring = 0;
 
  204   int len_substring = strlen(substring);
 
  206   const char* s1 = strstr(input_string, substring);
 
  208     len_before_substring = len_input_string;
 
  209     after_substring = NULL;
 
  210     len_after_substring = 0;
 
  214   after_substring = skipSeparator(s1, substring[len_substring-1]);
 
  215   len_before_substring = s1 - input_string;
 
  216   len_after_substring = len_input_string - len_before_substring - len_substring;
 
  220 int snl_fei::storeNamedAttribute(
const char* name,
 
  222          std::vector<char*>& attributeNames,
 
  223          std::vector<void*>& attributes)
 
  226   const char* foundname = attributeNames.empty() ?
 
  227     0 : snl_fei::getParam(name, attributeNames.size(),
 
  228         &(attributeNames[0]), offset);
 
  230   if (foundname != 0) {
 
  231     attributes[offset] = attribute;
 
  234     char* newname = 
new char[strlen(name)+1];
 
  235     strcpy(newname, name);
 
  236     attributeNames.push_back(newname);
 
  237     attributes.push_back(attribute);
 
  244 void* snl_fei::retrieveNamedAttribute(
const char* name,
 
  245               std::vector<char*>& attributeNames,
 
  246               std::vector<void*>& attributes)
 
  249   const char* foundname = attributeNames.empty() ?
 
  250     0 : snl_fei::getParam(name, attributeNames.size(),
 
  251         &(attributeNames[0]), offset);
 
  253   void* returnVal = NULL;
 
  255   if (foundname != 0) {
 
  256     returnVal = attributes[offset];
 
  266 unsigned snl_fei::leading_substring_length(
const char* 
string)
 
  268   if (
string == NULL) {
 
  272   const char* lastchar = string;
 
  275   while(*lastchar != 
' ' && *lastchar != 
'\t' && *lastchar != 
'\0') {
 
  284 const char* snl_fei::skipSeparator(
const char* paramString,
 
  287   if (paramString == NULL) 
return(NULL);
 
  289   const char* result = strchr(paramString, separator);
 
  291   if (result == NULL) 
return(result);
 
  294   while(result[0] == separator) result++;
 
  300 int snl_fei::mergeStringLists(
char**& strings,
 
  302             const char*
const* stringsToMerge,
 
  303             int numStringsToMerge)
 
  306   if (numStrings == 0) {
 
  307     strings = 
new char*[numStringsToMerge];
 
  309     for(i=0; i<numStringsToMerge; ++i){
 
  310       strings[i] = 
new char[strlen(stringsToMerge[i])+1];
 
  312       strcpy(strings[i], stringsToMerge[i]);
 
  315     numStrings = numStringsToMerge;
 
  319     bool* merged = 
new bool[numStringsToMerge];
 
  320     for(i=0; i<numStringsToMerge; ++i) {
 
  323       int len_temp, len_temp2;
 
  324       separate_string(stringsToMerge[i], 
" ",
 
  325                       temp, len_temp, temp2, len_temp2);
 
  326       std::string strtemp(temp, len_temp);
 
  327       int foundOffset = -1;
 
  328       const char* matchingString = 
 
  329   snl_fei::getParam(strtemp.c_str(), numStrings, strings, foundOffset);
 
  330       if (matchingString != NULL) {
 
  331         int len = strlen(stringsToMerge[i])+1;
 
  332   delete [] strings[foundOffset];
 
  333   strings[foundOffset] = 
new char[len];
 
  334   strcpy(strings[foundOffset], stringsToMerge[i]);
 
  338       else merged[i] = 
false;
 
  341     if (numMerged == numStringsToMerge) {
 
  346     char** newStrings = 
new char*[numStrings+numStringsToMerge-numMerged];
 
  347     for(i=0; i<numStrings; ++i) {
 
  348       newStrings[i] = strings[i];
 
  350     int offset = numStrings;
 
  351     for(i=0; i<numStringsToMerge; ++i) {
 
  353   int len = strlen(stringsToMerge[i])+1;
 
  354   newStrings[offset] = 
new char[len];
 
  355   strcpy(newStrings[offset++], stringsToMerge[i]);
 
  361     strings = newStrings;
 
  362     numStrings+= numStringsToMerge-numMerged;
 
  371                                    const std::vector<int>& bcEqnNumbers)
 
  374   if (numLagrangeConstraints < 1) {
 
  387   double* coefPtr = &(coefs[0]);
 
  388   int* indicesPtr = &(indices[0]);
 
  390   double fei_eps = 1.e-49;
 
  392   std::vector<int> cr_indices;
 
  393   std::map<int,Constraint<fei::Record<int>*>*>& lagrangeConstraints =
 
  396   std::map<int,Constraint<fei::Record<int>*>*>::const_iterator
 
  397     cr_iter = lagrangeConstraints.begin(),
 
  398     cr_end  = lagrangeConstraints.end();
 
  400   while(cr_iter != cr_end) {
 
  401     Constraint<fei::Record<int>*>* cr = (*cr_iter).second;
 
  405     std::vector<double>& weights = cr->getMasterWeights();
 
  406     double* weightsPtr = &weights[0];
 
  408     int len = cr_indices.size();
 
  409     int* cr_indPtr = &(cr_indices[0]);
 
  410     for(
int j=0; j<len; ++j) {
 
  411       if (std::abs(weightsPtr[j] + 1.0) > fei_eps) 
continue;
 
  413       int eqn = cr_indPtr[j];
 
  415   int cr_eqn = cr->getEqnNumber();
 
  417   CHK_ERR( bcEqns.
copyIn(1, &cr_eqn, 3, indicesPtr,
 
  418              (
double**)(&coefPtr)) );
 
  428 int snl_fei::gatherRemoteEssBCs(
fei::CSVec& essBCs,
 
  432   std::vector<int>& rrowOffs = remoteGraph->
rowOffsets;
 
  435   int numEssEqns = essBCs.size();
 
  436   if (numEssEqns > 0) {
 
  437     int* essEqns = &(essBCs.indices()[0]);
 
  438     double* coefs = &(essBCs.coefs()[0]);
 
  440     if (rrowOffs.size() > 0 && rcols.size() > 0) {
 
  442       int* rowOffsPtr = &(rrowOffs[0]);
 
  443       int* rcolsPtr = &(rcols[0]);
 
  445       for(
int j=0; j<numEssEqns; ++j) {
 
  447         int eqn = essEqns[j];
 
  449         for(
unsigned i=0; i<rrowOffs.size()-1; ++i) {
 
  450           int len = rowOffsPtr[i+1]-rowOffsPtr[i];
 
  451           int* colsPtr = &(rcolsPtr[rowOffsPtr[i]]);
 
  454             double coef = coefs[j];
 
  455             double* coefPtr = &coef;
 
  457             for(
int k=0; k<len; ++k) {
 
  458               CHK_ERR( matrix.
copyIn(1, &(colsPtr[k]),
 
  459                        1, &(eqn), &coefPtr) );
 
  481   newgraph->rowNumbers.resize(numrows);
 
  482   newgraph->rowOffsets.resize(numrows+1);
 
  483   newgraph->packedColumnIndices.resize(nnz);
 
  485   std::map<int,int> rowmap;
 
  487   for(
unsigned i=0; i<srg1->
rowNumbers.size(); ++i) {
 
  489     rowmap.insert(std::make_pair(srg1->
rowNumbers[i], rowlen));
 
  492   for(
unsigned i=0; i<srg2->
rowNumbers.size(); ++i) {
 
  494     rowmap.insert(std::make_pair(srg2->
rowNumbers[i], rowlen));
 
  497   std::map<int,int>::iterator
 
  498     r_iter = rowmap.begin(),
 
  499     r_end  = rowmap.end();
 
  502   for(
unsigned i=0; r_iter != r_end; ++r_iter, ++i) {
 
  503     newgraph->rowNumbers[i] = r_iter->first;
 
  504     int rowlen = r_iter->second;
 
  505     newgraph->rowOffsets[i] = offset;
 
  509   newgraph->rowOffsets[numrows] = offset;
 
  511   for(
unsigned i=0; i<srg1->
rowNumbers.size(); ++i) {
 
  514     int newcoloffset = newgraph->rowOffsets[r_iter->second];
 
  518     for(
int j=jbegin; j<jend; ++j) {
 
  519       newgraph->packedColumnIndices[newcoloffset++] =
 
  524   for(
unsigned i=0; i<srg2->
rowNumbers.size(); ++i) {
 
  527     int newcoloffset = newgraph->rowOffsets[r_iter->second];
 
  531     for(
int j=jbegin; j<jend; ++j) {
 
  532       newgraph->packedColumnIndices[newcoloffset++] =
 
  540 void snl_fei::copy2DBlockDiagToColumnContig(
int numBlocks,
 
  541               const int* blockSizes,
 
  542               const double*
const* values2d,
 
  544               double* colcontigvalues)
 
  546   int i, j, k, offset, coffset;
 
  549   case FEI_BLOCK_DIAGONAL_ROW:
 
  552     for(i=0; i<numBlocks; ++i) {
 
  553       int bsize = blockSizes[i];
 
  554       for(j=0; j<bsize; ++j) {
 
  555   for(k=0; k<bsize; ++k) {
 
  556     colcontigvalues[coffset+j*bsize+k] = values2d[offset+j][k];
 
  560       coffset += bsize*bsize;
 
  564     FEI_OSTRINGSTREAM osstr;
 
  565     osstr << 
"copy2DBlockDiagToColumnContig ERROR, format="<<format
 
  566     << 
" not recognized.";
 
  567     throw std::runtime_error(osstr.str());
 
  571 void snl_fei::copy2DToColumnContig(
int numrows,
 
  573            const double*
const* values2d,
 
  575            double* colcontigvalues)
 
  582     for(i=0; i<numrows; ++i) {
 
  583       for(j=0; j<numcols; ++j) {
 
  584   colcontigvalues[j*numrows+i] = values2d[i][j];
 
  590     for(j=0; j<numcols; ++j) {
 
  591       for(i=0; i<numrows; ++i) {
 
  592   colcontigvalues[j*numrows+i] = values2d[j][i];
 
  598     FEI_OSTRINGSTREAM osstr;
 
  599     osstr << 
"copy2DToColumnContig ERROR, format="<<format<<
" not recognized.";
 
  600     throw std::runtime_error(osstr.str());
 
std::vector< int > rowNumbers
 
virtual int getConstraintConnectivityIndices(ConstraintType *cr, std::vector< int > &globalIndices)=0
 
std::vector< int > packedColumnIndices
 
std::vector< int > rowOffsets
 
virtual std::map< int, ConstraintType * > & getLagrangeConstraints()=0
 
int binarySearch(const T &item, const T *list, int len)
 
virtual int copyIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
 
virtual int getLocalNumLagrangeConstraints() const =0
 
virtual int gatherFromOverlap(bool accumulate=true)=0