TransformationConstraintHandler.cpp

Go to the documentation of this file.
00001 /* ****************************************************************** **
00002 **    OpenSees - Open System for Earthquake Engineering Simulation    **
00003 **          Pacific Earthquake Engineering Research Center            **
00004 **                                                                    **
00005 **                                                                    **
00006 ** (C) Copyright 1999, The Regents of the University of California    **
00007 ** All Rights Reserved.                                               **
00008 **                                                                    **
00009 ** Commercial use of this program without express permission of the   **
00010 ** University of California, Berkeley, is strictly prohibited.  See   **
00011 ** file 'COPYRIGHT'  in main directory for information on usage and   **
00012 ** redistribution,  and for a DISCLAIMER OF ALL WARRANTIES.           **
00013 **                                                                    **
00014 ** Developed by:                                                      **
00015 **   Frank McKenna (fmckenna@ce.berkeley.edu)                         **
00016 **   Gregory L. Fenves (fenves@ce.berkeley.edu)                       **
00017 **   Filip C. Filippou (filippou@ce.berkeley.edu)                     **
00018 **                                                                    **
00019 ** ****************************************************************** */
00020                                                                         
00021 // $Revision: 1.12 $
00022 // $Date: 2005/11/29 22:04:40 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/handler/TransformationConstraintHandler.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: May 1998
00028 // Revision: A
00029 //
00030 // What: "@(#) TransformationConstraintHandler.C, revA"
00031 
00032 #include <TransformationConstraintHandler.h>
00033 #include <stdlib.h>
00034 
00035 #include <AnalysisModel.h>
00036 #include <Domain.h>
00037 #include <FE_Element.h>
00038 #include <FE_EleIter.h>
00039 #include <DOF_Group.h>
00040 #include <Node.h>
00041 #include <Element.h>
00042 #include <NodeIter.h>
00043 #include <ElementIter.h>
00044 #include <SP_ConstraintIter.h>
00045 #include <SP_Constraint.h>
00046 #include <MP_ConstraintIter.h>
00047 #include <MP_Constraint.h>
00048 #include <Integrator.h>
00049 #include <ID.h>
00050 #include <Subdomain.h>
00051 #include <Channel.h>
00052 #include <FEM_ObjectBroker.h>
00053 #include <TransformationDOF_Group.h>
00054 #include <TransformationFE.h>
00055 
00056 
00057 TransformationConstraintHandler::TransformationConstraintHandler()
00058 :ConstraintHandler(HANDLER_TAG_TransformationConstraintHandler),
00059  theFEs(0), theDOFs(0),numFE(0),numDOF(0),numConstrainedNodes(0)
00060 {
00061 
00062 }
00063 
00064 TransformationConstraintHandler::~TransformationConstraintHandler()
00065 {
00066   if (theDOFs != 0) 
00067     delete [] theDOFs;
00068 
00069   if (theFEs != 0)
00070     delete [] theFEs;
00071 }
00072 
00073 int
00074 TransformationConstraintHandler::handle(const ID *nodesLast)
00075 {
00076     // first check links exist to a Domain and an AnalysisModel object
00077     Domain *theDomain = this->getDomainPtr();
00078     AnalysisModel *theModel = this->getAnalysisModelPtr();
00079     Integrator *theIntegrator = this->getIntegratorPtr();    
00080     
00081     if ((theDomain == 0) || (theModel == 0) || (theIntegrator == 0)) {
00082         opserr << "WARNING TransformationConstraintHandler::handle() - ";
00083         opserr << " setLinks() has not been called\n";
00084         return -1;
00085     }
00086     
00087     // get number ofelements and nodes in the domain 
00088     // and init the theFEs and theDOFs arrays
00089     int numMPConstraints = theDomain->getNumMPs();
00090 
00091     //    int numSPConstraints = theDomain->getNumSPs();    
00092     int numSPConstraints = 0;
00093     SP_ConstraintIter &theSP1s = theDomain->getDomainAndLoadPatternSPs();
00094     SP_Constraint *theSP1; 
00095     while ((theSP1 = theSP1s()) != 0) 
00096         numSPConstraints++;
00097     
00098 
00099     numDOF = 0;
00100     ID transformedNode(0, 64);
00101 
00102     int i;
00103     
00104     // create an ID of constrained node tags in MP_Constraints
00105     ID constrainedNodesMP(0, numMPConstraints);
00106     MP_Constraint **mps =0;
00107     if (numMPConstraints != 0) {
00108         mps = new MP_Constraint *[numMPConstraints];
00109         if (mps == 0) {
00110             opserr << "WARNING TransformationConstraintHandler::handle() - ";
00111             opserr << "ran out of memory for MP_Constraints"; 
00112             opserr << " array of size " << numMPConstraints << endln;
00113             return -3;      
00114         }
00115         MP_ConstraintIter &theMPs = theDomain->getMPs();
00116         MP_Constraint *theMP; 
00117         int index = 0;
00118         while ((theMP = theMPs()) != 0) {
00119           int nodeConstrained = theMP->getNodeConstrained();
00120           if (transformedNode.getLocation(nodeConstrained) < 0)
00121             transformedNode[numDOF++] = nodeConstrained;
00122           constrainedNodesMP[index] = nodeConstrained;
00123           mps[index] = theMP;
00124           index++;
00125         }       
00126     }
00127 
00128     // create an ID of constrained node tags in SP_Constraints
00129     ID constrainedNodesSP(0, numSPConstraints);;
00130     SP_Constraint **sps =0;
00131     if (numSPConstraints != 0) {
00132         sps = new SP_Constraint *[numSPConstraints];
00133         if (sps == 0) {
00134             opserr << "WARNING TransformationConstraintHandler::handle() - ";
00135             opserr << "ran out of memory for SP_Constraints"; 
00136             opserr << " array of size " << numSPConstraints << endln;
00137             if (mps != 0) delete [] mps;
00138             if (sps != 0) delete [] sps;
00139             return -3;      
00140         }
00141         SP_ConstraintIter &theSPs = theDomain->getDomainAndLoadPatternSPs();
00142         SP_Constraint *theSP; 
00143         int index = 0;
00144         while ((theSP = theSPs()) != 0) {
00145           int constrainedNode = theSP->getNodeTag();
00146           if (transformedNode.getLocation(constrainedNode) < 0)
00147             transformedNode[numDOF++] = constrainedNode;            
00148           constrainedNodesSP[index] = constrainedNode;
00149           sps[index] = theSP;
00150           index++;
00151         }       
00152     }
00153 
00154     // create an array for the DOF_Groups and zero it
00155     if ((numDOF <= 0) || ((theDOFs = new DOF_Group *[numDOF]) == 0)) {
00156         opserr << "WARNING TransformationConstraintHandler::handle() - ";
00157         opserr << "ran out of memory for DOF_Groups";
00158         opserr << " array of size " << numDOF << endln;
00159         return -3;    
00160     }    
00161     for (i=0; i<numDOF; i++) theDOFs[i] = 0;
00162 
00163 
00164     //create a DOF_Group for each Node and add it to the AnalysisModel.
00165     //    :must of course set the initial IDs
00166     NodeIter &theNod = theDomain->getNodes();
00167     Node *nodPtr;
00168 
00169     int numDofGrp = 0;
00170     int count3 = 0;
00171     int countDOF =0;
00172     
00173     numConstrainedNodes = 0;
00174     numDOF = 0;
00175     while ((nodPtr = theNod()) != 0) {
00176 
00177         DOF_Group *dofPtr = 0;
00178 
00179         int nodeTag = nodPtr->getTag();
00180         int numNodalDOF = nodPtr->getNumberDOF();
00181         int loc = -1;
00182         int createdDOF = 0;
00183 
00184         loc = constrainedNodesMP.getLocation(nodeTag);
00185         if (loc >= 0) {
00186 
00187           TransformationDOF_Group *tDofPtr = 
00188             new TransformationDOF_Group(numDofGrp++, nodPtr, mps[loc], this); 
00189           
00190           createdDOF = 1;
00191           dofPtr = tDofPtr;
00192           
00193           // add any SPs
00194           if (numSPConstraints != 0) {
00195             loc = constrainedNodesSP.getLocation(nodeTag);
00196             if (loc >= 0) {
00197               tDofPtr->addSP_Constraint(*(sps[loc]));
00198               for (int i = loc+1; i<numSPConstraints; i++) {
00199                 if (constrainedNodesSP(i) == nodeTag)
00200                   tDofPtr->addSP_Constraint(*(sps[i]));
00201               }
00202             }
00203             // add the DOF to the array     
00204             theDOFs[numDOF++] = dofPtr;             
00205             numConstrainedNodes++;
00206           }
00207         }
00208         
00209         if (createdDOF == 0) {
00210           loc = constrainedNodesSP.getLocation(nodeTag);
00211           if (loc >= 0) {
00212             TransformationDOF_Group *tDofPtr = 
00213               new TransformationDOF_Group(numDofGrp++, nodPtr, this);
00214             
00215             int numSPs = 1;
00216             createdDOF = 1;
00217             dofPtr = tDofPtr;
00218             tDofPtr->addSP_Constraint(*(sps[loc]));
00219         
00220             // check for more SP_constraints acting on node and add them
00221             for (int i = loc+1; i<numSPConstraints; i++) {
00222               if (constrainedNodesSP(i) == nodeTag) {
00223                 tDofPtr->addSP_Constraint(*(sps[i]));
00224                 numSPs++;
00225               }
00226             }
00227             // add the DOF to the array
00228             theDOFs[numDOF++] = dofPtr;             
00229             numConstrainedNodes++;          
00230             countDOF+= numNodalDOF - numSPs;            
00231           }
00232         }
00233 
00234         // create an ordinary DOF_Group object if no dof constrained
00235         if (createdDOF == 0) {
00236             if ((dofPtr = new DOF_Group(numDofGrp++, nodPtr)) == 0) {
00237                 opserr << "WARNING TransformationConstraintHandler::handle() ";
00238                 opserr << "- ran out of memory";
00239                 opserr << " creating DOF_Group " << i << endln; 
00240                 if (mps != 0) delete [] mps;
00241                 if (sps != 0) delete [] sps;
00242                 return -4;              
00243             }
00244         
00245             countDOF+= numNodalDOF;
00246         }
00247         
00248         if (dofPtr == 0) 
00249           opserr << "TransformationConstraintHandler::handle() - error in logic\n";
00250             
00251         nodPtr->setDOF_GroupPtr(dofPtr);
00252         theModel->addDOF_Group(dofPtr);
00253     }
00254 
00255     // create the FE_Elements for the Elements and add to the AnalysisModel
00256     ElementIter &theEle = theDomain->getElements();
00257     Element *elePtr;
00258     FE_Element *fePtr;
00259 
00260     numFE = 0;
00261     ID transformedEle(0, 64);
00262 
00263     while ((elePtr = theEle()) != 0) {
00264       int flag = 0;
00265       if (elePtr->isSubdomain() == true) {
00266         Subdomain *theSub = (Subdomain *)elePtr;
00267         if (theSub->doesIndependentAnalysis() == true) 
00268           flag = 1;
00269       }
00270 
00271       if (flag == 0) {
00272       
00273         const ID &nodes = elePtr->getExternalNodes();
00274         int nodesSize = nodes.Size();
00275         int isConstrainedNode = 0;
00276         for (int i=0; i<nodesSize; i++) {
00277           int nodeTag = nodes(i);
00278           if (numMPConstraints != 0) {
00279             int loc = constrainedNodesMP.getLocation(nodeTag);
00280             if (loc >= 0) {
00281               isConstrainedNode = 1;
00282               i = nodesSize;
00283             }
00284           } 
00285           if (numSPConstraints != 0 && isConstrainedNode == 0) {
00286             int loc = constrainedNodesSP.getLocation(nodeTag);
00287             if (loc >= 0) {
00288               isConstrainedNode = 1;                
00289               i = nodesSize;
00290             }
00291           }
00292         }
00293         
00294         if (isConstrainedNode == 1) {
00295           transformedEle[numFE++] = elePtr->getTag();
00296         }
00297       }
00298     }
00299     
00300     // create an array for the FE_elements and zero it
00301     if ((numFE <= 0) || ((theFEs  = new FE_Element *[numFE]) == 0)) {
00302       opserr << "WARNING TransformationConstraintHandler::handle() - ";
00303       opserr << "ran out of memory for FE_elements"; 
00304       opserr << " array of size " << numFE << endln;
00305       return -2;
00306     }
00307     
00308     for (i=0; i<numFE; i++) theFEs[i] = 0;
00309 
00310     ElementIter &theEle1 = theDomain->getElements();
00311     
00312     // int numConstraints = numMPConstraints+numSPConstraints;
00313     int numFeEle = 0;
00314     int numFE = 0;
00315 
00316     while ((elePtr = theEle1()) != 0) {
00317       int tag = elePtr->getTag();
00318       if (elePtr->isSubdomain() == true) {
00319         Subdomain *theSub = (Subdomain *)elePtr;
00320         if (theSub->doesIndependentAnalysis() == false) {
00321           
00322           if (transformedEle.getLocation(tag) < 0) {
00323             if ((fePtr = new FE_Element(numFeEle, elePtr)) == 0) {
00324               opserr << "WARNING TransformationConstraintHandler::handle()";
00325               opserr << " - ran out of memory";
00326               opserr << " creating FE_Element " << elePtr->getTag() << endln; 
00327               if (mps != 0) delete [] mps;
00328               if (sps != 0) delete [] sps;
00329               return -5;
00330             }   
00331           } else {
00332             if ((fePtr = new TransformationFE(numFeEle, elePtr)) == 0) {                
00333               opserr << "WARNING TransformationConstraintHandler::handle()";
00334               opserr << " - ran out of memory";
00335               opserr << " creating TransformationFE " << elePtr->getTag() << endln; 
00336               if (mps != 0) delete [] mps;
00337               if (sps != 0) delete [] sps;
00338               return -6;                    
00339             }
00340             theFEs[numFE++] = fePtr;
00341           }
00342 
00343           numFeEle++;
00344           theModel->addFE_Element(fePtr);
00345           theSub->setFE_ElementPtr(fePtr);
00346         }
00347       } else {
00348         if (transformedEle.getLocation(tag) < 0) {
00349           if ((fePtr = new FE_Element(numFeEle, elePtr)) == 0) {
00350             opserr << "WARNING TransformationConstraintHandler::handle()";
00351             opserr << " - ran out of memory";
00352             opserr << " creating FE_Element " << elePtr->getTag() << endln; 
00353             if (mps != 0) delete [] mps;
00354             if (sps != 0) delete [] sps;
00355             return -5;
00356           }     
00357         } else {
00358           if ((fePtr = new TransformationFE(numFeEle, elePtr)) == 0) {          
00359             opserr << "WARNING TransformationConstraintHandler::handle()";
00360             opserr << " - ran out of memory";
00361             opserr << " creating TransformationFE " << elePtr->getTag() << endln; 
00362             if (mps != 0) delete [] mps;
00363             if (sps != 0) delete [] sps;
00364             return -6;              
00365           }
00366           theFEs[numFE++] = fePtr;
00367         }
00368         
00369         numFeEle++;
00370         theModel->addFE_Element(fePtr);
00371       }
00372     }
00373 
00374     theModel->setNumEqn(countDOF);
00375     
00376     // set the number of eqn in the model
00377     // now see if we have to set any of the dof's to -3
00378     //    int numLast = 0;
00379     if (nodesLast != 0) 
00380         for (i=0; i<nodesLast->Size(); i++) {
00381             int nodeID = (*nodesLast)(i);
00382             Node *nodPtr = theDomain->getNode(nodeID);
00383             if (nodPtr != 0) {
00384                 DOF_Group *dofPtr = nodPtr->getDOF_GroupPtr();
00385                 
00386                 const ID &id = dofPtr->getID();
00387                 // set all the dof values to -3
00388                 for (int j=0; j < id.Size(); j++) {
00389                     if (id(j) == -2) {
00390                         dofPtr->setID(j,-3);
00391                         count3++;
00392                     } else {
00393                         opserr << "WARNING TransformationConstraintHandler::handle() ";
00394                         opserr << " - boundary sp constraint in subdomain";
00395                         opserr << " this should not be - results suspect \n";
00396                         if (mps != 0) delete [] mps;
00397                         if (sps != 0) delete [] sps;
00398                     }
00399                 }
00400             }
00401         }
00402 
00403     if (mps != 0) delete [] mps;
00404     if (sps != 0) delete [] sps;
00405 
00406     return count3;
00407 }
00408 
00409 
00410 
00411 void 
00412 TransformationConstraintHandler::clearAll(void)
00413 {
00414     // delete the arrays
00415     if (theFEs != 0) delete [] theFEs;
00416     if (theDOFs != 0) delete [] theDOFs;
00417 
00418     // reset the numbers
00419     numDOF = 0;
00420     numFE =  0;
00421     theFEs = 0;
00422     theDOFs = 0;
00423 
00424     // for the nodes reset the DOF_Group pointers to 0
00425     Domain *theDomain = this->getDomainPtr();
00426     if (theDomain == 0)
00427         return;
00428 
00429     NodeIter &theNod = theDomain->getNodes();
00430     Node *nodPtr;
00431     while ((nodPtr = theNod()) != 0)
00432         nodPtr->setDOF_GroupPtr(0);
00433 }    
00434 
00435 int
00436 TransformationConstraintHandler::sendSelf(int cTag, Channel &theChannel)
00437 {
00438   return 0;
00439 }
00440 
00441 int
00442 TransformationConstraintHandler::recvSelf(int cTag, 
00443                                    Channel &theChannel, 
00444                                    FEM_ObjectBroker &theBroker)  
00445 {
00446   return 0;
00447 }
00448 
00449 
00450 int 
00451 TransformationConstraintHandler::applyLoad(void)
00452 {
00453     return this->enforceSPs();
00454 }
00455 
00456 int 
00457 TransformationConstraintHandler::enforceSPs(void)
00458 {
00459     for (int i=1; i<=numConstrainedNodes; i++) {
00460         // upward cast - safe as i put it in this location
00461         TransformationDOF_Group *theDof  =
00462             (TransformationDOF_Group *)theDOFs[numDOF-i];
00463         theDof->enforceSPs();
00464     }
00465 
00466     for (int j=0; j<numFE; j++) {
00467       FE_Element *theEle = theFEs[j];
00468       theEle->updateElement();
00469     }
00470 
00471     return 0;
00472 }
00473 
00474 int 
00475 TransformationConstraintHandler::doneNumberingDOF(void)
00476 {
00477     for (int i=1; i<=numConstrainedNodes; i++) {
00478         // upward cast - safe as i put it in this location
00479         TransformationDOF_Group *theDof  =
00480             (TransformationDOF_Group *)theDOFs[numDOF-i];
00481         theDof->doneID();
00482     }
00483 
00484     // iterate through the FE_Element getting them to set their IDs
00485     AnalysisModel *theModel=this->getAnalysisModelPtr();
00486     FE_EleIter &theEle = theModel->getFEs();
00487     FE_Element *elePtr;
00488     while ((elePtr = theEle()) != 0)
00489       elePtr->setID();
00490 
00491     return 0;
00492 }

Generated on Mon Oct 23 15:04:58 2006 for OpenSees by doxygen 1.5.0