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 <MinUnbalDispNorm.h>
00036 #include <AnalysisModel.h>
00037 #include <LinearSOE.h>
00038 #include <Vector.h>
00039 #include <Channel.h>
00040 #include <iostream.h>
00041 #include <math.h>
00042
00043 MinUnbalDispNorm::MinUnbalDispNorm(double lambda1, int specNumIter,
00044 double min, double max, int signFirstStep)
00045 :StaticIntegrator(INTEGRATOR_TAGS_MinUnbalDispNorm),
00046 dLambda1LastStep(lambda1),
00047 specNumIncrStep(specNumIter), numIncrLastStep(specNumIter),
00048 deltaUhat(0), deltaUbar(0), deltaU(0), deltaUstep(0),
00049 phat(0), deltaLambdaStep(0.0), currentLambda(0.0),
00050 signLastDeltaLambdaStep(1),
00051 dLambda1min(min), dLambda1max(max), signLastDeterminant(1), signFirstStepMethod(signFirstStep)
00052 {
00053
00054 if (specNumIncrStep == 0) {
00055 cerr << "WARNING LoadControl::LoadControl() - numIncr set to 0, 1 assumed\n";
00056 specNumIncrStep = 1.0;
00057 numIncrLastStep = 1.0;
00058 }
00059 }
00060
00061 MinUnbalDispNorm::~MinUnbalDispNorm()
00062 {
00063
00064 if (deltaUhat != 0)
00065 delete deltaUhat;
00066 if (deltaU != 0)
00067 delete deltaU;
00068 if (deltaUstep != 0)
00069 delete deltaUstep;
00070 if (phat != 0)
00071 delete phat;
00072 }
00073
00074 int
00075 MinUnbalDispNorm::newStep(void)
00076 {
00077
00078 AnalysisModel *theModel = this->getAnalysisModelPtr();
00079 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00080 if (theModel == 0 || theLinSOE == 0) {
00081 cerr << "WARNING MinUnbalDispNorm::newStep() ";
00082 cerr << "No AnalysisModel or LinearSOE has been set\n";
00083 return -1;
00084 }
00085
00086
00087 currentLambda = theModel->getCurrentDomainTime();
00088
00089
00090
00091 this->formTangent();
00092 theLinSOE->setB(*phat);
00093 theLinSOE->solve();
00094 (*deltaUhat) = theLinSOE->getX();
00095 Vector &dUhat = *deltaUhat;
00096
00097
00098 double factor = specNumIncrStep/numIncrLastStep;
00099 double dLambda = dLambda1LastStep*factor;
00100
00101
00102 if (dLambda < dLambda1min)
00103 dLambda = dLambda1min;
00104 else if (dLambda > dLambda1max)
00105 dLambda = dLambda1max;
00106
00107 dLambda1LastStep = dLambda;
00108
00109
00110 if (signFirstStepMethod == SIGN_LAST_STEP) {
00111 if (deltaLambdaStep < 0)
00112 signLastDeltaLambdaStep = -1;
00113 else
00114 signLastDeltaLambdaStep = +1;
00115
00116 dLambda *= signLastDeltaLambdaStep;
00117
00118 } else {
00119
00120 double det = theLinSOE->getDeterminant();
00121 int signDeterminant = 1;
00122 if (det < 0)
00123 signDeterminant = -1;
00124
00125 dLambda *= signDeterminant * signLastDeterminant;
00126
00127 signLastDeterminant = signDeterminant;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 deltaLambdaStep = dLambda;
00139 currentLambda += dLambda;
00140 numIncrLastStep = 0;
00141
00142
00143 (*deltaU) = dUhat;
00144 (*deltaU) *= dLambda;
00145 (*deltaUstep) = (*deltaU);
00146
00147
00148 theModel->incrDisp(*deltaU);
00149 theModel->applyLoadDomain(currentLambda);
00150 theModel->updateDomain();
00151
00152 return 0;
00153 }
00154
00155 int
00156 MinUnbalDispNorm::update(const Vector &dU)
00157 {
00158 AnalysisModel *theModel = this->getAnalysisModelPtr();
00159 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00160 if (theModel == 0 || theLinSOE == 0) {
00161 cerr << "WARNING MinUnbalDispNorm::update() ";
00162 cerr << "No AnalysisModel or LinearSOE has been set\n";
00163 return -1;
00164 }
00165
00166 (*deltaUbar) = dU;
00167
00168
00169 theLinSOE->setB(*phat);
00170 theLinSOE->solve();
00171 (*deltaUhat) = theLinSOE->getX();
00172
00173
00174 double a = (*deltaUhat)^(*deltaUbar);
00175 double b = (*deltaUhat)^(*deltaUhat);
00176 if (b == 0) {
00177 cerr << "MinUnbalDispNorm::update() - zero denominator\n";
00178 return -1;
00179 }
00180
00181 double dLambda = -a/b;
00182
00183
00184 (*deltaU) = (*deltaUbar);
00185 deltaU->addVector(1.0, *deltaUhat,dLambda);
00186
00187
00188 (*deltaUstep) += *deltaU;
00189 deltaLambdaStep += dLambda;
00190 currentLambda += dLambda;
00191
00192
00193 theModel->incrDisp(*deltaU);
00194 theModel->applyLoadDomain(currentLambda);
00195 theModel->updateDomain();
00196
00197
00198 for (int i=0; i<deltaU->Size(); i++)
00199 theLinSOE->setX(i, (*deltaU)(i));
00200
00201 numIncrLastStep++;
00202 return 0;
00203 }
00204
00205
00206
00207 int
00208 MinUnbalDispNorm::domainChanged(void)
00209 {
00210
00211 AnalysisModel *theModel = this->getAnalysisModelPtr();
00212 LinearSOE *theLinSOE = this->getLinearSOEPtr();
00213 if (theModel == 0 || theLinSOE == 0) {
00214 cerr << "WARNING MinUnbalDispNorm::update() ";
00215 cerr << "No AnalysisModel or LinearSOE has been set\n";
00216 return -1;
00217 }
00218 int size = theModel->getNumEqn();
00219
00220 if (deltaUhat == 0 || deltaUhat->Size() != size) {
00221 if (deltaUhat != 0)
00222 delete deltaUhat;
00223 deltaUhat = new Vector(size);
00224 if (deltaUhat == 0 || deltaUhat->Size() != size) {
00225 cerr << "FATAL MinUnbalDispNorm::domainChanged() - ran out of memory for";
00226 cerr << " deltaUhat Vector of size " << size << endl;
00227 exit(-1);
00228 }
00229 }
00230
00231 if (deltaUbar == 0 || deltaUbar->Size() != size) {
00232 if (deltaUbar != 0)
00233 delete deltaUbar;
00234 deltaUbar = new Vector(size);
00235 if (deltaUbar == 0 || deltaUbar->Size() != size) {
00236 cerr << "FATAL MinUnbalDispNorm::domainChanged() - ran out of memory for";
00237 cerr << " deltaUbar Vector of size " << size << endl;
00238 exit(-1);
00239 }
00240 }
00241
00242
00243 if (deltaU == 0 || deltaU->Size() != size) {
00244 if (deltaU != 0)
00245 delete deltaU;
00246 deltaU = new Vector(size);
00247 if (deltaU == 0 || deltaU->Size() != size) {
00248 cerr << "FATAL MinUnbalDispNorm::domainChanged() - ran out of memory for";
00249 cerr << " deltaU Vector of size " << size << endl;
00250 exit(-1);
00251 }
00252 }
00253
00254 if (deltaUstep == 0 || deltaUstep->Size() != size) {
00255 if (deltaUstep != 0)
00256 delete deltaUstep;
00257 deltaUstep = new Vector(size);
00258 if (deltaUstep == 0 || deltaUstep->Size() != size) {
00259 cerr << "FATAL MinUnbalDispNorm::domainChanged() - ran out of memory for";
00260 cerr << " deltaUstep Vector of size " << size << endl;
00261 exit(-1);
00262 }
00263 }
00264
00265 if (phat == 0 || phat->Size() != size) {
00266 if (phat != 0)
00267 delete phat;
00268 phat = new Vector(size);
00269 if (phat == 0 || phat->Size() != size) {
00270 cerr << "FATAL MinUnbalDispNorm::domainChanged() - ran out of memory for";
00271 cerr << " phat Vector of size " << size << endl;
00272 exit(-1);
00273 }
00274 }
00275
00276
00277
00278
00279 currentLambda = theModel->getCurrentDomainTime();
00280 currentLambda += 1.0;
00281 theModel->applyLoadDomain(currentLambda);
00282 this->formUnbalance();
00283 (*phat) = theLinSOE->getB();
00284 currentLambda -= 1.0;
00285 theModel->setCurrentDomainTime(currentLambda);
00286
00287
00288
00289 int haveLoad = 0;
00290 for (int i=0; i<size; i++)
00291 if ( (*phat)(i) != 0.0 ) {
00292 haveLoad = 1;
00293 i = size;
00294 }
00295
00296 if (haveLoad == 0) {
00297 cerr << "WARNING ArcLength::domainChanged() - zero reference load";
00298 return -1;
00299 }
00300
00301
00302 return 0;
00303 }
00304
00305 int
00306 MinUnbalDispNorm::sendSelf(int cTag,
00307 Channel &theChannel)
00308 {
00309 Vector data(8);
00310 data(0) = dLambda1LastStep;
00311 data(1) = specNumIncrStep;
00312 data(2) = numIncrLastStep;
00313 data(3) = deltaLambdaStep;
00314 data(4) = currentLambda;
00315 if (signLastDeltaLambdaStep == 1)
00316 data(5) = 1.0;
00317 else
00318 data(5) = 0.0;
00319 data(6) = dLambda1min;
00320 data(7) = dLambda1max;
00321
00322 if (theChannel.sendVector(this->getDbTag(), cTag, data) < 0) {
00323 cerr << "MinUnbalDispNorm::sendSelf() - failed to send the data\n";
00324 return -1;
00325 }
00326 return 0;
00327 }
00328
00329
00330 int
00331 MinUnbalDispNorm::recvSelf(int cTag,
00332 Channel &theChannel, FEM_ObjectBroker &theBroker)
00333 {
00334 Vector data(8);
00335 if (theChannel.recvVector(this->getDbTag(), cTag, data) < 0) {
00336 cerr << "MinUnbalDispNorm::sendSelf() - failed to send the data\n";
00337 return -1;
00338 }
00339
00340
00341
00342 dLambda1LastStep = data(0);
00343 specNumIncrStep = data(1);
00344 numIncrLastStep = data(2);
00345 deltaLambdaStep = data(3);
00346 currentLambda = data(4);
00347 if (data(5)== 1.0)
00348 signLastDeltaLambdaStep = 1;
00349 else
00350 signLastDeltaLambdaStep = -1;
00351 dLambda1min = data(6);
00352 dLambda1max = data(7);
00353
00354 return 0;
00355 }
00356
00357 void
00358 MinUnbalDispNorm::Print(ostream &s, int flag)
00359 {
00360 AnalysisModel *theModel = this->getAnalysisModelPtr();
00361 if (theModel != 0) {
00362 double cLambda = theModel->getCurrentDomainTime();
00363 s << "\t MinUnbalDispNorm - currentLambda: " << cLambda;
00364 } else
00365 s << "\t MinUnbalDispNorm - no associated AnalysisModel\n";
00366 }