9 #include <fei_macros.hpp>
11 #include <test_utils/HexBeam.hpp>
14 #define fei_file "HexBeam.cpp"
16 HexBeam::HexBeam(
int W,
int D,
int DofPerNode,
17 int decomp,
int numProcs,
int localProc)
22 localProc_(localProc),
27 dofPerNode_(DofPerNode)
29 totalNumElems_ = W*W*D;
30 totalNumNodes_ = (W+1)*(W+1)*(D+1);
31 numElemsPerSlice_ = W*W;
32 numNodesPerSlice_ = (W+1)*(W+1);
34 numGlobalDOF_ = totalNumNodes_*dofPerNode_;
36 numLocalSlices_ = D/numProcs;
37 int remainder = D%numProcs;
42 throw std::runtime_error(
"HexBeam: size D must be greater or equal num-procs.");
44 if (localProc < remainder) {
48 localNumNodes_ = numNodesPerSlice_*(numLocalSlices_+1);
49 localNumElems_ = numElemsPerSlice_*numLocalSlices_;
50 numLocalDOF_ = localNumNodes_*dofPerNode_;
53 firstLocalElem_ = localProc*numLocalSlices_*numElemsPerSlice_;
54 firstLocalNode_ = localProc*numLocalSlices_*numNodesPerSlice_;
55 if (remainder <= localProc && remainder > 0) {
56 firstLocalElem_ += remainder*numElemsPerSlice_;
57 firstLocalNode_ += remainder*numNodesPerSlice_;
67 <<
" aborting." << FEI_ENDL;
76 int HexBeam::getElemConnectivity(
int elemID,
int* nodeIDs)
78 if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
82 int whichGlobalSlice = elemID/numElemsPerSlice_;
83 int elemX = elemID%W_;
84 int elemY = (elemID%(W_*W_))/W_;
86 int firstElemNode = whichGlobalSlice*numNodesPerSlice_
87 + elemY*(W_+1) + elemX;
89 nodeIDs[0] = firstElemNode;
90 nodeIDs[1] = firstElemNode+1;
91 nodeIDs[2] = firstElemNode+W_+1;
92 nodeIDs[3] = nodeIDs[2]+1;
94 nodeIDs[4] = nodeIDs[0]+numNodesPerSlice_;
95 nodeIDs[5] = nodeIDs[1]+numNodesPerSlice_;
96 nodeIDs[6] = nodeIDs[2]+numNodesPerSlice_;
97 nodeIDs[7] = nodeIDs[3]+numNodesPerSlice_;
102 int HexBeam::getElemStiffnessMatrix(
int elemID,
double* elemMat)
104 if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
108 int i, len = nodesPerElem_*dofPerNode_*nodesPerElem_*dofPerNode_;
110 for(i=0; i<len; ++i) {
120 len = nodesPerElem_*dofPerNode_;
121 for(i=0; i<len; ++i) {
122 int offset = i*len+i;
123 elemMat[offset] = 4.0;
127 for(i=0; i<len; ++i) {
128 int offset = i*len+i;
130 elemMat[offset-2] = -0.5;
134 elemMat[offset+2] = -0.5;
138 elemMat[offset-4] = -0.1;
141 elemMat[offset+4] = -0.1;
148 int HexBeam::getElemLoadVector(
int elemID,
double* elemVec)
150 if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
154 int i, len = nodesPerElem_*dofPerNode_;
155 for(i=0; i<len; ++i) {
162 int HexBeam::getNumBCNodes()
164 int numBCNodes = (numLocalSlices_+1)*(W_+1);
165 return( numBCNodes );
168 int HexBeam::getBCNodes(
int numNodes,
int* nodeIDs)
170 if (numNodes != getNumBCNodes()) {
174 int firstBCNode = firstLocalNode_ + W_;
176 for(
int i=0; i<numNodes; ++i) {
177 nodeIDs[i] = firstBCNode + W_+1;
183 int HexBeam::getBCValues(
int numBCNodes,
int* offsetsIntoField,
double* vals)
185 if (numBCNodes != getNumBCNodes()) {
189 for(
int i=0; i<numBCNodes; ++i) {
190 offsetsIntoField[i] = 0;
197 int HexBeam::getNumSharedNodes()
199 if (numProcs_ < 2)
return(0);
201 int numSharedNodes = numNodesPerSlice_;
202 if (localProc_ > 0 && localProc_ < numProcs_-1) {
203 numSharedNodes += numNodesPerSlice_;
206 return(numSharedNodes);
209 int HexBeam::getSharedNodes(
int numSharedNodes,
211 int*& numSharingProcsPerNode,
214 if (numProcs_ < 2)
return(0);
216 if (numSharedNodes != getNumSharedNodes()) {
220 sharedNodes =
new int[numSharedNodes];
221 numSharingProcsPerNode =
new int[numSharedNodes];
222 sharingProcs =
new int*[numSharedNodes];
223 int* sharingProcVals =
new int[numSharedNodes];
224 if (sharedNodes == NULL || numSharingProcsPerNode == NULL ||
225 sharingProcs == NULL || sharingProcVals == NULL) {
230 for(i=0; i<numSharedNodes; ++i) {
231 numSharingProcsPerNode[i] = 1;
232 sharingProcs[i] = &(sharingProcVals[i]);
235 int firstSharedNode = firstLocalNode_+numNodesPerSlice_*numLocalSlices_;
238 if (localProc_ < numProcs_ - 1) {
239 for(i=0; i<numNodesPerSlice_; ++i) {
240 sharedNodes[offset] = firstSharedNode+i;
241 sharingProcs[offset++][0] = localProc_+1;
245 firstSharedNode = firstLocalNode_;
246 if (localProc_ > 0) {
247 for(i=0; i<numNodesPerSlice_; ++i) {
248 sharedNodes[offset] = firstSharedNode+i;
249 sharingProcs[offset++][0] = localProc_-1;
256 namespace HexBeam_Functions {
258 int print_cube_data(
HexBeam& hexcube,
int numProcs,
int localProc)
260 FEI_COUT << localProc <<
": num elems: " << hexcube.numLocalElems() << FEI_ENDL;
262 int* nodeIDs =
new int[hexcube.numNodesPerElem()];
263 int firstLocalElem = hexcube.firstLocalElem();
265 for(i=0; i<hexcube.numLocalElems(); ++i) {
266 hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs);
267 FEI_COUT << localProc <<
": elem " << firstLocalElem+i <<
", nodes: ";
268 for(
int j=0; j<hexcube.numNodesPerElem(); ++j) {
269 FEI_COUT << nodeIDs[j] <<
" ";
271 FEI_COUT << FEI_ENDL;
280 int init_elem_connectivities(
FEI* fei,
HexBeam& hexcube)
282 int numLocalElems = hexcube.numLocalElems();
283 int firstLocalElem = hexcube.firstLocalElem();
284 int nodesPerElem = hexcube.numNodesPerElem();
287 int** fieldIDsTable =
new int*[nodesPerElem];
288 int* numFieldsPerNode =
new int[nodesPerElem];
290 for(
int j=0; j<nodesPerElem; ++j) {
291 numFieldsPerNode[j] = 1;
292 fieldIDsTable[j] =
new int[numFieldsPerNode[j]];
293 for(
int k=0; k<numFieldsPerNode[j]; ++k) {
294 fieldIDsTable[j][k] = fieldID;
309 int* nodeIDs =
new int[nodesPerElem];
310 if (nodeIDs == NULL)
return(-1);
312 for(
int i=0; i<numLocalElems; ++i) {
313 CHK_ERR( hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs) );
315 CHK_ERR( fei->
initElem(blockID, firstLocalElem+i, nodeIDs) );
319 delete [] numFieldsPerNode;
320 for(
int jj=0; jj<nodesPerElem; ++jj) {
321 delete [] fieldIDsTable[jj];
323 delete [] fieldIDsTable;
328 int init_shared_nodes(
FEI* fei,
HexBeam& hexcube)
330 int numSharedNodes = hexcube.getNumSharedNodes();
331 if (numSharedNodes == 0) {
335 int* sharedNodes = NULL;
336 int* numSharingProcsPerNode = NULL;
337 int** sharingProcs = NULL;
338 if (numSharedNodes > 0) {
339 CHK_ERR( hexcube.getSharedNodes(numSharedNodes,
340 sharedNodes, numSharingProcsPerNode,
345 numSharingProcsPerNode, sharingProcs) );
347 delete [] sharedNodes;
348 delete [] numSharingProcsPerNode;
349 delete [] sharingProcs[0];
350 delete [] sharingProcs;
355 int init_constraints(
FEI* fei,
HexBeam& hexcube,
int& firstLocalCRID)
357 int numCRs = hexcube.getNumCRs();
362 int numNodesPerCR = hexcube.getNumNodesPerCR();
363 int* crnodes_1d =
new int[numCRs*numNodesPerCR];
364 int** crNodes =
new int*[numCRs];
366 for(i=0; i<numCRs; ++i) {
367 crNodes[i] = &(crnodes_1d[offset]);
368 offset += numNodesPerCR;
371 CHK_ERR( hexcube.getCRNodes(crNodes) );
374 int* fieldIDs =
new int[numNodesPerCR];
375 for(i=0; i<numNodesPerCR; ++i) fieldIDs[i] = 0;
377 for(i=0; i<numCRs; ++i) {
378 CHK_ERR( fei->
initCRMult(numNodesPerCR, crNodes[i], fieldIDs, crID) );
386 firstLocalCRID = crID;
390 delete [] crnodes_1d;
397 int load_constraints(
FEI* fei,
HexBeam& hexcube,
int firstLocalCRID)
399 int numCRs = hexcube.getNumCRs();
404 int numNodesPerCR = hexcube.getNumNodesPerCR();
405 int* crnodes_1d =
new int[numCRs*numNodesPerCR];
406 int** crNodes =
new int*[numCRs];
408 for(i=0; i<numCRs; ++i) {
409 crNodes[i] = &(crnodes_1d[offset]);
410 offset += numNodesPerCR;
413 CHK_ERR( hexcube.getCRNodes(crNodes) );
415 int* fieldIDs =
new int[numNodesPerCR];
416 for(i=0; i<numNodesPerCR; ++i) fieldIDs[i] = 0;
418 int fieldSize = hexcube.numDofPerNode();
419 double* weights =
new double[fieldSize*numNodesPerCR];
421 for(i=0; i<fieldSize*numNodesPerCR; ++i) weights[i] = 0.0;
423 weights[fieldSize] = 1.0;
424 double rhsValue = 0.0;
426 for(i=0; i<numCRs; ++i) {
428 numNodesPerCR, crNodes[i], fieldIDs,
429 weights, rhsValue) );
432 delete [] crnodes_1d;
440 int load_elem_data(
FEI* fei,
HexBeam& hexcube)
443 int numLocalElems = hexcube.localNumElems_;
444 int firstLocalElem = hexcube.firstLocalElem_;
445 int nodesPerElem = hexcube.numNodesPerElem();
446 int fieldSize = hexcube.numDofPerNode();
448 int len = nodesPerElem*fieldSize;
449 double* elemMat =
new double[len*len];
450 double** elemMat2D =
new double*[len];
451 double* elemVec =
new double[len];
453 int* nodeIDs =
new int[nodesPerElem];
455 if (elemMat == NULL || elemMat2D == NULL || elemVec == NULL ||
460 for(
int j=0; j<len; ++j) {
461 elemMat2D[j] = &(elemMat[j*len]);
464 CHK_ERR( hexcube.getElemStiffnessMatrix(firstLocalElem, elemMat) );
465 CHK_ERR( hexcube.getElemLoadVector(firstLocalElem, elemVec) );
467 for(
int i=0; i<numLocalElems; ++i) {
468 CHK_ERR( hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs) );
471 nodeIDs, elemMat2D, FEI_DENSE_ROW) );
473 CHK_ERR( fei->
sumInElemRHS(blockID, firstLocalElem+i, nodeIDs, elemVec) );
486 int numBCNodes = hexcube.getNumBCNodes();
487 if (numBCNodes == 0) {
491 int* nodeIDs =
new int[numBCNodes];
495 int* offsetsIntoField =
new int[numBCNodes];
496 double* prescribed_vals =
new double[numBCNodes];
498 CHK_ERR( hexcube.getBCNodes(numBCNodes, nodeIDs) );
500 CHK_ERR( hexcube.getBCValues(numBCNodes, offsetsIntoField, prescribed_vals) );
503 fieldID, offsetsIntoField, prescribed_vals) );
506 delete [] offsetsIntoField;
507 delete [] prescribed_vals;
514 int numLocalElems = hexcube.localNumElems_;
515 int firstLocalElem = hexcube.firstLocalElem_;
516 int nodesPerElem = hexcube.numNodesPerElem();
525 nodeIDType, fieldID);
538 int* nodeIDs =
new int[nodesPerElem];
539 if (nodeIDs == NULL)
return(-1);
541 for(
int i=0; i<numLocalElems; ++i) {
542 CHK_ERR( hexcube.getElemConnectivity(firstLocalElem+i, nodeIDs) );
544 CHK_ERR( matrixGraph->
initConnectivity(blockID, firstLocalElem+i, nodeIDs) );
554 int numSharedNodes = hexcube.getNumSharedNodes();
555 if (numSharedNodes == 0) {
559 int* sharedNodes = NULL;
560 int* numSharingProcsPerNode = NULL;
561 int** sharingProcs = NULL;
562 if (numSharedNodes > 0) {
563 CHK_ERR( hexcube.getSharedNodes(numSharedNodes,
564 sharedNodes, numSharingProcsPerNode,
572 CHK_ERR( nodeSpace->
initSharedIDs(numSharedNodes, nodeIDType,
573 sharedNodes, numSharingProcsPerNode,
576 delete [] sharedNodes;
577 delete [] numSharingProcsPerNode;
578 delete [] sharingProcs[0];
579 delete [] sharingProcs;
585 int localProc,
int& firstLocalCRID)
587 int numCRs = hexcube.getNumCRs();
592 int numNodesPerCR = hexcube.getNumNodesPerCR();
593 int* crnodes_1d =
new int[numCRs*numNodesPerCR];
594 int** crNodes =
new int*[numCRs];
596 for(i=0; i<numCRs; ++i) {
597 crNodes[i] = &(crnodes_1d[offset]);
598 offset += numNodesPerCR;
601 CHK_ERR( hexcube.getCRNodes(crNodes) );
603 int crID = localProc*100000;
604 firstLocalCRID = crID;
609 int* fieldIDs =
new int[numNodesPerCR];
610 int* idTypes =
new int[numNodesPerCR];
611 for(i=0; i<numNodesPerCR; ++i) {
613 idTypes[i] = nodeIDType;
616 for(i=0; i<numCRs; ++i) {
629 delete [] crnodes_1d;
638 int numCRs = hexcube.getNumCRs();
643 int numNodesPerCR = hexcube.getNumNodesPerCR();
644 int* crnodes_1d =
new int[numCRs*numNodesPerCR];
645 int** crNodes =
new int*[numCRs];
647 for(i=0; i<numCRs; ++i) {
648 crNodes[i] = &(crnodes_1d[offset]);
649 offset += numNodesPerCR;
652 CHK_ERR( hexcube.getCRNodes(crNodes) );
656 int* fieldIDs =
new int[numNodesPerCR];
657 int* idTypes =
new int[numNodesPerCR];
658 for(i=0; i<numNodesPerCR; ++i) {
660 idTypes[i] = nodeIDType;
663 int fieldSize = hexcube.numDofPerNode();
664 double* weights =
new double[fieldSize*numNodesPerCR];
666 for(i=0; i<fieldSize*numNodesPerCR; ++i) weights[i] = 0.0;
668 weights[fieldSize] = 1.0;
669 double rhsValue = 0.0;
670 int offsetOfSlave = 0;
671 int offsetIntoSlaveField = 0;
673 for(i=0; i<numCRs; ++i) {
679 offsetIntoSlaveField,
684 delete [] crnodes_1d;
698 int numLocalElems = hexcube.localNumElems_;
699 int firstLocalElem = hexcube.firstLocalElem_;
700 int nodesPerElem = hexcube.numNodesPerElem();
701 int fieldSize = hexcube.numDofPerNode();
703 int len = nodesPerElem*fieldSize;
704 double* elemMat =
new double[len*len];
705 double** elemMat2D =
new double*[len];
706 double* elemVec =
new double[len];
708 if (elemMat == NULL || elemMat2D == NULL || elemVec == NULL) {
712 for(
int j=0; j<len; ++j) {
713 elemMat2D[j] = &(elemMat[j*len]);
716 CHK_ERR( hexcube.getElemStiffnessMatrix(firstLocalElem, elemMat) );
717 CHK_ERR( hexcube.getElemLoadVector(firstLocalElem, elemVec) );
720 std::vector<int> indices(len);
726 for(
int i=0; i<numLocalElems; ++i) {
731 CHK_ERR( mat->
sumIn(len, &indices[0], len, &indices[0],
732 elemMat2D, FEI_DENSE_COL) );
733 CHK_ERR( rhs->
sumIn(len, &indices[0], elemVec, 0) );
749 int numCRs = hexcube.getNumCRs();
754 int numNodesPerCR = hexcube.getNumNodesPerCR();
756 int fieldSize = hexcube.numDofPerNode();
757 double* weights =
new double[fieldSize*numNodesPerCR];
760 for(i=0; i<fieldSize*numNodesPerCR; ++i) weights[i] = 0.0;
762 weights[fieldSize] = 1.0;
763 double rhsValue = 0.0;
765 for(i=0; i<numCRs; ++i) {
767 weights, rhsValue) );
777 int numBCNodes = hexcube.getNumBCNodes();
778 if (numBCNodes == 0) {
782 int* nodeIDs =
new int[numBCNodes];
787 int* offsetsIntoField =
new int[numBCNodes];
788 double* prescribed_vals =
new double[numBCNodes];
790 CHK_ERR( hexcube.getBCNodes(numBCNodes, nodeIDs) );
792 CHK_ERR( hexcube.getBCValues(numBCNodes, offsetsIntoField, prescribed_vals) );
796 offsetsIntoField, prescribed_vals) );
798 delete [] offsetsIntoField;
799 delete [] prescribed_vals;
virtual void setIndicesMode(int mode)=0
int initSharedIDs(int numShared, int idType, const int *sharedIDs, const int *numSharingProcsPerID, const int *sharingProcs)
virtual int sumInElemMatrix(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *const *elemStiffness, int elemFormat)=0
virtual int loadEssentialBCs(int numIDs, const int *IDs, int idType, int fieldID, int offsetIntoField, const double *prescribedValues)
virtual int loadLagrangeConstraint(int constraintID, const double *weights, double rhsValue)=0
virtual bool usingBlockEntryStorage()=0
virtual int loadNodeBCs(int numNodes, const GlobalID *nodeIDs, int fieldID, const int *offsetsIntoField, const double *prescribedValues)=0
virtual int initLagrangeConstraint(int constraintID, int constraintIDType, int numIDs, const int *idTypes, const int *IDs, const int *fieldIDs)=0
virtual int initSlaveConstraint(int numIDs, const int *idTypes, const int *IDs, const int *fieldIDs, int offsetOfSlave, int offsetIntoSlaveField, const double *weights, double rhsValue)=0
virtual int loadCRMult(int CRMultID, int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, const double *CRWeights, double CRValue)=0
virtual int initCRMult(int numCRNodes, const GlobalID *CRNodeIDs, const int *CRFieldIDs, int &CRID)=0
virtual fei::SharedPtr< fei::VectorSpace > getRowSpace()=0
virtual int initConnectivity(int blockID, int connectivityID, const int *connectedIdentifiers)=0
virtual int initSharedNodes(int numSharedNodes, const GlobalID *sharedNodeIDs, const int *numProcsPerNode, const int *const *sharingProcIDs)=0
virtual int initElemBlock(GlobalID elemBlockID, int numElements, int numNodesPerElement, const int *numFieldsPerNode, const int *const *nodalFieldIDs, int numElemDofFieldsPerElement, const int *elemDOFFieldIDs, int interleaveStrategy)=0
virtual int sumIn(int numRows, const int *rows, int numCols, const int *cols, const double *const *values, int format=0)=0
virtual int getConnectivityIndices(int blockID, int connectivityID, int indicesAllocLen, int *indices, int &numIndices)=0
virtual int sumIn(int numValues, const int *indices, const double *values, int vectorIndex=0)=0
virtual fei::SharedPtr< fei::MatrixGraph > getMatrixGraph() const =0
std::ostream & console_out()
virtual int sumInElemRHS(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn, const double *elemLoad)=0
virtual int definePattern(int numIDs, int idType)=0
virtual int initElem(GlobalID elemBlockID, GlobalID elemID, const GlobalID *elemConn)=0
virtual int initConnectivityBlock(int blockID, int numConnectivityLists, int patternID, bool diagonal=false)=0