HexBeamCR.cpp

00001 /*--------------------------------------------------------------------*/
00002 /*    Copyright 2005 Sandia Corporation.                              */
00003 /*    Under the terms of Contract DE-AC04-94AL85000, there is a       */
00004 /*    non-exclusive license for use of this work by or on behalf      */
00005 /*    of the U.S. Government.  Export of this program may require     */
00006 /*    a license from the United States Government.                    */
00007 /*--------------------------------------------------------------------*/
00008 
00009 #include <fei_macros.hpp>
00010 
00011 #include <test_utils/HexBeamCR.hpp>
00012 
00013 HexBeamCR::HexBeamCR(int W, int D, int DofPerNode,
00014      int decomp, int numProcs, int localProc)
00015   : HexBeam(W, D, DofPerNode, decomp, numProcs, localProc)
00016 {
00017   totalNumElems_ = W*W*D;
00018   totalNumNodes_ = (W+1)*(W+1)*(D+1) + (W+1)*(W+1)*(2*numProcs_-1);
00019 
00020   numGlobalDOF_ = totalNumNodes_*dofPerNode_;
00021 
00022   numLocalSlices_ = D/numProcs;
00023   int remainder = D%numProcs;
00024   firstLocalSlice_ = localProc_*numLocalSlices_;
00025 
00026   switch(decomp) {
00027   case HexBeamCR::OneD:
00028     if (D < numProcs) {
00029       FEI_CERR << "HexBeamCR: too many processors." << FEI_ENDL;
00030       inErrorState_ = true;
00031       break;
00032     }
00033     if (localProc < remainder) {
00034       ++numLocalSlices_;
00035       ++firstLocalSlice_;
00036     }
00037 
00038     localNumNodes_ = numNodesPerSlice_*(numLocalSlices_+2);
00039 
00040     localNumElems_ = numElemsPerSlice_*numLocalSlices_;
00041     numLocalDOF_ = localNumNodes_*dofPerNode_;
00042 
00043     if (localProc > 0) {
00044       firstLocalElem_ = localProc*numLocalSlices_*numElemsPerSlice_;
00045 
00046       firstLocalNode_ = localProc*localNumNodes_;
00047 
00048       if (remainder <= localProc && remainder > 0) {
00049   firstLocalElem_ += remainder*numElemsPerSlice_;
00050   firstLocalNode_ += remainder*numNodesPerSlice_;
00051       }
00052     }
00053 
00054     break;
00055 
00056   case HexBeamCR::TwoD:
00057   case HexBeamCR::ThreeD:
00058   default:
00059     FEI_CERR << "HexBeamCR: invalid decomp option: " << decomp
00060    <<" aborting." << FEI_ENDL;
00061     std::abort();
00062   }
00063 
00064   localCRslice_ = firstLocalSlice_ + numLocalSlices_/2;
00065   numLocalCRs_ = numNodesPerSlice_;
00066   if (localProc_ < numProcs_-1) {
00067     numLocalCRs_ += numNodesPerSlice_;
00068   }
00069 
00070   numNodesPerCR_ = 2;
00071 }
00072 
00073 HexBeamCR::~HexBeamCR()
00074 {
00075 }
00076 
00077 int HexBeamCR::getElemConnectivity(int elemID, int* nodeIDs)
00078 {
00079   if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
00080     return(-1);
00081   }
00082 
00083   int whichGlobalSlice = elemID/numElemsPerSlice_;
00084   int elemX = elemID%W_;
00085   int elemY = (elemID%(W_*W_))/W_;
00086   //FEI_COUT << "whichGlobalSlice: " << whichGlobalSlice << FEI_ENDL;
00087   int firstElemNode = (whichGlobalSlice + localProc_*2)*numNodesPerSlice_
00088                      + elemY*(W_+1) + elemX;
00089 
00090   if (whichGlobalSlice >= localCRslice_) {
00091     firstElemNode += numNodesPerSlice_;
00092   }
00093 
00094   nodeIDs[0] = firstElemNode;
00095   nodeIDs[1] = firstElemNode+1;
00096   nodeIDs[2] = firstElemNode+W_+1;
00097   nodeIDs[3] = nodeIDs[2]+1;
00098 
00099   nodeIDs[4] = nodeIDs[0]+numNodesPerSlice_;
00100   nodeIDs[5] = nodeIDs[1]+numNodesPerSlice_;
00101   nodeIDs[6] = nodeIDs[2]+numNodesPerSlice_;
00102   nodeIDs[7] = nodeIDs[3]+numNodesPerSlice_;
00103 
00104   return(0);
00105 }
00106 
00107 int HexBeamCR::getCRNodes(int** nodeIDs)
00108 {
00109   int offset = 0;
00110   int firstCRnode = (localCRslice_+localProc_*2)*numNodesPerSlice_;
00111   int i;
00112   for(i=0; i<numNodesPerSlice_; ++i) {
00113     nodeIDs[offset][0] = firstCRnode+i;
00114     nodeIDs[offset++][1] = firstCRnode+i+numNodesPerSlice_;
00115   }
00116 
00117   if (localProc_ >= numProcs_-1) return(0);
00118 
00119   int nextCRnode = firstLocalNode_ + localNumNodes_ - numNodesPerSlice_;
00120   for(i=0; i<numNodesPerSlice_; ++i) {
00121     nodeIDs[offset][0] = nextCRnode+i;
00122     nodeIDs[offset++][1] = nextCRnode+i+numNodesPerSlice_;    
00123   }
00124 
00125   return(0);
00126 }
00127 
00128 int HexBeamCR::getElemStiffnessMatrix(int elemID, double* elemMat)
00129 {
00130   if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
00131     return(-1);
00132   }
00133 
00134   int i, len = nodesPerElem_*dofPerNode_*nodesPerElem_*dofPerNode_;
00135 
00136   for(i=0; i<len; ++i) {
00137     elemMat[i] = 0.0;
00138   }
00139 
00140   //Should set up some semi-realistic stiffness-matrix coefficients here...
00141   //For now just use arbitrary numbers and set it up so the matrix won't be
00142   //too ill-conditioned. (This is intended for an assembly test more than
00143   //a solver test.)
00144 
00145   //Now set the diagonal to 4.0
00146   len = nodesPerElem_*dofPerNode_;
00147   for(i=0; i<len; ++i) {
00148     int offset = i*len+i;
00149     elemMat[offset] = 4.0;
00150   }
00151 
00152   //Now set some off-diagonals
00153   for(i=0; i<len; ++i) {
00154     int offset = i*len+i;
00155     if (i>1) {
00156       elemMat[offset-2] = -0.5;
00157     }
00158 
00159     if (i<len-2) {
00160       elemMat[offset+2] = -0.5;
00161     }
00162 
00163     if (i>3) {
00164       elemMat[offset-4] = -0.1;
00165     }
00166     if (i<len-4) {
00167       elemMat[offset+4] = -0.1;
00168     }
00169   }
00170 
00171   return(0);
00172 }
00173 
00174 int HexBeamCR::getElemLoadVector(int elemID, double* elemVec)
00175 {
00176   if (elemID < firstLocalElem_ || elemID > firstLocalElem_+localNumElems_) {
00177     return(-1);
00178   }
00179 
00180   int i, len = nodesPerElem_*dofPerNode_;
00181   for(i=0; i<len; ++i) {
00182     elemVec[i] = 1.0;
00183   }
00184 
00185   return(0);
00186 }
00187 
00188 int HexBeamCR::getNumBCNodes()
00189 {
00190   int numBCNodes = (numLocalSlices_+1)*(W_+1);
00191   return( numBCNodes );
00192 }
00193 
00194 int HexBeamCR::getBCNodes(int numNodes, int* nodeIDs)
00195 {
00196   if (numNodes != getNumBCNodes()) {
00197     return(-1);
00198   }
00199 
00200   int firstBCNode = firstLocalNode_ + W_;
00201 
00202   for(int i=0; i<numNodes; ++i) {
00203     nodeIDs[i] = firstBCNode + W_+1;
00204   }
00205 
00206   return(0);
00207 }
00208 
00209 int HexBeamCR::getBCGammaValues(int numBCDofs, double* gamma)
00210 {
00211   if (numBCDofs != getNumBCNodes()*dofPerNode_) {
00212     return(-1);
00213   }
00214 
00215   for(int i=0; i<numBCDofs; ++i) {
00216     gamma[i] = 2.0;
00217   }
00218 
00219   return(0);
00220 }
00221 
00222 int HexBeamCR::getNumSharedNodes()
00223 {
00224   if (numProcs_ < 2) return(0);
00225 
00226   int numSharedNodes = numNodesPerSlice_;
00227   if (localProc_ > 0 && localProc_ < numProcs_-1) {
00228     numSharedNodes += numNodesPerSlice_;
00229   }
00230 
00231   return(numSharedNodes);
00232 }
00233 
00234 int HexBeamCR::getSharedNodes(int numSharedNodes,
00235           int*& sharedNodes,
00236           int*& numSharingProcsPerNode,
00237           int**& sharingProcs)
00238 {
00239   if (numProcs_ < 2) return(0);
00240 
00241   if (numSharedNodes != getNumSharedNodes()) {
00242     return(-1);
00243   }
00244 
00245   sharedNodes = new int[numSharedNodes];
00246   numSharingProcsPerNode = new int[numSharedNodes];
00247   sharingProcs = new int*[numSharedNodes];
00248   int* sharingProcVals = new int[numSharedNodes];
00249   if (sharedNodes == NULL || numSharingProcsPerNode == NULL ||
00250       sharingProcs == NULL || sharingProcVals == NULL) {
00251     return(-1);
00252   }
00253 
00254   int i;
00255   for(i=0; i<numSharedNodes; ++i) {
00256     numSharingProcsPerNode[i] = 1;
00257     sharingProcs[i] = &(sharingProcVals[i]);
00258   }
00259 
00260   int firstSharedNode = firstLocalNode_+numNodesPerSlice_*(numLocalSlices_+2);
00261   int offset = 0;
00262   //FEI_COUT << localProc_ << ": firstSharedNode: " << firstSharedNode << FEI_ENDL;
00263   if (localProc_ < numProcs_ - 1) {
00264     for(i=0; i<numNodesPerSlice_; ++i) {
00265       sharedNodes[offset] = firstSharedNode+i;
00266       sharingProcs[offset++][0] = localProc_+1;
00267     }
00268   }
00269 
00270   firstSharedNode = firstLocalNode_;
00271   //FEI_COUT << localProc_ << ":+1 firstSharedNode: " << firstSharedNode << FEI_ENDL;
00272   if (localProc_ > 0) {
00273     for(i=0; i<numNodesPerSlice_; ++i) {
00274       sharedNodes[offset] = firstSharedNode+i;
00275       sharingProcs[offset++][0] = localProc_-1;
00276     }
00277   }
00278 
00279   return(0);
00280 }

Generated on Tue Jul 13 09:27:46 2010 for FEI by  doxygen 1.4.7