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 #include <stdlib.h>
00034
00035 #include <Channel.h>
00036 #include <Vector.h>
00037 #include <Matrix.h>
00038 #include <MatrixUtil.h>
00039 #include <Fiber.h>
00040 #include <classTags.h>
00041 #include <FiberSection.h>
00042 #include <ID.h>
00043 #include <FEM_ObjectBroker.h>
00044 #include <Information.h>
00045 #include <MaterialResponse.h>
00046
00047
00048 FiberSection::FiberSection(int tag, int num, Fiber **fibers):
00049 SectionForceDeformation(tag, SEC_TAG_Fiber),
00050 numFibers(num), theFibers(0), sizeFibers(num),
00051 e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
00052 {
00053 theFibers = new Fiber *[numFibers];
00054
00055 if (theFibers == 0)
00056 g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
00057 "FiberSection::FiberSection");
00058
00059 for (int i = 0; i < numFibers; i++) {
00060 theFibers[i] = fibers[i]->getCopy();
00061
00062 if (theFibers[i] == 0)
00063 g3ErrorHandler->fatal("%s -- failed to get copy of Fiber",
00064 "FiberSection::FiberSection");
00065 }
00066
00067 order = theFibers[0]->getOrder();
00068
00069 e = new Vector(order);
00070 eCommit = new Vector(order);
00071 s = new Vector(order);
00072 ks = new Matrix(order,order);
00073
00074 code = new ID(order);
00075 *code = theFibers[0]->getType();
00076 }
00077
00078
00079 FiberSection::FiberSection():
00080 SectionForceDeformation(0, SEC_TAG_Fiber),
00081 numFibers(0), theFibers(0), sizeFibers(0),
00082 e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
00083 {
00084
00085 }
00086
00087 FiberSection::FiberSection(int tag, int num):
00088 SectionForceDeformation(tag, SEC_TAG_Fiber),
00089 numFibers(0), theFibers(0), sizeFibers(num),
00090 e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
00091 {
00092
00093 if (sizeFibers == 0)
00094 sizeFibers = 2;
00095
00096
00097 theFibers = new Fiber *[sizeFibers];
00098
00099 if (theFibers == 0) {
00100 g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
00101 "FiberSection::FiberSection");
00102
00103 sizeFibers = 0;
00104 }
00105
00106
00107 for (int i = 0; i < sizeFibers; i++)
00108 theFibers[i] =0;
00109 }
00110
00111 int
00112 FiberSection::addFiber(Fiber &newFiber)
00113 {
00114 if (order == 0) {
00115 order = newFiber.getOrder();
00116
00117 e = new Vector(order);
00118 eCommit = new Vector(order);
00119 s = new Vector(order);
00120 ks = new Matrix(order,order);
00121
00122 code = new ID(order);
00123 *code = newFiber.getType();
00124 }
00125
00126 if (numFibers < sizeFibers) {
00127
00128 theFibers[numFibers] = &newFiber;
00129 numFibers++;
00130 }
00131 else {
00132
00133 int newSize = 2*numFibers;
00134 if (newSize == 0)
00135 newSize = 2;
00136
00137 Fiber **newArray = new Fiber *[newSize];
00138
00139 if (newArray == 0) {
00140 g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
00141 "FiberSection::addFiber");
00142
00143 sizeFibers = 0;
00144
00145 return -1;
00146 }
00147
00148
00149 sizeFibers = newSize;
00150
00151
00152 for (int i = 0; i < numFibers; i++)
00153 newArray[i] = theFibers[i];
00154
00155
00156 newArray[numFibers] = &newFiber;
00157 numFibers++;
00158
00159
00160 for (int j = numFibers; j < newSize; j++)
00161 newArray[j] = 0;
00162
00163 delete [] theFibers;
00164
00165 theFibers = newArray;
00166 }
00167
00168 return 0;
00169 }
00170
00171
00172 FiberSection::~FiberSection()
00173 {
00174 if (theFibers) {
00175 for (int i = 0; i < numFibers; i++)
00176 if (theFibers[i])
00177 delete theFibers[i];
00178
00179 delete [] theFibers;
00180 }
00181
00182 if (e)
00183 delete e;
00184 if (eCommit)
00185 delete eCommit;
00186 if (s)
00187 delete s;
00188 if (ks)
00189 delete ks;
00190 if (code)
00191 delete code;
00192 }
00193
00194 int FiberSection::setTrialSectionDeformation (const Vector &deforms)
00195 {
00196 int res = 0;
00197
00198 *e = deforms;
00199
00200 for (int i = 0; i < numFibers; i++)
00201 res += theFibers[i]->setTrialFiberStrain(deforms);
00202
00203 return res;
00204 }
00205
00206 const Vector&
00207 FiberSection::getSectionDeformation(void)
00208 {
00209 return *e;
00210 }
00211
00212 const Matrix&
00213 FiberSection::getSectionTangent(void)
00214 {
00215 ks->Zero();
00216
00217 for (int i = 0; i < numFibers; i++)
00218 ks->addMatrix(1.0, theFibers[i]->getFiberTangentStiffContr(), 1.0);
00219
00220 return *ks;
00221 }
00222
00223 const Vector&
00224 FiberSection::getStressResultant(void)
00225 {
00226 s->Zero();
00227
00228 for (int i = 0; i < numFibers; i++)
00229 s->addVector(1.0, theFibers[i]->getFiberStressResultants(), 1.0);
00230
00231 return *s;
00232 }
00233
00234 SectionForceDeformation*
00235 FiberSection::getCopy(void)
00236 {
00237 FiberSection *theCopy = new FiberSection (this->getTag(), numFibers, theFibers);
00238
00239 *(theCopy->eCommit) = *eCommit;
00240
00241 return theCopy;
00242 }
00243
00244 const ID&
00245 FiberSection::getType ()
00246 {
00247 return *code;
00248 }
00249
00250 int
00251 FiberSection::getOrder () const
00252 {
00253 return order;
00254 }
00255
00256 int
00257 FiberSection::commitState(void)
00258 {
00259
00260 int err = 0;
00261
00262 for (int i = 0; i < numFibers; i++)
00263 err += theFibers[i]->commitState();
00264
00265 *eCommit = *e;
00266
00267 return err;
00268 }
00269
00270 int
00271 FiberSection::revertToLastCommit(void)
00272 {
00273 int err = 0;
00274
00275
00276 *e = *eCommit;
00277
00278 s->Zero();
00279 ks->Zero();
00280
00281 for (int i = 0; i < numFibers; i++) {
00282
00283 err += theFibers[i]->revertToLastCommit();
00284
00285
00286 theFibers[i]->setTrialFiberStrain(*e);
00287 s->addVector(1.0, theFibers[i]->getFiberStressResultants(), 1.0);
00288 ks->addMatrix(1.0, theFibers[i]->getFiberTangentStiffContr(), 1.0);
00289 }
00290
00291 return err;
00292 }
00293
00294 int
00295 FiberSection::revertToStart(void)
00296 {
00297
00298 int err = 0;
00299
00300 for (int i = 0; i < numFibers; i++)
00301 err += theFibers[i]->revertToStart();
00302
00303 eCommit->Zero();
00304
00305 return err;
00306 }
00307
00308 int
00309 FiberSection::sendSelf(int commitTag, Channel &theChannel)
00310 {
00311 int res = 0;
00312
00313
00314 if (otherDbTag == 0)
00315 otherDbTag = theChannel.getDbTag();
00316
00317
00318 static ID data(5);
00319
00320 data(0) = this->getTag();
00321 data(1) = numFibers;
00322 data(2) = sizeFibers;
00323 data(3) = order;
00324 data(4) = otherDbTag;
00325
00326
00327 res += theChannel.sendID(this->getDbTag(), commitTag, data);
00328 if (res < 0) {
00329 g3ErrorHandler->warning("%s -- failed to send data ID",
00330 "FiberSection::sendSelf");
00331 return res;
00332 }
00333
00334 if (order > 0) {
00335
00336 res += theChannel.sendVector(this->getDbTag(), commitTag, *eCommit);
00337 if (res < 0) {
00338 g3ErrorHandler->warning("%s -- failed to send section deformations",
00339 "FiberSection::sendSelf");
00340 return res;
00341 }
00342 }
00343
00344
00345 if (numFibers > 0) {
00346
00347 ID dbTags(numFibers+1);
00348
00349 int i;
00350 int dbTag;
00351 for (i = 0; i < numFibers; i++) {
00352 dbTag = theFibers[i]->getDbTag();
00353
00354 if (dbTag == 0) {
00355 dbTag = theChannel.getDbTag();
00356 if (dbTag != 0)
00357 theFibers[i]->setDbTag(dbTag);
00358 }
00359
00360 dbTags(i) = dbTag;
00361 }
00362
00363
00364 dbTags(numFibers) = theFibers[0]->getClassTag();
00365
00366
00367 res += theChannel.sendID(otherDbTag, commitTag, dbTags);
00368 if (res < 0) {
00369 g3ErrorHandler->warning("%s -- failed to send dbTags ID",
00370 "FiberSection::sendSelf");
00371 return res;
00372 }
00373
00374
00375 for (i = 0; i < numFibers; i++) {
00376 res += theFibers[i]->sendSelf(commitTag, theChannel);
00377 if (res < 0) {
00378 g3ErrorHandler->warning("%s -- failed to send Fiber %d",
00379 "FiberSection::sendSelf", i);
00380 return res;
00381 }
00382 }
00383 }
00384
00385 return res;
00386 }
00387
00388 int
00389 FiberSection::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
00390 {
00391 int res = 0;
00392
00393
00394 static ID data(5);
00395
00396
00397 res += theChannel.recvID(this->getDbTag(), commitTag, data);
00398 if (res < 0) {
00399 g3ErrorHandler->warning("%s -- failed to receive data ID",
00400 "FiberSection::recvSelf");
00401 return res;
00402 }
00403
00404 this->setTag(data(0));
00405 numFibers = data(1);
00406 sizeFibers = data(2);
00407 order = data(3);
00408 otherDbTag = data(4);
00409
00410
00411 if (order > 0) {
00412 if (e == 0)
00413 e = new Vector(order);
00414 if (eCommit == 0)
00415 eCommit = new Vector(order);
00416 if (s == 0)
00417 s = new Vector(order);
00418 if (ks == 0)
00419 ks = new Matrix(order,order);
00420 if (code == 0)
00421 code = new ID(order);
00422
00423 if (e->Size() != order) {
00424 delete e;
00425 e = new Vector(order);
00426 }
00427 if (eCommit->Size() != order) {
00428 delete eCommit;
00429 eCommit = new Vector(order);
00430 }
00431 if (s->Size() != order) {
00432 delete s;
00433 s = new Vector(order);
00434 }
00435 if (ks->noRows() != order) {
00436 delete ks;
00437 ks = new Matrix(order,order);
00438 }
00439 if (code->Size() != order) {
00440 delete code;
00441 code = new ID(order);
00442 }
00443
00444
00445 res += theChannel.recvVector(this->getDbTag(), commitTag, *eCommit);
00446 if (res < 0) {
00447 g3ErrorHandler->warning("%s -- failed to receive section deformations",
00448 "FiberSection::recvSelf");
00449 return res;
00450 }
00451
00452 *e = *eCommit;
00453 }
00454
00455 if (numFibers > 0) {
00456
00457 ID dbTags(numFibers+1);
00458
00459
00460 res += theChannel.recvID(otherDbTag, commitTag, dbTags);
00461 if (res < 0) {
00462 g3ErrorHandler->warning("%s -- failed to receive dbTags ID",
00463 "FiberSection::recvSelf");
00464 return res;
00465 }
00466
00467 int i;
00468
00469 if (theFibers == 0) {
00470 theFibers = new Fiber *[sizeFibers];
00471 if (theFibers == 0) {
00472 g3ErrorHandler->warning("%s -- failed to allocate Fiber pointers",
00473 "FiberSection::recvSelf");
00474 return -1;
00475 }
00476 for (i = 0; i < sizeFibers; i++)
00477 theFibers[i] = 0;
00478 }
00479
00480 int fiberClassTag = dbTags(numFibers);
00481 for (i = 0; i < numFibers; i++) {
00482
00483 if (theFibers[i] == 0)
00484 theFibers[i] = theBroker.getNewFiber(fiberClassTag);
00485
00486
00487
00488 else if (theFibers[i]->getClassTag() != fiberClassTag) {
00489 delete theFibers[i];
00490 theFibers[i] = theBroker.getNewFiber(fiberClassTag);
00491 }
00492
00493
00494 if (theFibers[i] == 0) {
00495 g3ErrorHandler->warning("%s -- could not get Fiber %d",
00496 "FiberSection::recvSelf", i);
00497 return -1;
00498 }
00499
00500
00501 theFibers[i]->setDbTag(dbTags(i));
00502 res += theFibers[i]->recvSelf(commitTag, theChannel, theBroker);
00503 if (res < 0) {
00504 g3ErrorHandler->warning("%s -- could not receive Fiber %d",
00505 "FiberSection::recvSelf", i);
00506 return res;
00507 }
00508 }
00509
00510
00511 *code = theFibers[0]->getType();
00512 }
00513
00514
00515
00516 return res;
00517 }
00518
00519 void
00520 FiberSection::Print(OPS_Stream &s, int flag)
00521 {
00522 s << "\nFiberSection, tag: " << this->getTag() << endln;
00523 s << "\tSection code: " << *code;
00524 s << "\tNumber of Fibers: " << numFibers << endln;
00525
00526 if (flag == 1)
00527 for (int i = 0; i < numFibers; i++)
00528 theFibers[i]->Print(s, flag);
00529 }
00530
00531 Response*
00532 FiberSection::setResponse(const char **argv, int argc, Information §Info)
00533 {
00534
00535 Response *res = SectionForceDeformation::setResponse(argv, argc, sectInfo);
00536 if (res != 0)
00537 return res;
00538
00539
00540 else if (strcmp(argv[0],"fiber") == 0) {
00541 int key = 0;
00542 int passarg = 2;
00543
00544 if (argc <= 2)
00545 return 0;
00546 else if (argc <= 3)
00547 key = atoi(argv[1]);
00548 else {
00549 double yCoord = atof(argv[1]);
00550 double zCoord = atof(argv[2]);
00551 double ySearch, zSearch;
00552 theFibers[0]->getFiberLocation(ySearch,zSearch);
00553 double closestDist = sqrt( pow(ySearch-yCoord,2) +
00554 pow(zSearch-zCoord,2) );
00555 double distance;
00556 for (int j = 1; j < numFibers; j++) {
00557 theFibers[j]->getFiberLocation(ySearch,zSearch);
00558 distance = sqrt( pow(ySearch-yCoord,2) +
00559 pow(zSearch-zCoord,2) );
00560 if (distance < closestDist) {
00561 closestDist = distance;
00562 key = j;
00563 }
00564 }
00565 theFibers[key]->getFiberLocation(ySearch,zSearch);
00566 passarg = 3;
00567 }
00568
00569 if (key < numFibers)
00570 return theFibers[key]->setResponse(&argv[passarg],argc-passarg,sectInfo);
00571 else
00572 return 0;
00573 }
00574
00575
00576 else
00577 return 0;
00578 }
00579
00580 int
00581 FiberSection::getResponse(int responseID, Information §Info)
00582 {
00583
00584
00585 return SectionForceDeformation::getResponse(responseID, sectInfo);
00586 }