FEI Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
snl_fei_Utils.cpp
Go to the documentation of this file.
1/*--------------------------------------------------------------------*/
2/* Copyright 2005 Sandia Corporation. */
3/* Under the terms of Contract DE-AC04-94AL85000, there is a */
4/* non-exclusive license for use of this work by or on behalf */
5/* of the U.S. Government. Export of this program may require */
6/* a license from the United States Government. */
7/*--------------------------------------------------------------------*/
8
9#include <fei_macros.hpp>
10
11#include <limits>
12#include <cmath>
13#include <stdexcept>
14
15#include <snl_fei_Utils.hpp>
16#include "fei_Record.hpp"
17#include <fei_MatrixGraph.hpp>
19#include <fei_Matrix_Impl.hpp>
20#include <fei_ParameterSet.hpp>
21
22#include <fei_CommUtils.hpp>
23#include <fei_TemplateUtils.hpp>
24#include <fei_CSVec.hpp>
25#include <fei_chk_mpi.hpp>
26
27#undef fei_file
28#define fei_file "snl_fei_Utils.cpp"
29#include <fei_ErrMacros.hpp>
30
31//----------------------------------------------------------------------------
32const char* snl_fei::getParam(const char* key,
33 int numParams,
34 const char* const* paramStrings)
35{
36 int foundOffset = -1;
37 return( getParam(key, numParams, paramStrings, foundOffset) );
38}
39
40//----------------------------------------------------------------------------
41const char* snl_fei::getParamValue(const char* key,
42 int numParams,
43 const char* const* paramStrings,
44 char separator)
45{
46 const char* param = getParam(key, numParams, paramStrings);
47
48 return( param != NULL ? skipSeparator(param, separator) : NULL );
49}
50
51//----------------------------------------------------------------------------
52const char* snl_fei::getParamValue(const char* key,
53 int numParams,
54 const char* const* paramStrings,
55 int& foundOffset,
56 char separator)
57{
58 const char* param = getParam(key, numParams, paramStrings, foundOffset);
59
60 return( param != NULL ? skipSeparator(param, separator) : NULL );
61}
62
63//----------------------------------------------------------------------------
64int snl_fei::getIntParamValue(const char* key,
65 int numParams,
66 const char*const* params,
67 int& paramValue)
68{
69 const char* tempstr = getParamValue(key, numParams, params);
70 if (tempstr==NULL) return(-1);
71
72 std::string strg(tempstr);
73 FEI_ISTRINGSTREAM isstr(strg);
74 isstr >> paramValue;
75 return( isstr.fail() ? -1 : 0 );
76}
77
78//----------------------------------------------------------------------------
79int snl_fei::getDoubleParamValue(const char* key,
80 int numParams,
81 const char*const* params,
82 double& paramValue)
83{
84 const char* tempstr = getParamValue(key, numParams, params);
85 if (tempstr==NULL) return(-1);
86
87 std::string strg(tempstr);
88 FEI_ISTRINGSTREAM isstr(strg);
89 isstr >> paramValue;
90 return( isstr.fail() ? -1 : 0 );
91}
92
93//----------------------------------------------------------------------------
94int snl_fei::getDoubleParamValue(const char* key,
95 std::vector<std::string>& params,
96 double& paramValue)
97{
98 const char* tempstr = getParamValue(key, params);
99 if (tempstr==NULL) return(-1);
100
101 std::string strg(tempstr);
102 FEI_ISTRINGSTREAM isstr(strg);
103 isstr >> paramValue;
104 return( isstr.fail() ? -1 : 0 );
105}
106
107//----------------------------------------------------------------------------
108const char* snl_fei::getParam(const char* key,
109 int numParams,
110 const char* const* paramStrings,
111 int& foundOffset)
112{
113 const char* returnPtr = NULL;
114 foundOffset = -1;
115
116 //if the search-key is null, or if the list of strings to be searched is null,
117 //or if the number of strings to be searched is null, then return now.
118 //
119 if (key == NULL || paramStrings == NULL || numParams == 0) {
120 return(returnPtr);
121 }
122
123 unsigned keyLen = strlen(key);
124
125 for(int i=numParams-1; i>=0; --i) {
126 const char* paramStr = paramStrings[i];
127
128 //if the i-th paramString is null, skip it.
129 if (paramStr == NULL) continue;
130
131 unsigned paramStr_len = leading_substring_length(paramStr);
132 if (paramStr_len != keyLen) continue;
133
134 if (strncmp(key, paramStr, keyLen) == 0) {
135 returnPtr = paramStr;
136 foundOffset = i;
137 return(returnPtr);
138 }
139 }
140
141 return(returnPtr);
142}
143
144//----------------------------------------------------------------------------
145const char* snl_fei::getParam(const char* key,
146 std::vector<std::string>& params,
147 int& foundOffset)
148{
149 std::vector<std::string>::iterator
150 p_iter = params.begin(),
151 p_end = params.end();
152
153 int offset = 0;
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;
158
159 std::string::size_type i = pstr.find(key);
160 if (i == 0) {
161 foundOffset = offset;
162 return( pstr.c_str() );
163 }
164 }
165
166 return( NULL );
167}
168
169//----------------------------------------------------------------------------
170const char* snl_fei::getParamValue(const char* key,
171 std::vector<std::string>& params,
172 char separator)
173{
174 int offset = 0;
175 return( skipSeparator( getParam(key, params, offset), separator) );
176}
177
178//----------------------------------------------------------------------------
179void 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)
185{
186 if (input_string == NULL) {
187 before_substring = NULL;
188 len_before_substring = 0;
189 after_substring = NULL;
190 len_after_substring = 0;
191 return;
192 }
193
194 int len_input_string = strlen(input_string);
195 before_substring = input_string;
196
197 if (substring == NULL) {
198 len_before_substring = len_input_string;
199 after_substring = NULL;
200 len_after_substring = 0;
201 return;
202 }
203
204 int len_substring = strlen(substring);
205
206 const char* s1 = strstr(input_string, substring);
207 if (s1 == NULL) {
208 len_before_substring = len_input_string;
209 after_substring = NULL;
210 len_after_substring = 0;
211 return;
212 }
213
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;
217}
218
219//----------------------------------------------------------------------------
220int snl_fei::storeNamedAttribute(const char* name,
221 void* attribute,
222 std::vector<char*>& attributeNames,
223 std::vector<void*>& attributes)
224{
225 int offset = -1;
226 const char* foundname = attributeNames.empty() ?
227 0 : snl_fei::getParam(name, attributeNames.size(),
228 &(attributeNames[0]), offset);
229
230 if (foundname != 0) {
231 attributes[offset] = attribute;
232 }
233 else {
234 char* newname = new char[strlen(name)+1];
235 strcpy(newname, name);
236 attributeNames.push_back(newname);
237 attributes.push_back(attribute);
238 }
239
240 return(0);
241}
242
243//----------------------------------------------------------------------------
244void* snl_fei::retrieveNamedAttribute(const char* name,
245 std::vector<char*>& attributeNames,
246 std::vector<void*>& attributes)
247{
248 int offset = -1;
249 const char* foundname = attributeNames.empty() ?
250 0 : snl_fei::getParam(name, attributeNames.size(),
251 &(attributeNames[0]), offset);
252
253 void* returnVal = NULL;
254
255 if (foundname != 0) {
256 returnVal = attributes[offset];
257 }
258 else {
259 return( returnVal );
260 }
261
262 return( returnVal );
263}
264
265//----------------------------------------------------------------------------
266unsigned snl_fei::leading_substring_length(const char* string)
267{
268 if (string == NULL) {
269 return(0);
270 }
271
272 const char* lastchar = string;
273 unsigned len = 0;
274
275 while(*lastchar != ' ' && *lastchar != '\t' && *lastchar != '\0') {
276 ++len;
277 ++lastchar;
278 }
279
280 return(len);
281}
282
283//----------------------------------------------------------------------------
284const char* snl_fei::skipSeparator(const char* paramString,
285 char separator)
286{
287 if (paramString == NULL) return(NULL);
288
289 const char* result = strchr(paramString, separator);
290
291 if (result == NULL) return(result);
292
293 //allow for the possibility that separator is repeated
294 while(result[0] == separator) result++;
295
296 return( result );
297}
298
299//----------------------------------------------------------------------------
300int snl_fei::mergeStringLists(char**& strings,
301 int& numStrings,
302 const char*const* stringsToMerge,
303 int numStringsToMerge)
304{
305 int i;
306 if (numStrings == 0) {
307 strings = new char*[numStringsToMerge];
308
309 for(i=0; i<numStringsToMerge; ++i){
310 strings[i] = new char[strlen(stringsToMerge[i])+1];
311
312 strcpy(strings[i], stringsToMerge[i]);
313 }
314
315 numStrings = numStringsToMerge;
316 }
317 else {
318 int numMerged = 0;
319 bool* merged = new bool[numStringsToMerge];
320 for(i=0; i<numStringsToMerge; ++i) {
321 const char* temp;
322 const char* temp2;
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]);
335 merged[i] = true;
336 ++numMerged;
337 }
338 else merged[i] = false;
339 }
340
341 if (numMerged == numStringsToMerge) {
342 delete [] merged;
343 return(0);
344 }
345
346 char** newStrings = new char*[numStrings+numStringsToMerge-numMerged];
347 for(i=0; i<numStrings; ++i) {
348 newStrings[i] = strings[i];
349 }
350 int offset = numStrings;
351 for(i=0; i<numStringsToMerge; ++i) {
352 if (!merged[i]) {
353 int len = strlen(stringsToMerge[i])+1;
354 newStrings[offset] = new char[len];
355 strcpy(newStrings[offset++], stringsToMerge[i]);
356 }
357 }
358 delete [] merged;
359
360 delete [] strings;
361 strings = newStrings;
362 numStrings+= numStringsToMerge-numMerged;
363 }
364
365 return(0);
366}
367
368//----------------------------------------------------------------------------
370 fei::Matrix& bcEqns,
371 const std::vector<int>& bcEqnNumbers)
372{
373 int numLagrangeConstraints = matrixGraph.getLocalNumLagrangeConstraints();
374 if (numLagrangeConstraints < 1) {
375 return(0);
376 }
377
378 double coefs[3];
379 int indices[3];
380 indices[0] = 0;
381 indices[1] = 1;
382 indices[2] = 2;
383 coefs[0] = 1.0;
384 coefs[1] = 0.0;
385 coefs[2] = 1.0;
386
387 double* coefPtr = &(coefs[0]);
388 int* indicesPtr = &(indices[0]);
389
390 double fei_eps = 1.e-49;
391
392 std::vector<int> cr_indices;
393 std::map<int,Constraint<fei::Record<int>*>*>& lagrangeConstraints =
394 matrixGraph.getLagrangeConstraints();
395
396 std::map<int,Constraint<fei::Record<int>*>*>::const_iterator
397 cr_iter = lagrangeConstraints.begin(),
398 cr_end = lagrangeConstraints.end();
399
400 while(cr_iter != cr_end) {
401 Constraint<fei::Record<int>*>* cr = (*cr_iter).second;
402
403 CHK_ERR( matrixGraph.getConstraintConnectivityIndices(cr, cr_indices) );
404
405 std::vector<double>& weights = cr->getMasterWeights();
406 double* weightsPtr = &weights[0];
407
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;
412
413 int eqn = cr_indPtr[j];
414 if (fei::binarySearch(eqn, bcEqnNumbers) > -1) {
415 int cr_eqn = cr->getEqnNumber();
416
417 CHK_ERR( bcEqns.copyIn(1, &cr_eqn, 3, indicesPtr,
418 (double**)(&coefPtr)) );
419 }
420 }
421 ++cr_iter;
422 }
423
424 return(0);
425}
426
427//----------------------------------------------------------------------------
429 fei::SparseRowGraph* remoteGraph,
430 fei::Matrix& matrix)
431{
432 std::vector<int>& rrowOffs = remoteGraph->rowOffsets;
433 std::vector<int>& rcols = remoteGraph->packedColumnIndices;
434
435 int numEssEqns = essBCs.size();
436 if (numEssEqns > 0) {
437 int* essEqns = &(essBCs.indices()[0]);
438 double* coefs = &(essBCs.coefs()[0]);
439
440 if (rrowOffs.size() > 0 && rcols.size() > 0) {
441
442 int* rowOffsPtr = &(rrowOffs[0]);
443 int* rcolsPtr = &(rcols[0]);
444
445 for(int j=0; j<numEssEqns; ++j) {
446
447 int eqn = essEqns[j];
448
449 for(unsigned i=0; i<rrowOffs.size()-1; ++i) {
450 int len = rowOffsPtr[i+1]-rowOffsPtr[i];
451 int* colsPtr = &(rcolsPtr[rowOffsPtr[i]]);
452
453 if (fei::binarySearch(eqn, colsPtr, len) > -1) {
454 double coef = coefs[j];
455 double* coefPtr = &coef;
456
457 for(int k=0; k<len; ++k) {
458 CHK_ERR( matrix.copyIn(1, &(colsPtr[k]),
459 1, &(eqn), &coefPtr) );
460 }
461 }
462 }
463 }
464 }
465 }
466
467 CHK_ERR( matrix.gatherFromOverlap(false) );
468
469 return(0);
470}
471
474 const fei::SparseRowGraph* srg2)
475{
477
478 int numrows = srg1->rowNumbers.size() + srg2->rowNumbers.size();
479 int nnz = srg1->packedColumnIndices.size() + srg2->packedColumnIndices.size();
480
481 newgraph->rowNumbers.resize(numrows);
482 newgraph->rowOffsets.resize(numrows+1);
483 newgraph->packedColumnIndices.resize(nnz);
484
485 std::map<int,int> rowmap;
486
487 for(unsigned i=0; i<srg1->rowNumbers.size(); ++i) {
488 int rowlen = srg1->rowOffsets[i+1]-srg1->rowOffsets[i];
489 rowmap.insert(std::make_pair(srg1->rowNumbers[i], rowlen));
490 }
491
492 for(unsigned i=0; i<srg2->rowNumbers.size(); ++i) {
493 int rowlen = srg2->rowOffsets[i+1]-srg2->rowOffsets[i];
494 rowmap.insert(std::make_pair(srg2->rowNumbers[i], rowlen));
495 }
496
497 std::map<int,int>::iterator
498 r_iter = rowmap.begin(),
499 r_end = rowmap.end();
500
501 int offset = 0;
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;
506 offset += rowlen;
507 r_iter->second = i;
508 }
509 newgraph->rowOffsets[numrows] = offset;
510
511 for(unsigned i=0; i<srg1->rowNumbers.size(); ++i) {
512 r_iter = rowmap.find(srg1->rowNumbers[i]);
513
514 int newcoloffset = newgraph->rowOffsets[r_iter->second];
515
516 int jbegin = srg1->rowOffsets[i];
517 int jend = srg1->rowOffsets[i+1];
518 for(int j=jbegin; j<jend; ++j) {
519 newgraph->packedColumnIndices[newcoloffset++] =
520 srg1->packedColumnIndices[j];
521 }
522 }
523
524 for(unsigned i=0; i<srg2->rowNumbers.size(); ++i) {
525 r_iter = rowmap.find(srg2->rowNumbers[i]);
526
527 int newcoloffset = newgraph->rowOffsets[r_iter->second];
528
529 int jbegin = srg2->rowOffsets[i];
530 int jend = srg2->rowOffsets[i+1];
531 for(int j=jbegin; j<jend; ++j) {
532 newgraph->packedColumnIndices[newcoloffset++] =
533 srg2->packedColumnIndices[j];
534 }
535 }
536
537 return(newgraph);
538}
539
541 const int* blockSizes,
542 const double*const* values2d,
543 int format,
544 double* colcontigvalues)
545{
546 int i, j, k, offset, coffset;
547
548 switch(format) {
550 offset = 0;
551 coffset = 0;
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];
557 }
558 }
559 offset += bsize;
560 coffset += bsize*bsize;
561 }
562 break;
563 default:
564 FEI_OSTRINGSTREAM osstr;
565 osstr << "copy2DBlockDiagToColumnContig ERROR, format="<<format
566 << " not recognized.";
567 throw std::runtime_error(osstr.str());
568 }
569}
570
572 int numcols,
573 const double*const* values2d,
574 int format,
575 double* colcontigvalues)
576{
577 int i, j;
578
579 switch(format) {
580
581 case FEI_DENSE_ROW:
582 for(i=0; i<numrows; ++i) {
583 for(j=0; j<numcols; ++j) {
584 colcontigvalues[j*numrows+i] = values2d[i][j];
585 }
586 }
587 break;
588
589 case FEI_DENSE_COL:
590 for(j=0; j<numcols; ++j) {
591 for(i=0; i<numrows; ++i) {
592 colcontigvalues[j*numrows+i] = values2d[j][i];
593 }
594 }
595 break;
596
597 default:
598 FEI_OSTRINGSTREAM osstr;
599 osstr << "copy2DToColumnContig ERROR, format="<<format<<" not recognized.";
600 throw std::runtime_error(osstr.str());
601 }
602}
std::vector< int > & indices()
Definition: fei_CSVec.hpp:31
size_t size() const
Definition: fei_CSVec.hpp:36
std::vector< double > & coefs()
Definition: fei_CSVec.hpp:33
virtual int getLocalNumLagrangeConstraints() const =0
virtual std::map< int, ConstraintType * > & getLagrangeConstraints()=0
virtual int getConstraintConnectivityIndices(ConstraintType *cr, std::vector< int > &globalIndices)=0
virtual int copyIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
virtual int gatherFromOverlap(bool accumulate=true)=0
std::vector< int > rowNumbers
std::vector< int > packedColumnIndices
std::vector< int > rowOffsets
std::vector< double > & getMasterWeights()
#define CHK_ERR(a)
#define FEI_DENSE_ROW
Definition: fei_defs.h:77
#define FEI_DENSE_COL
Definition: fei_defs.h:80
#define FEI_BLOCK_DIAGONAL_ROW
Definition: fei_defs.h:84
#define FEI_OSTRINGSTREAM
Definition: fei_sstream.hpp:32
#define FEI_ISTRINGSTREAM
Definition: fei_sstream.hpp:31
int binarySearch(const T &item, const T *list, int len)
int mergeStringLists(char **&strings, int &numStrings, const char *const *stringsToMerge, int numStringsToMerge)
void separate_string(const char *input_string, const char *substring, const char *&before_substring, int &len_before_substring, const char *&after_substring, int &len_after_substring)
int gatherRemoteEssBCs(fei::CSVec &essBCs, fei::SparseRowGraph *remoteGraph, fei::Matrix &matrix)
int getIntParamValue(const char *key, int numParams, const char *const *params, int &paramValue)
int resolveConflictingCRs(fei::MatrixGraph &matrixGraph, fei::Matrix &bcEqns, const std::vector< int > &bcEqnNumbers)
int storeNamedAttribute(const char *name, void *attribute, std::vector< char * > &attributeNames, std::vector< void * > &attributes)
const char * skipSeparator(const char *paramString, char separator=' ')
fei::SharedPtr< fei::SparseRowGraph > mergeSparseRowGraphs(const fei::SparseRowGraph *srg1, const fei::SparseRowGraph *srg2)
unsigned leading_substring_length(const char *string)
int getDoubleParamValue(const char *key, int numParams, const char *const *params, double &paramValue)
const char * getParam(const char *key, int numParams, const char *const *paramStrings)
void copy2DBlockDiagToColumnContig(int numBlocks, const int *blockSizes, const double *const *values2d, int format, double *colcontigvalues)
const char * getParamValue(const char *key, int numParams, const char *const *paramStrings, char separator=' ')
void * retrieveNamedAttribute(const char *name, std::vector< char * > &attributeNames, std::vector< void * > &attributes)
void copy2DToColumnContig(int numrows, int numcols, const double *const *values2d, int format, double *colcontigvalues)