00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
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
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
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
00121
00122 int
00123 PenaltyMP_FE::setID(void)
00124 {
00125 int result = 0;
00126
00127
00128
00129
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;
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;
00156 result = -4;
00157 }
00158 else
00159 myID(i) = theConstrainedNodesID(constrained);
00160 }
00161 }
00162
00163
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;
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;
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
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
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
00271
00272
00273
00274
00275
00276 int rows = C->noRows();
00277 int cols = C->noCols();
00278 Matrix CT(cols,rows);
00279 const Matrix &Cref = *C;
00280
00281 for (int k = 0; k < cols; k++)
00282 for (int l = 0; l < rows; l++)
00283 CT(k,l) = Cref(l,k);
00284
00285 tang->addMatrixProduct(0.0, CT, Cref, alpha);
00286 }
00287
00288