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