591
565
//------------------------------------------------------------------------------
592
int SNL_FEI_Structure::initCoefAccessPattern(int patternID,
594
const int* numFieldsPerRow,
595
const int* const* rowFieldIDs,
597
const int* numFieldsPerCol,
598
const int* const* colFieldIDs,
599
int interleaveStrategy)
602
//This is a simple function -- just stores this incoming data in a new
603
//PatternDescriptor, if this patternID hasn't already been used. If it
604
//has already been used, return an error (nonzero).
606
CHK_ERR( addPattern(patternID) )
607
PatternDescriptor* pattern = NULL;
608
CHK_ERR( getPatternDescriptor(patternID, pattern) )
610
if (numRowIDs <= 0 || numColIDsPerRow <= 0) {
611
FEI_CERR << "SNL_FEI_Structure::initCoefAccessPattern: numRowIDs: " << numRowIDs
612
<< ", numColIDsPerRow: " << numColIDsPerRow
613
<< ". These values must both be" << " > 0." << FEI_ENDL;
619
CHK_ERR( pattern->setNumRowIDs(numRowIDs) )
620
feiArray<int>& fieldsPerRow = pattern->getNumFieldsPerRow();
621
feiArray<int>* rFieldIDs = pattern->getRowFieldIDs();
623
for(i=0; i<numRowIDs; i++) {
624
fieldsPerRow[i] = numFieldsPerRow[i];
626
for(int j=0; j<fieldsPerRow[i]; j++) {
627
rFieldIDs[i].append(rowFieldIDs[i][j]);
632
CHK_ERR( pattern->setNumColIDsPerRow(numColIDsPerRow) )
633
feiArray<int>& fieldsPerCol = pattern->getNumFieldsPerCol();
634
feiArray<int>* cFieldIDs = pattern->getColFieldIDs();
636
for(i=0; i<numColIDsPerRow; i++) {
637
fieldsPerCol[i] = numFieldsPerCol[i];
639
for(int j=0; j<numFieldsPerCol[i]; j++) {
640
cFieldIDs[i].append(colFieldIDs[i][j]);
644
pattern->setInterleaveStrategy(interleaveStrategy);
649
//------------------------------------------------------------------------------
650
int SNL_FEI_Structure::initCoefAccess(int patternID,
651
const int* rowIDTypes,
652
const GlobalID* rowIDs,
653
const int* colIDTypes,
654
const GlobalID* colIDs)
656
PatternDescriptor* pattern = NULL;
657
CHK_ERR( getPatternDescriptor(patternID, pattern) );
659
int numRowIDs = pattern->getNumRowIDs();
660
int numColIDsPerRow = pattern->getNumColIDsPerRow();
662
CHK_ERR( appendPatternConnectivity(patternID,
663
numRowIDs, rowIDTypes, rowIDs,
665
colIDTypes, colIDs) );
667
for(int i=0; i<numRowIDs; i++){
668
if (rowIDTypes[i] == FEI_NODE) {
669
CHK_ERR( nodeDatabase_->initNodeID(rowIDs[i]) );
673
for(int j=0; j<numRowIDs*numColIDsPerRow; j++) {
674
if (colIDTypes[j] == FEI_NODE) {
675
CHK_ERR( nodeDatabase_->initNodeID(colIDs[j]) );
682
//------------------------------------------------------------------------------
683
566
int SNL_FEI_Structure::initSlaveVariable(GlobalID slaveNodeID,
684
567
int slaveFieldID,
685
568
int offsetIntoSlaveField,
1458
1327
//------------------------------------------------------------------------------
1459
int SNL_FEI_Structure::initAccessPatternStructure()
1461
FEI_OSTREAM& os = dbgOut();
1462
if (debugOutput_) os << "# initAccessPatternStructure" << FEI_ENDL;
1464
int numPatterns = getNumPatterns();
1466
for(int i=0; i<numPatterns; i++) {
1467
PatternDescriptor* pattern = NULL;
1468
CHK_ERR( getPatternDescriptor_index(i, pattern));
1470
int patternID = pattern->getPatternID();
1471
ConnectivityTable& conn = getPatternConnectivity(patternID);
1473
//The ConnectivityTable struct is meant to hold element-connectivities,
1474
//but I'm also using it to hold pattern connectivities.
1476
feiArray<int> rowIndices(0, 8), colIndices(0,8);
1478
//The rows of the 'connectivities' table alternate, holding rowNodes and
1479
//then colNodes. ... confusing, yes. But...
1481
int offset = 0, loopCount = conn.numRows/2;
1482
for(int row=0; row<loopCount; row++) {
1484
feiArray<GlobalID>& rownodes = *(conn.connectivities[offset++]);
1485
feiArray<GlobalID>& colnodes = *(conn.connectivities[offset++]);
1487
feiArray<int> rowColOffsets(0, rownodes.length());
1488
CHK_ERR( rowColOffsets.reAllocate(rownodes.length()) )
1492
CHK_ERR( getPatternScatterIndices(patternID, rownodes.dataPtr(),
1493
colnodes.dataPtr(), rowIndices,
1494
rowColOffsets,numColsPerRow,
1497
if (rownodes.length() == 0 || colnodes.length() == 0) ERReturn(-1)
1499
int colIndicesPerRow = colIndices.length()/rownodes.length();
1501
SSGraph ssgraph(rowIndices.length(),
1502
rowIndices.dataPtr(),
1504
rowColOffsets.dataPtr(),
1505
colIndices.dataPtr());
1507
CHK_ERR( createEqnStructure(ssgraph) );
1511
return(FEI_SUCCESS);
1514
//------------------------------------------------------------------------------
1515
1328
NodeDescriptor& SNL_FEI_Structure::findNodeDescriptor(GlobalID nodeID)
1844
1661
//------------------------------------------------------------------------------
1845
int SNL_FEI_Structure::storePatternScatterIndices(SSGraph& mat)
1848
//This function takes a "small" matrix-graph structure, and puts the indices
1849
//either into the global sparse matrix structure, or into the EqnCommMgr if
1850
//they represent an off-processor matrix location.
1853
int numRows = mat.getRows().length();
1854
int* rows = mat.getRows().dataPtr();
1856
if (numRows == 0) return(FEI_SUCCESS);
1858
feiArray<feiArray<int>*>& indices = mat.getIndices();
1860
for(int i=0; i<numRows; i++) {
1862
int reducedRow = -1;
1863
bool isSlave = translateToReducedEqn(row, reducedRow);
1864
if (isSlave) ERReturn(-1);
1866
feiArray<int>& colIndices = *(indices[i]);
1868
workSpace_.resize(colIndices.length());
1869
for(int jj=0; jj<colIndices.length(); jj++) {
1870
isSlave = translateToReducedEqn(colIndices[jj], workSpace_[jj]);
1871
if (isSlave) ERReturn(-1);
1874
if ((localStartRow_ > row) || (row > localEndRow_)) {
1875
int owner = getOwnerProcForEqn(row);
1876
eqnCommMgr_->addRemoteIndices(reducedRow, owner,
1877
workSpace_.dataPtr(),
1878
workSpace_.length());
1882
for(int j=0; j<workSpace_.length(); j++) {
1883
CHK_ERR( createMatrixPosition(reducedRow, workSpace_[j],
1884
"storePatScttrInd") );
1887
return(FEI_SUCCESS);
1890
//------------------------------------------------------------------------------
1891
int SNL_FEI_Structure::storePatternScatterIndices_noSlaves(SSGraph& mat)
1894
//This function takes a "small" matrix-graph structure, and puts the indices
1895
//either into the global sparse matrix structure, or into the EqnCommMgr if
1896
//they represent an off-processor matrix location.
1899
int numRows = mat.getRows().length();
1900
int* rows = mat.getRows().dataPtr();
1902
if (numRows == 0) return(FEI_SUCCESS);
1904
feiArray<feiArray<int>*>& indices = mat.getIndices();
1906
for(int i=0; i<numRows; i++) {
1909
feiArray<int>& colIndices = *(indices[i]);
1911
if ((localStartRow_ > row) || (row > localEndRow_)) {
1912
int owner = getOwnerProcForEqn(row);
1913
eqnCommMgr_->addRemoteIndices(row, owner,
1914
colIndices.dataPtr(),
1915
colIndices.length());
1919
int* colIndPtr = colIndices.dataPtr();
1920
for(int j=0; j<colIndices.length(); j++) {
1921
CHK_ERR( createMatrixPosition(row, colIndPtr[j],
1922
"storePatScttrInd_noSlvs") );
1926
return(FEI_SUCCESS);
1929
//------------------------------------------------------------------------------
1930
int SNL_FEI_Structure::createSymmEqnStructure(feiArray<int>& scatterIndices)
1662
int SNL_FEI_Structure::createSymmEqnStructure(std::vector<int>& scatterIndices)
1932
1664
//scatterIndices are both the rows and the columns for a structurally
1933
1665
//symmetric 2-dimensional contribution to the matrix.
2197
1929
//------------------------------------------------------------------------------
2198
int SNL_FEI_Structure::storeElementScatterIndices_noSlaves(feiArray<int>& indices)
2200
//This function takes a list of equation numbers as input and for each one,
2201
//if it is a local equation number, goes to that row of the sysMatIndices
2202
//structure and stores the whole list of equation numbers as column indices
2203
//in that row of the matrix structure. If the equation number is not local,
2204
//then it is given to the EqnCommMgr.
2206
int i, numIndices = indices.length();
2207
int* indPtr = indices.dataPtr();
2209
for(i=0; i<numIndices; i++) {
2210
int row = indPtr[i];
2211
if (row < localStartRow_ || row > localEndRow_) {
2212
int owner = getOwnerProcForEqn(row);
2213
eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
2217
if (generateGraph_) {
2218
fei::ctg_set<int>& thisRow =
2219
sysMatIndices_[row - reducedStartRow_];
2221
for(int j=0; j<numIndices; ++j) {
2222
if (debugOutput_ && outputLevel_ > 2) {
2223
dbgOut() << "# storeElemScttrInds_ns crtMatPoss("
2224
<< row << "," << indPtr[j] << ")"<<FEI_ENDL;
2227
thisRow.insert2(indPtr[j]);
2232
return(FEI_SUCCESS);
2235
//------------------------------------------------------------------------------
2236
int SNL_FEI_Structure::storeElementScatterBlkIndices_noSlaves(feiArray<int>& indices)
2238
//This function takes a list of equation numbers as input and for each one,
2239
//if it is a local equation number, goes to that row of the sysMatIndices
2240
//structure and stores the whole list of equation numbers as column indices
2241
//in that row of the matrix structure. If the equation number is not local,
2242
//then it is given to the EqnCommMgr.
2244
int i, numIndices = indices.length();
2245
int* indPtr = indices.dataPtr();
2247
for(i=0; i<numIndices; i++) {
2248
int row = indPtr[i];
2249
if (row < localStartRow_ || row > localEndRow_) {
2250
int owner = getOwnerProcForEqn(row);
2251
eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
2255
if (generateGraph_) {
2256
fei::ctg_set<int>& thisRow =
2257
sysMatIndices_[row - reducedStartRow_];
2259
for(int j=0; j<numIndices; ++j) {
2260
if (debugOutput_ && outputLevel_ > 2) {
2261
dbgOut() << "# storeElemScttrInds_ns crtMatPoss("
2262
<< row << "," << indPtr[j] << ")"<<FEI_ENDL;
2265
thisRow.insert2(indPtr[j]);
2270
return(FEI_SUCCESS);
2273
//------------------------------------------------------------------------------
2274
int SNL_FEI_Structure::createEqnStructure(SSGraph& mat)
2276
//This function creates the global matrix structure positions associated with
2277
//the "small" matrix-structure in 'mat'.
2278
//If there are no slave equations in either the whole problem or in 'mat',
2279
//then mat is simply handed to 'storePatternScatterIndices' which either
2280
//creates local matrix positions or makes insertions to EqnCommMgr, based on
2281
//whether the locations represented in 'mat' are local or not.
2283
//If there are slave equations present in 'mat', then its contents are
2284
//distributed into the locally-held submatrices Kdi, Kid, Kdd which will
2285
//later be assembled into the global matrix structure by the function
2286
//'assembleReducedStructure'.
2288
int numRows = mat.getRows().length();
2289
int* rows = mat.getRows().dataPtr();
2291
if (numRows == 0) return(FEI_SUCCESS);
2293
if (numSlaveEquations() == 0) {
2294
CHK_ERR( storePatternScatterIndices_noSlaves(mat) );
2295
return(FEI_SUCCESS);
2298
feiArray<feiArray<int>*>& indices = mat.getIndices();
2300
rSlave_.resize(numRows);
2302
bool anySlaves = false;
2303
for(int r=0; r<numRows; r++) {
2304
rSlave_[r] = isSlaveEqn(rows[r]);
2305
const int* indPtr = indices[r]->dataPtr();
2306
if (rSlave_[r]) anySlaves = true;
2308
for(int j=0; j<indices[r]->length(); j++) {
2309
cSlave_.append(isSlaveEqn(indPtr[j]));
2310
if (cSlave_[cSlave_.length()-1]) anySlaves = true;
2315
CHK_ERR( storePatternScatterIndices(mat) );
2316
return(FEI_SUCCESS);
2320
for(int i=0; i<numRows; i++) {
2323
int numCols = indices[i]->length();
2324
const int* indicesPtr = indices[i]->dataPtr();
2325
bool* colSlave = cSlave_.dataPtr() + offset;
2329
//Since this is a slave equation, the non-slave columns of this row go
2330
//into 'Kdi_', and the slave columns go into 'Kdd_'.
2331
for(int jj=0; jj<numCols; jj++) {
2332
int col = indicesPtr[jj];
2334
Kdd_->createPosition(row, col);
2337
Kdi_->createPosition(row, col);
2341
//We also need to put the non-slave rows of column 'row' into 'K_id'.
2342
for(int ii=0; ii<numRows; ii++) {
2343
int rowi = rows[ii];
2344
if (rSlave_[ii]) continue;
2346
int index = indices[ii]->find(row);
2347
if (index < 0) continue;
2349
Kid_->createPosition(rowi, row);
2352
reducedEqnCounter_++;
2356
else {//row is not a slave eqn...
2357
int reducedRow = -1;
2358
bool isSlave = translateToReducedEqn(row, reducedRow);
2359
if (isSlave) ERReturn(-1);
2361
bool rowIsLocal = true;
2362
if (localStartRow_ > row || row > localEndRow_) {
2366
//put all non-slave columns from this row into the assembled matrix.
2367
for(int j=0; j<numCols; j++) {
2368
int col = indicesPtr[j];
2370
if (colSlave[j]) continue;
2372
int reducedCol = -1;
2373
isSlave = translateToReducedEqn(col, reducedCol);
2374
if (isSlave) ERReturn(-1);
2377
CHK_ERR( createMatrixPosition(reducedRow, reducedCol,
2381
int owner = getOwnerProcForEqn(row);
2383
FEI_CERR << "SNL_FEI_Structure ERROR, owner-proc not found for row "
2388
eqnCommMgr_->addRemoteIndices(reducedRow, owner, &reducedCol, 1);
2394
if (reducedEqnCounter_ > 300) CHK_ERR( assembleReducedStructure() );
1930
int SNL_FEI_Structure::storeElementScatterIndices_noSlaves(std::vector<int>& indices)
1932
//This function takes a list of equation numbers as input and for each one,
1933
//if it is a local equation number, goes to that row of the sysMatIndices
1934
//structure and stores the whole list of equation numbers as column indices
1935
//in that row of the matrix structure. If the equation number is not local,
1936
//then it is given to the EqnCommMgr.
1938
int i, numIndices = indices.size();
1939
int* indPtr = &indices[0];
1941
for(i=0; i<numIndices; i++) {
1942
int row = indPtr[i];
1943
if (row < localStartRow_ || row > localEndRow_) {
1944
int owner = getOwnerProcForEqn(row);
1945
eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
1949
if (generateGraph_) {
1950
fei::ctg_set<int>& thisRow =
1951
sysMatIndices_[row - reducedStartRow_];
1953
for(int j=0; j<numIndices; ++j) {
1954
if (debugOutput_ && outputLevel_ > 2) {
1955
dbgOut() << "# storeElemScttrInds_ns crtMatPoss("
1956
<< row << "," << indPtr[j] << ")"<<FEI_ENDL;
1959
thisRow.insert2(indPtr[j]);
1964
return(FEI_SUCCESS);
1967
//------------------------------------------------------------------------------
1968
int SNL_FEI_Structure::storeElementScatterBlkIndices_noSlaves(std::vector<int>& indices)
1970
//This function takes a list of equation numbers as input and for each one,
1971
//if it is a local equation number, goes to that row of the sysMatIndices
1972
//structure and stores the whole list of equation numbers as column indices
1973
//in that row of the matrix structure. If the equation number is not local,
1974
//then it is given to the EqnCommMgr.
1976
int i, numIndices = indices.size();
1977
int* indPtr = &indices[0];
1979
for(i=0; i<numIndices; i++) {
1980
int row = indPtr[i];
1981
if (row < localStartRow_ || row > localEndRow_) {
1982
int owner = getOwnerProcForEqn(row);
1983
eqnCommMgr_->addRemoteIndices(row, owner, indPtr, numIndices);
1987
if (generateGraph_) {
1988
fei::ctg_set<int>& thisRow =
1989
sysMatIndices_[row - reducedStartRow_];
1991
for(int j=0; j<numIndices; ++j) {
1992
if (debugOutput_ && outputLevel_ > 2) {
1993
dbgOut() << "# storeElemScttrInds_ns crtMatPoss("
1994
<< row << "," << indPtr[j] << ")"<<FEI_ENDL;
1997
thisRow.insert2(indPtr[j]);
2396
2002
return(FEI_SUCCESS);
2405
2011
//resulting contributions to off-processor portions of the matrix structure to
2406
2012
//the EqnCommMgr.
2408
SSMat* D = getSlaveDependencies();
2410
//form tmpMat1_ = Kid*D
2411
CHK_ERR( Kid_->matMat(*D, *tmpMat1_) );
2413
//form tmpMat2_ = D^T*Kdi
2414
CHK_ERR( D->matTransMat(*Kdi_, *tmpMat2_) );
2416
CHK_ERR( translateMatToReducedEqns(*tmpMat1_) );
2417
CHK_ERR( translateMatToReducedEqns(*tmpMat2_) );
2418
if (numProcs_ > 1) {
2419
CHK_ERR( eqnCommMgr_->addRemoteEqns(*tmpMat1_, true) );
2420
CHK_ERR( eqnCommMgr_->addRemoteEqns(*tmpMat2_, true) );
2423
CHK_ERR( createMatrixPositions(*tmpMat1_) );
2424
CHK_ERR( createMatrixPositions(*tmpMat2_) );
2426
//form tmpMat1_ = D^T*Kdd
2427
CHK_ERR( D->matTransMat(*Kdd_, *tmpMat1_) );
2429
//form tmpMat2_ = tpmMat1_*D = D^T*Kdd*D
2430
CHK_ERR( tmpMat1_->matMat(*D, *tmpMat2_) );
2432
CHK_ERR( translateMatToReducedEqns(*tmpMat2_) );
2433
if (numProcs_ > 1) {
2434
CHK_ERR( eqnCommMgr_->addRemoteEqns(*tmpMat2_, true) );
2436
CHK_ERR( createMatrixPositions(*tmpMat2_) );
2438
Kdi_->logicalClear();
2439
Kid_->logicalClear();
2440
Kdd_->logicalClear();
2014
fei::FillableMat* D = getSlaveDependencies();
2021
//form tmpMat1_ = Kid_*D
2022
fei::multiply_CSRMat_CSRMat(csrKid, csrD, tmpMat1_);
2024
//form tmpMat2_ = D^T*Kdi_
2025
fei::multiply_trans_CSRMat_CSRMat(csrD, csrKdi, tmpMat2_);
2027
CHK_ERR( translateMatToReducedEqns(tmpMat1_) );
2028
CHK_ERR( translateMatToReducedEqns(tmpMat2_) );
2029
if (numProcs_ > 1) {
2030
CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat1_, true) );
2031
CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat2_, true) );
2034
CHK_ERR( createMatrixPositions(tmpMat1_) );
2035
CHK_ERR( createMatrixPositions(tmpMat2_) );
2037
//form tmpMat1_ = D^T*Kdd_
2038
fei::multiply_trans_CSRMat_CSRMat(csrD, csrKdd, tmpMat1_);
2040
//form tmpMat2_ = tmpMat1_*D = D^T*Kdd_*D
2041
fei::multiply_CSRMat_CSRMat(tmpMat1_, csrD, tmpMat2_);
2044
CHK_ERR( translateMatToReducedEqns(tmpMat2_) );
2045
if (numProcs_ > 1) {
2046
CHK_ERR( eqnCommMgr_->addRemoteEqns(tmpMat2_, true) );
2048
CHK_ERR( createMatrixPositions(tmpMat2_) );
2441
2053
reducedEqnCounter_ = 0;
2443
2055
return(FEI_SUCCESS);
2499
2111
//------------------------------------------------------------------------------
2500
int SNL_FEI_Structure::translateMatToReducedEqns(SSMat& mat)
2112
int SNL_FEI_Structure::translateMatToReducedEqns(fei::CSRMat& mat)
2502
//Given a matrix in global numbering, convert all of its contents to the
2114
//Given a matrix in unreduced numbering, convert all of its contents to the
2503
2115
//"reduced" equation space. If any of the row-numbers or column-indices in
2504
2116
//this matrix object are slave equations, they will not be referenced. In
2505
2117
//this case, a positive warning-code will be returned.
2507
feiArray<int>& rowNumbers = mat.getRowNumbers();
2508
feiArray<SSVec*>& rows = mat.getRows();
2510
2119
int reducedEqn = -1;
2511
2120
int foundSlave = 0;
2513
for(int i=0; i<rowNumbers.length(); i++) {
2122
fei::SparseRowGraph& srg = mat.getGraph();
2124
std::vector<int>& rowNumbers = srg.rowNumbers;
2125
for(size_t i=0; i<rowNumbers.size(); ++i) {
2514
2126
bool isSlave = translateToReducedEqn(rowNumbers[i], reducedEqn);
2515
2127
if (isSlave) foundSlave = 1;
2516
2128
else rowNumbers[i] = reducedEqn;
2518
feiArray<int>& colInds = rows[i]->indices();
2519
for(int j=0; j<colInds.length(); j++) {
2520
bool isSlave = translateToReducedEqn(colInds[j], reducedEqn);
2521
if (isSlave) foundSlave = 1;
2522
else colInds[j] = reducedEqn;
2131
std::vector<int>& colIndices = srg.packedColumnIndices;
2132
for(size_t i=0; i<colIndices.size(); ++i) {
2133
bool isSlave = translateToReducedEqn(colIndices[i], reducedEqn);
2134
if (isSlave) foundSlave = 1;
2135
else colIndices[i] = reducedEqn;
2526
2138
return(foundSlave);
2529
2141
//------------------------------------------------------------------------------
2530
int SNL_FEI_Structure::createMatrixPositions(SSMat& mat)
2142
int SNL_FEI_Structure::createMatrixPositions(fei::CSRMat& mat)
2532
2144
if (!generateGraph_) {
2536
//This function must be called with a SSMat object that already has its
2148
//This function must be called with a CSRMat object that already has its
2537
2149
//contents numbered in "reduced" equation-numbers.
2539
2151
//This function has one simple task -- for each row,col pair stored in 'mat',
2540
2152
//call 'createMatrixPosition' to make an entry in the global matrix structure
2541
2153
//if it doesn't already exist.
2543
int numRows = mat.getRowNumbers().length();
2544
int* rowNumbers = mat.getRowNumbers().dataPtr();
2545
feiArray<SSVec*>& rows = mat.getRows();
2547
for(int i=0; i<numRows; i++) {
2548
int* indicesRow = rows[i]->indices().dataPtr();
2550
for(int j=0; j<rows[i]->length(); j++) {
2551
CHK_ERR( createMatrixPosition(rowNumbers[i], indicesRow[j],
2552
"crtMatPos(SSMat)") );
2155
const std::vector<int>& rowNumbers = mat.getGraph().rowNumbers;
2156
const std::vector<int>& rowOffsets = mat.getGraph().rowOffsets;
2157
const std::vector<int>& pckColInds = mat.getGraph().packedColumnIndices;
2159
for(size_t i=0; i<rowNumbers.size(); ++i) {
2160
int row = rowNumbers[i];
2161
int offset = rowOffsets[i];
2162
int rowlen = rowOffsets[i+1]-offset;
2163
const int* indices = &pckColInds[offset];
2165
for(int j=0; j<rowlen; j++) {
2166
CHK_ERR( createMatrixPosition(row, indices[j], "crtMatPos(CSRMat)") );
3147
2766
int found = snl_fei::binarySearch(blockID, blockIDs_, insertPoint);
3150
blockIDs_.insert(blockID, insertPoint);
2769
blockIDs_.insert(blockIDs_.begin()+insertPoint, blockID);
3152
2771
BlockDescriptor* block = new BlockDescriptor;
3153
2772
block->setGlobalBlockID(blockID);
3155
blocks_.insert(block, insertPoint);
2774
blocks_.insert(blocks_.begin()+insertPoint, block);
3157
2776
ConnectivityTable* newConnTable = new ConnectivityTable;
3158
connTables_.insert(newConnTable, insertPoint);
3161
return(FEI_SUCCESS);
3164
//------------------------------------------------------------------------------
3165
int SNL_FEI_Structure::addPattern(int patternID) {
3167
//Append a patternID to our (unsorted) list of patternIDs if it isn't
3168
//already present. Also, add a pattern-descriptor if patternID wasn't
3171
int found = patternIDs_.find(patternID);
3174
patternIDs_.append(patternID);
3175
int len = patternIDs_.length();
3177
PatternDescriptor** newPttrns = new PatternDescriptor*[len];
3178
ConnectivityTable** newConn = new ConnectivityTable*[len];
3180
for(int i=0; i<len-1; i++) {
3181
newPttrns[i] = patterns_[i];
3182
newConn[i] = patternConn_[i];
3184
newPttrns[len-1] = new PatternDescriptor;
3185
newConn[len-1] = new ConnectivityTable;
3187
newPttrns[len-1]->setPatternID(patternID);
3189
delete [] patterns_;
3190
patterns_ = newPttrns;
3192
delete [] patternConn_;
3193
patternConn_ = newConn;
2777
connTables_.insert(connTables_.begin()+insertPoint, newConnTable);
3196
2780
return(FEI_SUCCESS);
3497
//we also need to run through the patterns and their connectivities, and
3498
//add the fields for each pattern to the nodes that are accessed using that
3502
int numPatterns = patternIDs_.length();
3503
for(int i=0; i<numPatterns; i++) {
3504
PatternDescriptor& pattern = *(patterns_[i]);
3506
feiArray<int>& fieldsPerRow = pattern.getNumFieldsPerRow();
3507
feiArray<int>* rowFields = pattern.getRowFieldIDs();
3508
feiArray<int>& fieldsPerCol = pattern.getNumFieldsPerCol();
3509
feiArray<int>* colFields = pattern.getColFieldIDs();
3510
int numColIDsPerRow = pattern.getNumColIDsPerRow();
3512
int n,numConnRows = patternConn_[i]->numRows;
3513
int offset = 0, loopCount = numConnRows/2;
3514
for(int r=0; r<loopCount; r++) {
3515
feiArray<GlobalID>& rowIDs = *(patternConn_[i]->connectivities[offset++]);
3516
feiArray<GlobalID>& colIDs = *(patternConn_[i]->connectivities[offset++]);
3518
for(n=0; n<rowIDs.length(); n++) {
3519
NodeDescriptor* node = NULL;
3520
CHK_ERR( nodeDatabase_->getNodeWithID(rowIDs[n], node) );
3522
for(int f=0; f<fieldsPerRow[n]; f++) {
3523
node->addField((rowFields[n])[f]);
3526
node->setOwnerProc(localProc_);
3527
nodeCommMgr_->informLocal(*node);
3529
for(int c=0; c<fieldsPerCol.length(); c++) {
3530
CHK_ERR(nodeDatabase_->getNodeWithID(colIDs[n*numColIDsPerRow + c],
3533
for(int f=0; f<fieldsPerCol[c]; f++) {
3534
node->addField((colFields[c])[f]);
3537
node->setOwnerProc(localProc_);
3538
// nodeCommMgr_->informLocal(*node);
3544
2989
activeNodesInitialized_ = true;
3546
2991
if (debugOutput_) os << "# leaving finalizeActiveNodes" << FEI_ENDL;
3822
3265
if (debugOutput_) os << "# calculateSlaveEqns" << FEI_ENDL;
3824
3267
if (eqnCommMgr_ != NULL) delete eqnCommMgr_;
3825
eqnCommMgr_ = new EqnCommMgr(*commUtilsInt_);
3268
eqnCommMgr_ = new EqnCommMgr(comm_);
3826
3269
eqnCommMgr_->setNumRHSs(1);
3831
feiArray<int> mEqns;
3832
feiArray<double> mCoefs;
3834
for(i=0; i<slaveVars_->length(); i++) {
3271
std::vector<int> eqns;
3272
std::vector<int> mEqns;
3273
std::vector<double> mCoefs;
3275
for(size_t i=0; i<slaveVars_->size(); i++) {
3836
3277
SlaveVariable* svar = (*slaveVars_)[i];
3838
3279
eqns.resize( getFieldSize(svar->getFieldID()));
3839
3280
CHK_ERR( getEqnNumbers(svar->getNodeID(), FEI_NODE, svar->getFieldID(),
3840
numEqns, eqns.dataPtr()));
3281
numEqns, &eqns[0]));
3842
3283
int slaveEqn = eqns[svar->getFieldOffset()];
3844
const feiArray<GlobalID>* mNodes = svar->getMasterNodeIDs();
3845
const feiArray<int>* mFields = svar->getMasterFields();
3846
const feiArray<double>* mWeights = svar->getWeights();
3847
const feiArray<double>& mWeightsRef = *mWeights;
3285
const std::vector<GlobalID>* mNodes = svar->getMasterNodeIDs();
3286
const std::vector<int>* mFields = svar->getMasterFields();
3287
const std::vector<double>* mWeights = svar->getWeights();
3288
const std::vector<double>& mWeightsRef = *mWeights;
3848
3289
int mwOffset = 0;
3850
for(int j=0; j<mNodes->length(); j++) {
3291
for(size_t j=0; j<mNodes->size(); j++) {
3851
3292
int mfSize = getFieldSize((*mFields)[j]);
3853
3294
eqns.resize(mfSize);
3854
3295
GlobalID mNodeID = (*mNodes)[j];
3855
3296
int mFieldID = (*mFields)[j];
3856
3297
CHK_ERR( getEqnNumbers( mNodeID, FEI_NODE, mFieldID,
3857
mfSize, eqns.dataPtr()));
3859
3300
double fei_eps = 1.e-49;
3861
3302
for(int k=0; k<mfSize; k++) {
3862
3303
if (std::abs(mWeightsRef[mwOffset++]) > fei_eps) {
3863
mEqns.append(eqns[k]);
3864
mCoefs.append(mWeightsRef[mwOffset-1]);
3304
mEqns.push_back(eqns[k]);
3305
mCoefs.push_back(mWeightsRef[mwOffset-1]);
3869
CHK_ERR( slaveEqns_->addEqn(slaveEqn, mCoefs.dataPtr(), mEqns.dataPtr(),
3870
mEqns.length(), false) );
3310
CHK_ERR( slaveEqns_->addEqn(slaveEqn, &mCoefs[0], &mEqns[0],
3311
mEqns.size(), false) );
3871
3312
mEqns.resize(0);
3872
3313
mCoefs.resize(0);
3875
3316
#ifndef FEI_SER
3876
int numLocalSlaves = slaveVars_->length();
3317
int numLocalSlaves = slaveVars_->size();
3877
3318
int globalMaxSlaves = 0;
3878
CHK_ERR( commUtilsInt_->GlobalMax(numLocalSlaves, globalMaxSlaves) );
3319
CHK_ERR( fei::GlobalMax(comm_, numLocalSlaves, globalMaxSlaves) );
3880
3321
if (globalMaxSlaves > 0) {
3881
3322
CHK_ERR( gatherSlaveEqns(comm, eqnCommMgr_, slaveEqns_) );
4486
3921
//------------------------------------------------------------------------------
4487
int SNL_FEI_Structure::getPatternScatterIndices(int patternID,
4488
const GlobalID* rowNodes,
4489
const GlobalID* colNodes,
4490
feiArray<int>& rowIndices,
4491
feiArray<int>& rowColOffsets,
4492
int& colIndicesPerRow,
4493
feiArray<int>& colIndices)
4495
int index = patternIDs_.find(patternID);
4498
FEI_CERR << "SNL_FEI_Structure::getPatternScatterIndices: ERROR, patternID "
4499
<< (int)patternID << " not found." << FEI_ENDL;
4503
PatternDescriptor& pattern = *(patterns_[index]);
4505
NodeDescriptor** rNodeDesc = NULL;
4506
NodeDescriptor** cNodeDesc = NULL;
4508
CHK_ERR( getPatternNodeDescriptors(pattern, rowNodes, colNodes,
4509
rNodeDesc, cNodeDesc) );
4511
int numRows = pattern.getNumRowIDs();
4512
int numColsPerRow = pattern.getNumColIDsPerRow();
4513
int interleave = pattern.getInterleaveStrategy();
4515
feiArray<int>& fieldsPerRow = pattern.getNumFieldsPerRow();
4516
feiArray<int>* rowFieldIDs = pattern.getRowFieldIDs();
4518
feiArray<int>& fieldsPerCol = pattern.getNumFieldsPerCol();
4519
feiArray<int>* colFieldIDs = pattern.getColFieldIDs();
4520
int** cFieldIDs = new int*[fieldsPerCol.length()];
4521
for(int c=0; c<fieldsPerCol.length(); c++)
4522
cFieldIDs[c] = colFieldIDs[c].dataPtr();
4525
colIndicesPerRow = 0;
4527
for(i=0; i<fieldsPerCol.length(); i++) {
4528
for(int j=0; j<fieldsPerCol[i]; j++)
4529
colIndicesPerRow += getFieldSize(colFieldIDs[i][j]);
4532
colIndices.resize(numRows*colIndicesPerRow);
4534
CHK_ERR( setPatternRowColOffsets( pattern, colIndicesPerRow, rowColOffsets) );
4536
for(i=0; i<numRows; i++) {
4539
if (interleave == FEI_NODE_MAJOR) {
4540
CHK_ERR( getNodeMajorIndices(&(cNodeDesc[i*numColsPerRow]),
4542
cFieldIDs, fieldsPerCol.dataPtr(),
4543
&(colIndices[i*colIndicesPerRow]), dummy2) )
4546
CHK_ERR(getFieldMajorIndices(&(cNodeDesc[i*numColsPerRow]),
4548
cFieldIDs, fieldsPerCol.dataPtr(),
4549
&(colIndices[i*colIndicesPerRow]), dummy2) )
4553
delete [] cFieldIDs;
4555
if (interleave == FEI_NODE_MAJOR) {
4556
CHK_ERR( getNodeMajorIndices(rNodeDesc, numRows,
4557
rowFieldIDs, fieldsPerRow, rowIndices ) );
4560
CHK_ERR( getFieldMajorIndices(rNodeDesc, numRows,
4561
rowFieldIDs, fieldsPerRow, rowIndices) );
4564
return(FEI_SUCCESS);
4567
//------------------------------------------------------------------------------
4568
int SNL_FEI_Structure::setPatternRowColOffsets(PatternDescriptor& pattern,
4570
feiArray<int>& rowColOffsets)
4572
//This function sets the rowColOffsets array. The length of this array will
4573
//be the number of row-indices associated with the pattern. The contents of
4574
//this array will be offsets into an array of column-indices, which is of
4575
//length num-row-IDs * numColIndices. The tricky thing here is that the
4576
//order of those offsets varies depending on whether the pattern's interleave
4577
//strategy is FEI_NODE_MAJOR or FEI_FIELD_MAJOR.
4579
rowColOffsets.resize(0);
4581
//First, get the row-field info and num-row-ids info.
4582
int numRowIDs = pattern.getNumRowIDs();
4583
feiArray<int>& numFieldsPerRow = pattern.getNumFieldsPerRow();
4584
feiArray<int>* rowFieldIDs = pattern.getRowFieldIDs();
4586
//numFieldsPerRow is a list of length numRowIDs.
4587
//rowFieldIDs is a list of feiArrays. There are 'numRowIDs' feiArrays, and
4588
//the i-th feiArray is of length numFieldsPerRow[i].
4590
int interleave = pattern.getInterleaveStrategy();
4593
//if interleave == FEI_NODE_MAJOR then we simply loop over the rowFieldIDs
4594
//and increment the col-offset by numColIndices once each row-ID.
4596
//if interleave == FEI_FIELD_MAJOR then we need to first create a flat list
4597
//of the fieldIDs (each appearing only once) and then loop over the
4598
//rowFieldIDs table once for each unique fieldID, and whenever that fieldID is
4599
//encountered, append an offset to the list. The offset to be appended will be
4600
//'current-row-id'*numColIndices.
4602
if (interleave == FEI_NODE_MAJOR) {
4604
for(int rowID=0; rowID<numRowIDs; rowID++) {
4605
for(int field=0; field<numFieldsPerRow[rowID]; field++) {
4606
int numEqns = getFieldSize(rowFieldIDs[rowID][field]);
4607
if (numEqns < 0) ERReturn(-1);
4609
for(int eqn=0; eqn<numEqns; eqn++) {
4610
rowColOffsets.append(colOffset);
4613
colOffset += numColIndices;
4616
else if (interleave == FEI_FIELD_MAJOR) {
4618
feiArray<int> fields;
4619
for(i=0; i<numRowIDs; i++) {
4620
for(int j=0; j<numFieldsPerRow[i]; j++) {
4621
if (fields.find(rowFieldIDs[i][j]) < 0)
4622
fields.append(rowFieldIDs[i][j]);
4626
for(i=0; i<fields.length(); i++) {
4627
for(int rowID=0; rowID<numRowIDs; rowID++) {
4628
for(int field=0; field<numFieldsPerRow[rowID]; field++) {
4629
if (fields[i] == rowFieldIDs[rowID][field]) {
4630
int numEqns = getFieldSize(fields[i]);
4631
if (numEqns < 0) ERReturn(-1);
4633
for(int eqn=0; eqn<numEqns; eqn++) {
4634
rowColOffsets.append(rowID*numColIndices);
4642
return(FEI_SUCCESS);
4645
//------------------------------------------------------------------------------
4646
int SNL_FEI_Structure::getPatternScatterIndices(int patternID,
4647
const GlobalID* rowNodes,
4648
feiArray<int>& rowIndices)
4650
int index = patternIDs_.find(patternID);
4653
FEI_CERR << "SNL_FEI_Structure::getPatternScatterIndices: ERROR, patternID "
4654
<< (int)patternID << " not found." << FEI_ENDL;
4658
PatternDescriptor& pattern = *(patterns_[index]);
4660
int interleave = pattern.getInterleaveStrategy();
4662
int numRows = pattern.getNumRowIDs();
4663
feiArray<int>& fieldsPerRow = pattern.getNumFieldsPerRow();
4664
feiArray<int>* rowFieldIDs = pattern.getRowFieldIDs();
4666
NodeDescriptor** rNodeDesc = NULL;
4667
NodeDescriptor** cNodeDesc = NULL;
4669
int err = getPatternNodeDescriptors(pattern, rowNodes, NULL,
4670
rNodeDesc, cNodeDesc);
4671
if (err) return(err);
4673
if (interleave == FEI_NODE_MAJOR) {
4674
err = getNodeMajorIndices(rNodeDesc, numRows,
4675
rowFieldIDs, fieldsPerRow, rowIndices);
4676
if (err) return(err);
4679
err = getFieldMajorIndices(rNodeDesc, numRows,
4680
rowFieldIDs, fieldsPerRow, rowIndices);
4681
if (err) return(err);
4684
return(FEI_SUCCESS);
4687
//------------------------------------------------------------------------------
4688
3922
int SNL_FEI_Structure::getElemNodeDescriptors(int blockIndex, int elemIndex,
4689
3923
NodeDescriptor** nodes)