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
00036
00037
00038
00039
00040
00041
00042 #include <DisplacementControl.h>
00043 #include <AnalysisModel.h>
00044 #include <LinearSOE.h>
00045 #include <Vector.h>
00046 #include <Channel.h>
00047 #include <iostream.h>
00048 #include <math.h>
00049 #include <Domain.h>
00050 #include <Node.h>
00051 #include <DOF_Group.h>
00052 #include <ID.h>
00053
00054 DisplacementControl::DisplacementControl(int node, int dof,
00055 double increment,
00056 Domain *domain,
00057 int numIncr,
00058 double min, double max)
00059 :StaticIntegrator(INTEGRATOR_TAGS_DisplacementControl),
00060 theNode(node), theDof(dof), theIncrement(increment), theDomain(domain),
00061 theDofID(0),
00062 deltaUhat(0), deltaUbar(0), deltaU(0), deltaUstep(0),
00063 phat(0), deltaLambdaStep(0.0), currentLambda(0.0),
00064 specNumIncrStep(numIncr), numIncrLastStep(numIncr),
00065 minIncrement(min), maxIncrement(max)
00066 {
00067
00068 if (numIncr == 0) {
00069 cerr << "WARNING DisplacementControl::DisplacementControl() -";
00070 cerr << " numIncr set to 0, 1 assumed\n";
00071 specNumIncrStep = 1.0;
00072 numIncrLastStep = 1.0;
00073 }
00074 }
00075
00076 DisplacementControl::~DisplacementControl()
00077 {
00078
00079 if (deltaUhat != 0)
00080 delete deltaUhat;
00081 if (deltaU != 0)
00082 delete deltaU;
00083 if (deltaUstep != 0)
00084 delete deltaUstep;
00085 if (phat != 0)
00086 delete phat;
00087 }
00088
00089 int
00090 DisplacementControl::newStep(void)
00091 {
00092
00093
00094
00095 AnalysisModel *theModel = this->getAnalysisModelPtr();
00096 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00097 if (theModel == 0 || theLinSOE == 0) {
00098 cerr << "WARNING DisplacementControl::newStep() ";
00099 cerr << "No AnalysisModel or LinearSOE has been set\n";
00100 return -1;
00101 }
00102
00103
00104
00105 double factor = specNumIncrStep/numIncrLastStep;
00106 theIncrement *=factor;
00107
00108 if (theIncrement < minIncrement)
00109 theIncrement = minIncrement;
00110 else if (theIncrement > maxIncrement)
00111 theIncrement = maxIncrement;
00112
00113
00114
00115 currentLambda = theModel->getCurrentDomainTime();
00116
00117
00118 this->formTangent();
00119 theLinSOE->setB(*phat);
00120
00121 theLinSOE->solve();
00122 (*deltaUhat) = theLinSOE->getX();
00123 Vector &dUhat = *deltaUhat;
00124
00125 double dUahat = dUhat(theDofID);
00126
00127
00128 double dLambda = theIncrement/dUahat;
00129
00130 deltaLambdaStep = dLambda;
00131 currentLambda += dLambda;
00132
00133
00134
00135 (*deltaU) = dUhat;
00136 (*deltaU) *= dLambda;
00137 (*deltaUstep) = (*deltaU);
00138
00139
00140 theModel->incrDisp(*deltaU);
00141 theModel->applyLoadDomain(currentLambda);
00142 theModel->updateDomain();
00143
00144 numIncrLastStep = 0;
00145
00146 return 0;
00147 }
00148
00149 int
00150 DisplacementControl::update(const Vector &dU)
00151 {
00152 AnalysisModel *theModel = this->getAnalysisModelPtr();
00153 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00154 if (theModel == 0 || theLinSOE == 0) {
00155 cerr << "WARNING DisplacementControl::update() ";
00156 cerr << "No AnalysisModel or LinearSOE has been set\n";
00157 return -1;
00158 }
00159
00160 (*deltaUbar) = dU;
00161 double dUabar = (*deltaUbar)(theDofID);
00162
00163
00164 theLinSOE->setB(*phat);
00165 theLinSOE->solve();
00166 (*deltaUhat) = theLinSOE->getX();
00167
00168 double dUahat = (*deltaUhat)(theDofID);
00169
00170
00171 double dLambda = -dUabar/dUahat;
00172
00173
00174 (*deltaU) = (*deltaUbar);
00175 deltaU->addVector(1.0, *deltaUhat,dLambda);
00176
00177
00178 (*deltaUstep) += *deltaU;
00179 deltaLambdaStep += dLambda;
00180 currentLambda += dLambda;
00181
00182
00183 theModel->incrDisp(*deltaU);
00184 theModel->applyLoadDomain(currentLambda);
00185 theModel->updateDomain();
00186
00187
00188 for (int i=0; i<deltaU->Size(); i++)
00189 theLinSOE->setX(i, (*deltaU)(i));
00190
00191 numIncrLastStep++;
00192
00193 return 0;
00194 }
00195
00196
00197
00198 int
00199 DisplacementControl::domainChanged(void)
00200 {
00201
00202 AnalysisModel *theModel = this->getAnalysisModelPtr();
00203 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00204 if (theModel == 0 || theLinSOE == 0) {
00205 cerr << "WARNING DisplacementControl::update() ";
00206 cerr << "No AnalysisModel or LinearSOE has been set\n";
00207 return -1;
00208 }
00209 int size = theModel->getNumEqn();
00210
00211 if (deltaUhat == 0 || deltaUhat->Size() != size) {
00212 if (deltaUhat != 0)
00213 delete deltaUhat;
00214 deltaUhat = new Vector(size);
00215 if (deltaUhat == 0 || deltaUhat->Size() != size) {
00216 cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00217 cerr << " deltaUhat Vector of size " << size << endl;
00218 exit(-1);
00219 }
00220 }
00221
00222 if (deltaUbar == 0 || deltaUbar->Size() != size) {
00223 if (deltaUbar != 0)
00224 delete deltaUbar;
00225 deltaUbar = new Vector(size);
00226 if (deltaUbar == 0 || deltaUbar->Size() != size) {
00227 cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00228 cerr << " deltaUbar Vector of size " << size << endl;
00229 exit(-1);
00230 }
00231 }
00232
00233 if (deltaU == 0 || deltaU->Size() != size) {
00234 if (deltaU != 0)
00235 delete deltaU;
00236 deltaU = new Vector(size);
00237 if (deltaU == 0 || deltaU->Size() != size) {
00238 cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00239 cerr << " deltaU Vector of size " << size << endl;
00240 exit(-1);
00241 }
00242 }
00243
00244 if (deltaUstep == 0 || deltaUstep->Size() != size) {
00245 if (deltaUstep != 0)
00246 delete deltaUstep;
00247 deltaUstep = new Vector(size);
00248 if (deltaUstep == 0 || deltaUstep->Size() != size) {
00249 cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00250 cerr << " deltaUstep Vector of size " << size << endl;
00251 exit(-1);
00252 }
00253 }
00254
00255 if (phat == 0 || phat->Size() != size) {
00256 if (phat != 0)
00257 delete phat;
00258 phat = new Vector(size);
00259 if (phat == 0 || phat->Size() != size) {
00260 cerr << "FATAL DisplacementControl::domainChanged() - ran out of memory for";
00261 cerr << " phat Vector of size " << size << endl;
00262 exit(-1);
00263 }
00264 }
00265
00266
00267
00268
00269 currentLambda = theModel->getCurrentDomainTime();
00270 currentLambda += 1.0;
00271 theModel->applyLoadDomain(currentLambda);
00272 this->formUnbalance();
00273 (*phat) = theLinSOE->getB();
00274 currentLambda -= 1.0;
00275 theModel->setCurrentDomainTime(currentLambda);
00276
00277
00278
00279 int haveLoad = 0;
00280 for (int i=0; i<size; i++)
00281 if ( (*phat)(i) != 0.0 ) {
00282 haveLoad = 1;
00283 i = size;
00284 }
00285
00286 if (haveLoad == 0) {
00287 cerr << "WARNING DisplacementControl::domainChanged() - zero reference load";
00288 return -1;
00289 }
00290
00291
00292
00293
00294 Node *theNodePtr = theDomain->getNode(theNode);
00295 DOF_Group *theGroup = theNodePtr->getDOF_GroupPtr();
00296 const ID &theID = theGroup->getID();
00297 theDofID = theID(theDof);
00298
00299 return 0;
00300 }
00301
00302 int
00303 DisplacementControl::sendSelf(int cTag,
00304 Channel &theChannel)
00305 {
00306
00307 return 0;
00308 }
00309
00310
00311 int
00312 DisplacementControl::recvSelf(int cTag,
00313 Channel &theChannel, FEM_ObjectBroker &theBroker)
00314 {
00315
00316 return 0;
00317 }
00318
00319 void
00320 DisplacementControl::Print(ostream &s, int flag)
00321 {
00322
00323 }