Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

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.1.1.1 $
00022 // $Date: 2000/09/15 08:23:17 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/handler/TransformationConstraintHandler.cpp,v $
00024                                                                         
00025                                                                         
00026 // File: ~/analysis/handler/TransformationConstraintHandler.C
00027 // 
00028 // Written: fmk 
00029 // Created: May 1998
00030 // Revision: A
00031 //
00032 // What: "@(#) TransformationConstraintHandler.C, revA"
00033 
00034 #include <TransformationConstraintHandler.h>
00035 #include <stdlib.h>
00036 
00037 #include <AnalysisModel.h>
00038 #include <Domain.h>
00039 #include <FE_Element.h>
00040 #include <DOF_Group.h>
00041 #include <Node.h>
00042 #include <Element.h>
00043 #include <NodeIter.h>
00044 #include <ElementIter.h>
00045 #include <SP_ConstraintIter.h>
00046 #include <SP_Constraint.h>
00047 #include <MP_ConstraintIter.h>
00048 #include <MP_Constraint.h>
00049 #include <Integrator.h>
00050 #include <ID.h>
00051 #include <Subdomain.h>
00052 #include <Channel.h>
00053 #include <FEM_ObjectBroker.h>
00054 #include <TransformationDOF_Group.h>
00055 #include <TransformationFE.h>
00056 
00057 
00058 TransformationConstraintHandler::TransformationConstraintHandler()
00059 :ConstraintHandler(HANDLER_TAG_TransformationConstraintHandler),
00060  theFEs(0), theDOFs(0),numFE(0),numDOF(0),numConstrainedNodes(0)
00061 {
00062 
00063 }
00064 
00065 TransformationConstraintHandler::~TransformationConstraintHandler()
00066 {
00067     // delete the FE_Element and DOF_Group objects
00068     for (int i=0; i<numFE; i++)
00069  if (theFEs[i] != 0)
00070    delete theFEs[i];
00071 
00072     for (int j=0; j<numDOF; j++)
00073  if (theDOFs[j] != 0)
00074    delete theDOFs[j];
00075     
00076     // delete the arrays
00077     if (theFEs != 0) delete [] theFEs;
00078     if (theDOFs != 0) delete [] theDOFs;
00079 }
00080 
00081 int
00082 TransformationConstraintHandler::handle(const ID *nodesLast)
00083 {
00084     // first check links exist to a Domain and an AnalysisModel object
00085     Domain *theDomain = this->getDomainPtr();
00086     AnalysisModel *theModel = this->getAnalysisModelPtr();
00087     Integrator *theIntegrator = this->getIntegratorPtr();    
00088     
00089     if ((theDomain == 0) || (theModel == 0) || (theIntegrator == 0)) {
00090  cerr << "WARNING TransformationConstraintHandler::handle() - ";
00091  cerr << " setLinks() has not been called\n";
00092  return -1;
00093     }
00094     
00095     // get number ofelements and nodes in the domain 
00096     // and init the theFEs and theDOFs arrays
00097     int numMPConstraints = theDomain->getNumMPs();
00098     //    int numSPConstraints = theDomain->getNumSPs();    
00099     int numSPConstraints = 0;
00100     SP_ConstraintIter &theSP1s = theDomain->getDomainAndLoadPatternSPs();
00101     SP_Constraint *theSP1; 
00102     while ((theSP1 = theSP1s()) != 0) 
00103  numSPConstraints++;
00104     
00105     
00106     // int numConstraints = numMPConstraints+numSPConstraints;
00107     numFE = theDomain->getNumElements();
00108     numDOF = theDomain->getNumNodes();
00109 
00110     // create an array for the FE_elements and zero it
00111     if ((numFE <= 0) || ((theFEs  = new FE_Element *[numFE]) == 0)) {
00112  cerr << "WARNING TransformationConstraintHandler::handle() - ";
00113         cerr << "ran out of memory for FE_elements"; 
00114  cerr << " array of size " << numFE << endl;
00115  return -2;
00116     }
00117     int i;
00118     for (i=0; i<numFE; i++) theFEs[i] = 0;
00119 
00120     // create an array for the DOF_Groups and zero it
00121     if ((numDOF <= 0) || ((theDOFs = new DOF_Group *[numDOF]) == 0)) {
00122  cerr << "WARNING TransformationConstraintHandler::handle() - ";
00123         cerr << "ran out of memory for DOF_Groups";
00124  cerr << " array of size " << numDOF << endl;
00125  return -3;    
00126     }    
00127     for (i=0; i<numDOF; i++) theDOFs[i] = 0;
00128     
00129     // create an ID of constrained node tags in MP_Constraints
00130     ID *constrainedNodesMP =0;
00131     MP_Constraint **mps =0;
00132     if (numMPConstraints != 0) {
00133  constrainedNodesMP = new ID(numMPConstraints);
00134  mps = new MP_Constraint *[numMPConstraints];
00135  if (mps == 0) {
00136      cerr << "WARNING TransformationConstraintHandler::handle() - ";
00137      cerr << "ran out of memory for MP_Constraints"; 
00138      cerr << " array of size " << numMPConstraints << endl;
00139      return -3;     
00140  }
00141  MP_ConstraintIter &theMPs = theDomain->getMPs();
00142  MP_Constraint *theMP; 
00143  int index = 0;
00144  while ((theMP = theMPs()) != 0) {
00145      (*constrainedNodesMP)(index) = theMP->getNodeConstrained();
00146      mps[index] = theMP;
00147      index++;
00148  } 
00149     }
00150 
00151     // create an ID of constrained node tags in SP_Constraints
00152     ID *constrainedNodesSP =0;
00153     SP_Constraint **sps =0;
00154     if (numSPConstraints != 0) {
00155  constrainedNodesSP = new ID(numSPConstraints);
00156  sps = new SP_Constraint *[numSPConstraints];
00157  if (sps == 0) {
00158      cerr << "WARNING TransformationConstraintHandler::handle() - ";
00159      cerr << "ran out of memory for SP_Constraints"; 
00160      cerr << " array of size " << numSPConstraints << endl;
00161      return -3;     
00162  }
00163  SP_ConstraintIter &theSPs = theDomain->getDomainAndLoadPatternSPs();
00164  SP_Constraint *theSP; 
00165  int index = 0;
00166  while ((theSP = theSPs()) != 0) {
00167      (*constrainedNodesSP)(index) = theSP->getNodeTag();
00168      sps[index] = theSP;
00169      index++;
00170  } 
00171     }
00172     
00173     //create a DOF_Group for each Node and add it to the AnalysisModel.
00174     //    :must of course set the initial IDs
00175     NodeIter &theNod = theDomain->getNodes();
00176     Node *nodPtr;
00177 
00178     int numDofGrp = 0;
00179     int count3 = 0;
00180     int countDOF =0;
00181     
00182     numConstrainedNodes = 0;
00183     int numUnconstrainedNodes = 0;
00184     
00185     while ((nodPtr = theNod()) != 0) {
00186 
00187         DOF_Group *dofPtr = 0;
00188 
00189  int nodeTag = nodPtr->getTag();
00190  int numNodalDOF = nodPtr->getNumberDOF();
00191  int loc = -1;
00192  int createdDOF = 0;
00193 
00194  if (numMPConstraints != 0) { 
00195      loc = constrainedNodesMP->getLocation(nodeTag);
00196      if (loc >= 0) {
00197 
00198   TransformationDOF_Group *tDofPtr = 
00199       new TransformationDOF_Group(numDofGrp++, nodPtr, mps[loc]); 
00200          
00201   createdDOF = 1;
00202   dofPtr = tDofPtr;
00203   
00204   // add any SPs
00205   if (numSPConstraints != 0) {
00206       loc = constrainedNodesSP->getLocation(nodeTag);
00207       if (loc >= 0) {
00208    tDofPtr->addSP_Constraint(*(sps[loc]));
00209    for (int i = loc+1; i<numSPConstraints; i++) {
00210        if ((*constrainedNodesSP)(i) == nodeTag)
00211     tDofPtr->addSP_Constraint(*(sps[i]));
00212    }
00213       }
00214       // add the DOF to the array     
00215       theDOFs[numDOF-numConstrainedNodes-1] = dofPtr;          
00216       numConstrainedNodes++;
00217   }
00218      }
00219  }
00220  
00221  if (createdDOF == 0 && numSPConstraints != 0) {
00222      loc = constrainedNodesSP->getLocation(nodeTag);
00223      if (loc >= 0) {
00224   TransformationDOF_Group *tDofPtr = 
00225       new TransformationDOF_Group(numDofGrp++, nodPtr);
00226   
00227   int numSPs = 1;
00228   createdDOF = 1;
00229   dofPtr = tDofPtr;
00230   tDofPtr->addSP_Constraint(*(sps[loc]));
00231 
00232   // check for more SP_constraints acting on node and add them
00233   for (int i = loc+1; i<numSPConstraints; i++) {
00234       if ((*constrainedNodesSP)(i) == nodeTag) {
00235    tDofPtr->addSP_Constraint(*(sps[i]));
00236    numSPs++;
00237       }
00238   }
00239   // add the DOF to the array
00240   theDOFs[numDOF-numConstrainedNodes-1] = dofPtr;          
00241   numConstrainedNodes++;     
00242   countDOF+= numNodalDOF - numSPs;  
00243      }
00244  }
00245 
00246  // create an ordinary DOF_Group object if no dof constrained
00247  if (createdDOF == 0) {
00248      if ((dofPtr = new DOF_Group(numDofGrp++, nodPtr)) == 0) {
00249   cerr << "WARNING TransformationConstraintHandler::handle() ";
00250   cerr << "- ran out of memory";
00251   cerr << " creating DOF_Group " << i << endl; 
00252   return -4;      
00253      }
00254  
00255      countDOF+= numNodalDOF;
00256      theDOFs[numUnconstrainedNodes++] = dofPtr;     
00257  }
00258  
00259  if (dofPtr == 0) 
00260    cerr << "TransformationConstraintHandler::handle() - error in logic\n";
00261      
00262  nodPtr->setDOF_GroupPtr(dofPtr);
00263  theModel->addDOF_Group(dofPtr);
00264     }
00265 
00266     // create the FE_Elements for the Elements and add to the AnalysisModel
00267     ElementIter &theEle = theDomain->getElements();
00268     Element *elePtr;
00269 
00270     int numFeEle = 0;
00271     FE_Element *fePtr;
00272     while ((elePtr = theEle()) != 0) {
00273 
00274  // we must check to see if the element has a constrained node
00275  const ID &nodes = elePtr->getExternalNodes();
00276  int nodesSize = nodes.Size();
00277  int isConstrainedNode = 0;
00278  for (int i=0; i<nodesSize; i++) {
00279      int nodeTag = nodes(i);
00280      if (numMPConstraints != 0) {
00281   int loc = constrainedNodesMP->getLocation(nodeTag);
00282   if (loc >= 0) {
00283       isConstrainedNode = 1;
00284       i = nodesSize;
00285   }
00286      } 
00287      if (numSPConstraints != 0 && isConstrainedNode == 0) {
00288   int loc = constrainedNodesSP->getLocation(nodeTag);
00289   if (loc >= 0) {
00290       isConstrainedNode = 1;      
00291       i = nodesSize;
00292   }
00293      }
00294  }     
00295      
00296  // if constrained Transformation otherwise normal FE_Element
00297  if (isConstrainedNode == 0) {
00298      if ((fePtr = new FE_Element(elePtr)) == 0) {
00299   cerr << "WARNING TransformationConstraintHandler::handle()";
00300   cerr << " - ran out of memory";
00301   cerr << " creating FE_Element " << elePtr->getTag() << endl; 
00302   return -5;
00303      }  
00304  } else {
00305      if ((fePtr = new TransformationFE(elePtr, *this)) == 0) {  
00306   cerr << "WARNING TransformationConstraintHandler::handle()";
00307   cerr << " - ran out of memory";
00308   cerr << " creating TransformationFE " << elePtr->getTag() << endl; 
00309   return -6;      
00310      }
00311  }
00312  
00313  theFEs[numFeEle++] = fePtr;
00314  theModel->addFE_Element(fePtr);
00315 
00316  if (elePtr->isSubdomain() == true) {
00317      Subdomain *theSub = (Subdomain *)elePtr;
00318      theSub->setFE_ElementPtr(fePtr);
00319  }
00320     }
00321 
00322     theModel->setNumEqn(countDOF);
00323     
00324     // set the number of eqn in the model
00325     // now see if we have to set any of the dof's to -3
00326     //    int numLast = 0;
00327     if (nodesLast != 0) 
00328  for (i=0; i<nodesLast->Size(); i++) {
00329      int nodeID = (*nodesLast)(i);
00330      Node *nodPtr = theDomain->getNode(nodeID);
00331      if (nodPtr != 0) {
00332   DOF_Group *dofPtr = nodPtr->getDOF_GroupPtr();
00333   
00334   const ID &id = dofPtr->getID();
00335   // set all the dof values to -3
00336   for (int j=0; j < id.Size(); j++) {
00337       if (id(j) == -2) {
00338    dofPtr->setID(j,-3);
00339    count3++;
00340       } else {
00341    cerr << "WARNING TransformationConstraintHandler::handle() ";
00342    cerr << " - boundary sp constraint in subdomain";
00343    cerr << " this should not be - results suspect \n";
00344       }
00345   }
00346      }
00347  }
00348 
00349     return count3;
00350 }
00351 
00352 
00353 
00354 void 
00355 TransformationConstraintHandler::clearAll(void)
00356 {
00357     // delete the FE_Element and DOF_Group objects
00358     for (int i=0; i<numFE; i++)
00359  if (theFEs[i] != 0)
00360      delete theFEs[i];
00361 
00362     for (int j=0; j<numDOF; j++)
00363  if (theDOFs[j] != 0)
00364      delete theDOFs[j];
00365     
00366     // delete the arrays
00367     if (theFEs != 0) delete [] theFEs;
00368     if (theDOFs != 0) delete [] theDOFs;
00369     
00370     // reset the numbers
00371     numDOF = 0;
00372     numFE =  0;
00373     theFEs = 0;
00374     theDOFs = 0;
00375 
00376     // for the nodes reset the DOF_Group pointers to 0
00377     Domain *theDomain = this->getDomainPtr();
00378     if (theDomain == 0)
00379  return;
00380 
00381     NodeIter &theNod = theDomain->getNodes();
00382     Node *nodPtr;
00383     while ((nodPtr = theNod()) != 0)
00384  nodPtr->setDOF_GroupPtr(0);
00385 }    
00386 
00387 int
00388 TransformationConstraintHandler::sendSelf(int cTag, Channel &theChannel)
00389 {
00390   return 0;
00391 }
00392 
00393 int
00394 TransformationConstraintHandler::recvSelf(int cTag, 
00395        Channel &theChannel, 
00396        FEM_ObjectBroker &theBroker)  
00397 {
00398   return 0;
00399 }
00400 
00401 
00402 
00403 int 
00404 TransformationConstraintHandler::enforceSPs(void)
00405 {
00406     for (int i=1; i<=numConstrainedNodes; i++) {
00407  // upward cast - safe as i put it in this location
00408  TransformationDOF_Group *theDof  =
00409      (TransformationDOF_Group *)theDOFs[numDOF-i];
00410  theDof->enforceSPs();
00411     }
00412     return 0;
00413 }
00414 
00415 int 
00416 TransformationConstraintHandler::doneDOFids(void)
00417 {
00418     for (int i=1; i<=numConstrainedNodes; i++) {
00419  // upward cast - safe as i put it in this location
00420  TransformationDOF_Group *theDof  =
00421      (TransformationDOF_Group *)theDOFs[numDOF-i];
00422  theDof->doneID();
00423     }
00424     return 0;
00425 }
Copyright Contact Us