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 <LagrangeMP_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 LagrangeMP_FE::LagrangeMP_FE(Domain &theDomain, MP_Constraint &TheMP,
00052 DOF_Group &theGroup, double Alpha)
00053 :FE_Element(3,(TheMP.getConstrainedDOFs()).Size()+
00054 (TheMP.getRetainedDOFs()).Size() +
00055 (TheMP.getRetainedDOFs()).Size()),
00056 alpha(Alpha), theMP(&TheMP),
00057 theConstrainedNode(0), theRetainedNode(0),
00058 theDofGroup(&theGroup), tang(0), resid(0)
00059 {
00060 const Matrix &constraint = theMP->getConstraint();
00061 int noRows = constraint.noRows();
00062 int noCols = constraint.noCols();
00063 int size = 2*noRows+noCols;
00064
00065 tang = new Matrix(size,size);
00066 resid = new Vector(size);
00067 if (tang == 0 || resid == 0 || tang->noCols() == 0 || resid->Size() == 0) {
00068 cerr << "FATAL LagrangeMP_FE::LagrangeMP_FE() - out of memory\n";
00069 exit(-1);
00070 }
00071 tang->Zero();
00072 resid->Zero();
00073
00074 theRetainedNode = theDomain.getNode(theMP->getNodeRetained());
00075 theConstrainedNode = theDomain.getNode(theMP->getNodeConstrained());
00076
00077 if (theRetainedNode == 0) {
00078 cerr << "WARNING LagrangeMP_FE::LagrangeMP_FE()";
00079 cerr << "- no asscoiated Retained Node\n";
00080 exit(-1);
00081 }
00082
00083 if (theConstrainedNode == 0) {
00084 cerr << "WARNING LagrangeMP_FE::LagrangeMP_FE()";
00085 cerr << "- no asscoiated Constrained Node\n";
00086 exit(-1);
00087 }
00088
00089 if (theMP->isTimeVarying() == false) {
00090 this->determineTangent();
00091 }
00092
00093
00094
00095 DOF_Group *theConstrainedNodesDOFs = theConstrainedNode->getDOF_GroupPtr();
00096 if (theConstrainedNodesDOFs == 0) {
00097 cerr << "WARNING LagrangeMP_FE::LagrangeMP_FE()";
00098 cerr << " - no DOF_Group with Constrained Node\n";
00099 exit(-1);
00100 }
00101
00102 DOF_Group *theRetainedNodesDOFs = theRetainedNode->getDOF_GroupPtr();
00103 if (theRetainedNodesDOFs == 0) {
00104 cerr << "WARNING LagrangeMP_FE::LagrangeMP_FE()";
00105 cerr << " - no DOF_Group with Retained Node\n";
00106 exit(-1);
00107 }
00108
00109 myDOF_Groups(0) = theConstrainedNodesDOFs->getTag();
00110 myDOF_Groups(1) = theRetainedNodesDOFs->getTag();
00111 myDOF_Groups(2) = theDofGroup->getTag();
00112 }
00113
00114 LagrangeMP_FE::~LagrangeMP_FE()
00115 {
00116 if (tang != 0)
00117 delete tang;
00118 if (resid != 0)
00119 delete resid;
00120 }
00121
00122
00123
00124 int
00125 LagrangeMP_FE::setID(void)
00126 {
00127 int result = 0;
00128
00129
00130
00131
00132 if (theConstrainedNode == 0) {
00133 cerr << "WARNING LagrangeMP_FE::setID(void)";
00134 cerr << "- no asscoiated Constrained Node\n";
00135 return -1;
00136 }
00137 DOF_Group *theConstrainedNodesDOFs = theConstrainedNode->getDOF_GroupPtr();
00138 if (theConstrainedNodesDOFs == 0) {
00139 cerr << "WARNING LagrangeMP_FE::setID(void)";
00140 cerr << " - no DOF_Group with Constrained Node\n";
00141 return -2;
00142 }
00143
00144 const ID &constrainedDOFs = theMP->getConstrainedDOFs();
00145 const ID &theConstrainedNodesID = theConstrainedNodesDOFs->getID();
00146
00147 int size1 = constrainedDOFs.Size();
00148 for (int i=0; i<size1; i++) {
00149 int constrained = constrainedDOFs(i);
00150 if (constrained < 0 ||
00151 constrained >= theConstrainedNode->getNumberDOF()) {
00152
00153 cerr << "WARNING LagrangeMP_FE::setID(void) - unknown DOF ";
00154 cerr << constrained << " at Node\n";
00155 myID(i) = -1;
00156 result = -3;
00157 }
00158 else {
00159 if (constrained >= theConstrainedNodesID.Size()) {
00160 cerr << "WARNING LagrangeMP_FE::setID(void) - ";
00161 cerr << " Nodes DOF_Group too small\n";
00162 myID(i) = -1;
00163 result = -4;
00164 }
00165 else
00166 myID(i) = theConstrainedNodesID(constrained);
00167 }
00168 }
00169
00170
00171 if (theRetainedNode == 0) {
00172 cerr << "WARNING LagrangeMP_FE::setID(void)";
00173 cerr << "- no asscoiated Retained Node\n";
00174 return -1;
00175 }
00176 DOF_Group *theRetainedNodesDOFs = theRetainedNode->getDOF_GroupPtr();
00177 if (theRetainedNodesDOFs == 0) {
00178 cerr << "WARNING LagrangeMP_FE::setID(void)";
00179 cerr << " - no DOF_Group with Retained Node\n";
00180 return -2;
00181 }
00182
00183 const ID &RetainedDOFs = theMP->getRetainedDOFs();
00184 const ID &theRetainedNodesID = theRetainedNodesDOFs->getID();
00185
00186 int size2 = RetainedDOFs.Size();
00187 for (int j=0; j<size2; j++) {
00188 int retained = RetainedDOFs(j);
00189 if (retained < 0 || retained >= theRetainedNode->getNumberDOF()) {
00190 cerr << "WARNING LagrangeMP_FE::setID(void) - unknown DOF ";
00191 cerr << retained << " at Node\n";
00192 myID(j+size1) = -1;
00193 result = -3;
00194 }
00195 else {
00196 if (retained >= theRetainedNodesID.Size()) {
00197 cerr << "WARNING LagrangeMP_FE::setID(void) - ";
00198 cerr << " Nodes DOF_Group too small\n";
00199 myID(j+size1) = -1;
00200 result = -4;
00201 }
00202 else
00203 myID(j+size1) = theRetainedNodesID(retained);
00204 }
00205 }
00206
00207
00208 const ID &theGroupsID = theDofGroup->getID();
00209 int size3 = theGroupsID.Size();
00210 for (int k=0; k<size3; k++)
00211 myID(k+size1+size2) = theGroupsID(k);
00212
00213
00214 return result;
00215 }
00216
00217 const Matrix &
00218 LagrangeMP_FE::getTangent(Integrator *theNewIntegrator)
00219 {
00220 if (theMP->isTimeVarying() == true)
00221 this->determineTangent();
00222
00223 return *tang;
00224 }
00225
00226 const Vector &
00227 LagrangeMP_FE::getResidual(Integrator *theNewIntegrator)
00228 {
00229 return *resid;
00230 }
00231
00232
00233
00234 const Vector &
00235 LagrangeMP_FE::getTangForce(const Vector &disp, double fact)
00236 {
00237
00238 return *resid;
00239 }
00240
00241 void
00242 LagrangeMP_FE::determineTangent(void)
00243 {
00244 const Matrix &constraint = theMP->getConstraint();
00245 int noRows = constraint.noRows();
00246 int noCols = constraint.noCols();
00247 int n = noRows+noCols;
00248
00249 tang->Zero();
00250
00251 for (int j=0; j<noRows; j++) {
00252 (*tang)(n+j, j) = -alpha;
00253 (*tang)(j, n+j) = -alpha;
00254 }
00255
00256 for (int i=0; i<noRows; i++)
00257 for (int j=0; j<noCols; j++) {
00258 double val = constraint(i,j) * alpha;
00259 (*tang)(n+i, j+noRows) = val;
00260 (*tang)(noRows+j, n+i) = val;
00261 }
00262 }
00263
00264
00265
00266
00267