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