PenaltyMP_FE.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.7 $
00022 // $Date: 2006/02/08 20:20:00 $
00023 // $Source: /usr/local/cvs/OpenSees/SRC/analysis/fe_ele/penalty/PenaltyMP_FE.cpp,v $
00024                                                                         
00025                                                                         
00026 // Written: fmk 
00027 // Created: 11/96
00028 // Revision: A
00029 //
00030 // Purpose: This file contains the code for implementing the methods
00031 // of the PenaltyMP_FE class interface.
00032 //
00033 // the interface:
00034 
00035 #include <PenaltyMP_FE.h>
00036 #include <stdlib.h>
00037 
00038 #include <Element.h>
00039 #include <Domain.h>
00040 #include <Node.h>
00041 #include <DOF_Group.h>
00042 #include <Integrator.h>
00043 #include <Subdomain.h>
00044 #include <AnalysisModel.h>
00045 #include <Matrix.h>
00046 #include <Vector.h>
00047 #include <Node.h>
00048 #include <MP_Constraint.h>
00049 #include <DOF_Group.h>
00050 
00051 PenaltyMP_FE::PenaltyMP_FE(int tag, Domain &theDomain, 
00052                            MP_Constraint &TheMP, double Alpha)
00053 :FE_Element(tag, 2,(TheMP.getConstrainedDOFs()).Size()+
00054  (TheMP.getRetainedDOFs()).Size()),
00055  theMP(&TheMP), theConstrainedNode(0) , theRetainedNode(0),
00056  tang(0), resid(0), C(0), alpha(Alpha)
00057 {
00058     
00059     int size;
00060     const ID &id1 = theMP->getConstrainedDOFs();
00061     size = id1.Size();
00062     const ID &id2 = theMP->getRetainedDOFs();    
00063     size += id2.Size();
00064 
00065     tang = new Matrix(size,size);
00066     resid = new Vector(size);
00067     C = new Matrix(id1.Size(),size);
00068 
00069     if (tang == 0 || resid == 0 || C == 0 ||
00070         tang->noCols() != size || C->noCols() != size || 
00071         resid->Size() != size) {
00072         opserr << "FATAL PenaltyMP_FE::PenaltyMP_FE() - out of memory\n";
00073         exit(-1);
00074     }
00075             
00076     theRetainedNode = theDomain.getNode(theMP->getNodeRetained());    
00077     theConstrainedNode = theDomain.getNode(theMP->getNodeConstrained());
00078 
00079     if (theRetainedNode == 0 || theConstrainedNode == 0) {
00080         opserr << "FATAL PenaltyMP_FE::PenaltyMP_FE() - Constrained or Retained";
00081         opserr << " Node does not exist in Domain\n";
00082         opserr << theMP->getNodeRetained() << " " << theMP->getNodeConstrained() << endln;
00083         exit(-1);
00084     }   
00085 
00086 
00087     // set up the dof groups tags
00088     DOF_Group *dofGrpPtr = 0;
00089     dofGrpPtr = theRetainedNode->getDOF_GroupPtr();
00090     if (dofGrpPtr != 0) 
00091         myDOF_Groups(0) = dofGrpPtr->getTag();      
00092     else 
00093         opserr << "WARNING PenaltyMP_FE::PenaltyMP_FE() - node no Group yet?\n"; 
00094     dofGrpPtr = theConstrainedNode->getDOF_GroupPtr();
00095     if (dofGrpPtr != 0) 
00096         myDOF_Groups(1) = dofGrpPtr->getTag();          
00097     else
00098         opserr << "WARNING PenaltyMP_FE::PenaltyMP_FE() - node no Group yet?\n"; 
00099     
00100     
00101     if (theMP->isTimeVarying() == false) {
00102         this->determineTangent();
00103         // we can free up the space taken by C as it is no longer needed
00104         if (C != 0)
00105             delete C;
00106         C = 0;
00107     }
00108 }
00109 
00110 PenaltyMP_FE::~PenaltyMP_FE()
00111 {
00112     if (tang != 0)
00113         delete tang;
00114     if (resid != 0)
00115         delete resid;
00116     if (C != 0)
00117         delete C;
00118 }    
00119 
00120 // void setID(int index, int value);
00121 //      Method to set the correMPonding index of the ID to value.
00122 int
00123 PenaltyMP_FE::setID(void)
00124 {
00125     int result = 0;
00126 
00127     // first determine the IDs in myID for those DOFs marked
00128     // as constrained DOFs, this is obtained from the DOF_Group
00129     // associated with the constrained node
00130     DOF_Group *theConstrainedNodesDOFs = theConstrainedNode->getDOF_GroupPtr();
00131     if (theConstrainedNodesDOFs == 0) {
00132         opserr << "WARNING PenaltyMP_FE::setID(void)";
00133         opserr << " - no DOF_Group with Constrained Node\n";
00134         return -2;
00135     }    
00136 
00137     const ID &constrainedDOFs = theMP->getConstrainedDOFs();
00138     const ID &theConstrainedNodesID = theConstrainedNodesDOFs->getID();    
00139     
00140     int size1 = constrainedDOFs.Size();
00141     for (int i=0; i<size1; i++) {
00142         int constrained = constrainedDOFs(i);
00143         if (constrained < 0 || 
00144             constrained >= theConstrainedNode->getNumberDOF()) {
00145             
00146             opserr << "WARNING PenaltyMP_FE::setID(void) - unknown DOF ";
00147             opserr << constrained << " at Node\n";
00148             myID(i) = -1; // modify so nothing will be added to equations
00149             result = -3;
00150         }       
00151         else {
00152             if (constrained >= theConstrainedNodesID.Size()) {
00153                 opserr << "WARNING PenaltyMP_FE::setID(void) - ";
00154                 opserr << " Nodes DOF_Group too small\n";
00155                 myID(i) = -1; // modify so nothing will be added to equations
00156                 result = -4;
00157             }
00158             else
00159                 myID(i) = theConstrainedNodesID(constrained);
00160         }
00161     }
00162     
00163     // now determine the IDs for the retained dof's
00164     DOF_Group *theRetainedNodesDOFs = theRetainedNode->getDOF_GroupPtr();
00165     if (theRetainedNodesDOFs == 0) {
00166         opserr << "WARNING PenaltyMP_FE::setID(void)";
00167         opserr << " - no DOF_Group with Retained Node\n";
00168         return -2;
00169     }    
00170     
00171     const ID &RetainedDOFs = theMP->getRetainedDOFs();
00172     const ID &theRetainedNodesID = theRetainedNodesDOFs->getID();    
00173 
00174     int size2 = RetainedDOFs.Size();
00175     for (int j=0; j<size2; j++) {
00176         int retained = RetainedDOFs(j);
00177         if (retained < 0 || retained >= theRetainedNode->getNumberDOF()) {
00178             opserr << "WARNING PenaltyMP_FE::setID(void) - unknown DOF ";
00179             opserr << retained << " at Node\n";
00180             myID(j+size1) = -1; // modify so nothing will be added
00181             result = -3;
00182         }       
00183         else {
00184             if (retained >= theRetainedNodesID.Size()) {
00185                 opserr << "WARNING PenaltyMP_FE::setID(void) - ";
00186                 opserr << " Nodes DOF_Group too small\n";
00187                 myID(j+size1) = -1; // modify so nothing will be added 
00188                 result = -4;
00189             }
00190             else
00191                 myID(j+size1) = theRetainedNodesID(retained);
00192         }
00193     }
00194 
00195     myDOF_Groups(0) = theConstrainedNodesDOFs->getTag();
00196     myDOF_Groups(1) = theRetainedNodesDOFs->getTag();
00197 
00198     return result;
00199 }
00200 
00201 const Matrix &
00202 PenaltyMP_FE::getTangent(Integrator *theNewIntegrator)
00203 {
00204     if (theMP->isTimeVarying() == true)
00205         this->determineTangent();    
00206     return *tang;
00207 }
00208 
00209 const Vector &
00210 PenaltyMP_FE::getResidual(Integrator *theNewIntegrator)
00211 {
00212     // zero residual, CD = 0
00213     return *resid;
00214 }
00215 
00216 
00217 
00218 const Vector &
00219 PenaltyMP_FE::getTangForce(const Vector &disp, double fact)
00220 {
00221  opserr << "WARNING PenaltySP_FE::getTangForce() - not yet implemented\n";
00222  return *resid;
00223 }
00224 
00225 const Vector &
00226 PenaltyMP_FE::getK_Force(const Vector &disp, double fact)
00227 {
00228  opserr << "WARNING PenaltySP_FE::getK_Force() - not yet implemented\n";
00229  return *resid;
00230 }
00231 
00232 const Vector &
00233 PenaltyMP_FE::getKi_Force(const Vector &disp, double fact)
00234 {
00235  opserr << "WARNING PenaltySP_FE::getK_Force() - not yet implemented\n";
00236  return *resid;
00237 }
00238 
00239 const Vector &
00240 PenaltyMP_FE::getC_Force(const Vector &disp, double fact)
00241 {
00242  opserr << "WARNING PenaltySP_FE::getC_Force() - not yet implemented\n";
00243  return *resid;
00244 }
00245 
00246 const Vector &
00247 PenaltyMP_FE::getM_Force(const Vector &disp, double fact)
00248 {
00249  opserr << "WARNING PenaltySP_FE::getM_Force() - not yet implemented\n";
00250  return *resid;
00251 }
00252 
00253 void  
00254 PenaltyMP_FE::determineTangent(void)
00255 {
00256     // first determine [C] = [-I [Ccr]]
00257     C->Zero();
00258     const Matrix &constraint = theMP->getConstraint();
00259     int noRows = constraint.noRows();
00260     int noCols = constraint.noCols();
00261     
00262     for (int j=0; j<noRows; j++)
00263         (*C)(j,j) = -1.0;
00264     
00265     for (int i=0; i<noRows; i++)
00266         for (int j=0; j<noCols; j++)
00267             (*C)(i,j+noRows) = constraint(i,j);
00268     
00269 
00270     // now form the tangent: [K] = alpha * [C]^t[C]
00271     // *(tang) = (*C)^(*C);
00272     // *(tang) *= alpha;
00273 
00274         // THIS IS A WORKAROUND UNTIL WE GET addMatrixTransposeProduct() IN
00275         // THE Matrix CLASS OR UNROLL THIS COMPUTATION
00276         int rows = C->noRows();
00277         int cols = C->noCols();
00278         Matrix CT(cols,rows);
00279         const Matrix &Cref = *C;
00280         // Fill in the transpose of C
00281         for (int k = 0; k < cols; k++)
00282                 for (int l = 0; l < rows; l++)
00283                         CT(k,l) = Cref(l,k);
00284         // Compute alpha*(C^*C)
00285         tang->addMatrixProduct(0.0, CT, Cref, alpha);
00286 }
00287 
00288 

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