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 #include <SectionIntegration.h>
00045
00046 ID FiberSection2d::code(2);
00047
00048
00049 FiberSection2d::FiberSection2d(int tag, int num, Fiber **fibers):
00050 SectionForceDeformation(tag, SEC_TAG_FiberSection2d),
00051 numFibers(num), theMaterials(0), matData(0),
00052 yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)
00053 {
00054 if (numFibers != 0) {
00055 theMaterials = new UniaxialMaterial *[numFibers];
00056
00057 if (theMaterials == 0) {
00058 opserr << "FiberSection2d::FiberSection2d -- failed to allocate Material pointers";
00059 exit(-1);
00060 }
00061
00062 matData = new double [numFibers*2];
00063
00064 if (matData == 0) {
00065 opserr << "FiberSection2d::FiberSection2d -- failed to allocate double array for material data\n";
00066 exit(-1);
00067 }
00068
00069
00070 double Qz = 0.0;
00071 double A = 0.0;
00072
00073 for (int i = 0; i < numFibers; i++) {
00074 Fiber *theFiber = fibers[i];
00075 double yLoc, zLoc, Area;
00076 theFiber->getFiberLocation(yLoc, zLoc);
00077 Area = theFiber->getArea();
00078 A += Area;
00079 Qz += yLoc*Area;
00080 matData[i*2] = yLoc;
00081 matData[i*2+1] = Area;
00082 UniaxialMaterial *theMat = theFiber->getMaterial();
00083 theMaterials[i] = theMat->getCopy();
00084
00085 if (theMaterials[i] == 0) {
00086 opserr << "FiberSection2d::FiberSection2d -- failed to get copy of a Material\n";
00087 exit(-1);
00088 }
00089 }
00090
00091 yBar = Qz/A;
00092 }
00093
00094 s = new Vector(sData, 2);
00095 ks = new Matrix(kData, 2, 2);
00096
00097 sData[0] = 0.0;
00098 sData[1] = 0.0;
00099
00100 kData[0] = 0.0;
00101 kData[1] = 0.0;
00102 kData[2] = 0.0;
00103 kData[3] = 0.0;
00104
00105 code(0) = SECTION_RESPONSE_P;
00106 code(1) = SECTION_RESPONSE_MZ;
00107 }
00108
00109 FiberSection2d::FiberSection2d(int tag, int num, UniaxialMaterial **mats,
00110 SectionIntegration &si):
00111 SectionForceDeformation(tag, SEC_TAG_FiberSection2d),
00112 numFibers(num), theMaterials(0), matData(0),
00113 yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)
00114 {
00115 if (numFibers != 0) {
00116 theMaterials = new UniaxialMaterial *[numFibers];
00117
00118 if (theMaterials == 0) {
00119 opserr << "FiberSection2d::FiberSection2d -- failed to allocate Material pointers";
00120 exit(-1);
00121 }
00122 matData = new double [numFibers*2];
00123
00124 if (matData == 0) {
00125 opserr << "FiberSection2d::FiberSection2d -- failed to allocate double array for material data\n";
00126 exit(-1);
00127 }
00128 }
00129
00130 sectionIntegr = si.getCopy();
00131 if (sectionIntegr == 0) {
00132 opserr << "Error: FiberSection2d::FiberSection2d: could not create copy of section integration object" << endln;
00133 exit(-1);
00134 }
00135
00136 double fiberLocs[10000];
00137 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00138
00139 double fiberArea[10000];
00140 sectionIntegr->getFiberWeights(numFibers, fiberArea);
00141
00142 double Qz = 0.0;
00143 double A = 0.0;
00144
00145 for (int i = 0; i < numFibers; i++) {
00146
00147 A += fiberArea[i];
00148 Qz += fiberLocs[i]*fiberArea[i];
00149
00150 theMaterials[i] = mats[i]->getCopy();
00151
00152 if (theMaterials[i] == 0) {
00153 opserr << "FiberSection2d::FiberSection2d -- failed to get copy of a Material\n";
00154 exit(-1);
00155 }
00156 }
00157
00158 yBar = Qz/A;
00159
00160 s = new Vector(sData, 2);
00161 ks = new Matrix(kData, 2, 2);
00162
00163 sData[0] = 0.0;
00164 sData[1] = 0.0;
00165
00166 kData[0] = 0.0;
00167 kData[1] = 0.0;
00168 kData[2] = 0.0;
00169 kData[3] = 0.0;
00170
00171 code(0) = SECTION_RESPONSE_P;
00172 code(1) = SECTION_RESPONSE_MZ;
00173 }
00174
00175
00176 FiberSection2d::FiberSection2d():
00177 SectionForceDeformation(0, SEC_TAG_FiberSection2d),
00178 numFibers(0), theMaterials(0), matData(0),
00179 yBar(0.0), sectionIntegr(0), e(2), eCommit(2), s(0), ks(0), dedh(2)
00180 {
00181 s = new Vector(sData, 2);
00182 ks = new Matrix(kData, 2, 2);
00183
00184 sData[0] = 0.0;
00185 sData[1] = 0.0;
00186
00187 kData[0] = 0.0;
00188 kData[1] = 0.0;
00189 kData[2] = 0.0;
00190 kData[3] = 0.0;
00191
00192 code(0) = SECTION_RESPONSE_P;
00193 code(1) = SECTION_RESPONSE_MZ;
00194 }
00195
00196 int
00197 FiberSection2d::addFiber(Fiber &newFiber)
00198 {
00199
00200 int newSize = numFibers+1;
00201 UniaxialMaterial **newArray = new UniaxialMaterial *[newSize];
00202 double *newMatData = new double [2 * newSize];
00203 if (newArray == 0 || newMatData == 0) {
00204 opserr <<"FiberSection2d::addFiber -- failed to allocate Fiber pointers\n";
00205 return -1;
00206 }
00207
00208
00209 int i;
00210 for (i = 0; i < numFibers; i++) {
00211 newArray[i] = theMaterials[i];
00212 newMatData[2*i] = matData[2*i];
00213 newMatData[2*i+1] = matData[2*i+1];
00214 }
00215
00216
00217 double yLoc, zLoc, Area;
00218 newFiber.getFiberLocation(yLoc, zLoc);
00219 Area = newFiber.getArea();
00220 newMatData[numFibers*2] = yLoc;
00221 newMatData[numFibers*2+1] = Area;
00222 UniaxialMaterial *theMat = newFiber.getMaterial();
00223 newArray[numFibers] = theMat->getCopy();
00224
00225 if (newArray[numFibers] == 0) {
00226 opserr <<"FiberSection2d::addFiber -- failed to get copy of a Material\n";
00227 delete [] newMatData;
00228 return -1;
00229 }
00230
00231 numFibers++;
00232
00233 if (theMaterials != 0) {
00234 delete [] theMaterials;
00235 delete [] matData;
00236 }
00237
00238 theMaterials = newArray;
00239 matData = newMatData;
00240
00241 double Qz = 0.0;
00242 double A = 0.0;
00243
00244
00245 for (i = 0; i < numFibers; i++) {
00246 yLoc = -matData[2*i];
00247 Area = matData[2*i+1];
00248 A += Area;
00249 Qz += yLoc*Area;
00250 }
00251
00252 yBar = Qz/A;
00253
00254 return 0;
00255 }
00256
00257
00258
00259
00260 FiberSection2d::~FiberSection2d()
00261 {
00262 if (theMaterials != 0) {
00263 for (int i = 0; i < numFibers; i++)
00264 if (theMaterials[i] != 0)
00265 delete theMaterials[i];
00266
00267 delete [] theMaterials;
00268 }
00269
00270 if (matData != 0)
00271 delete [] matData;
00272
00273 if (s != 0)
00274 delete s;
00275
00276 if (ks != 0)
00277 delete ks;
00278
00279 if (sectionIntegr != 0)
00280 delete sectionIntegr;
00281 }
00282
00283 int
00284 FiberSection2d::setTrialSectionDeformation (const Vector &deforms)
00285 {
00286 int res = 0;
00287
00288 e = deforms;
00289
00290 kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00291 sData[0] = 0.0; sData[1] = 0.0;
00292
00293 double d0 = deforms(0);
00294 double d1 = deforms(1);
00295
00296 double fiberLocs[10000];
00297 double fiberArea[10000];
00298
00299 if (sectionIntegr != 0) {
00300 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00301 sectionIntegr->getFiberWeights(numFibers, fiberArea);
00302 }
00303 else {
00304 for (int i = 0; i < numFibers; i++) {
00305 fiberLocs[i] = matData[2*i];
00306 fiberArea[i] = matData[2*i+1];
00307 }
00308 }
00309
00310 for (int i = 0; i < numFibers; i++) {
00311 UniaxialMaterial *theMat = theMaterials[i];
00312 double y = fiberLocs[i] - yBar;
00313 double A = fiberArea[i];
00314
00315
00316 double strain = d0 - y*d1;
00317 double tangent, stress;
00318 res = theMat->setTrial(strain, stress, tangent);
00319
00320 double ks0 = tangent * A;
00321 double ks1 = ks0 * -y;
00322 kData[0] += ks0;
00323 kData[1] += ks1;
00324 kData[3] += ks1 * -y;
00325
00326 double fs0 = stress * A;
00327 sData[0] += fs0;
00328 sData[1] += fs0 * -y;
00329 }
00330
00331 kData[2] = kData[1];
00332
00333 return res;
00334 }
00335
00336 const Vector&
00337 FiberSection2d::getSectionDeformation(void)
00338 {
00339 return e;
00340 }
00341
00342 const Matrix&
00343 FiberSection2d::getInitialTangent(void)
00344 {
00345 static double kInitial[4];
00346 static Matrix kInitialMatrix(kInitial, 2, 2);
00347 kInitial[0] = 0.0; kInitial[1] = 0.0; kInitial[2] = 0.0; kInitial[3] = 0.0;
00348
00349 double fiberLocs[10000];
00350 double fiberArea[10000];
00351
00352 if (sectionIntegr != 0) {
00353 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00354 sectionIntegr->getFiberWeights(numFibers, fiberArea);
00355 }
00356 else {
00357 for (int i = 0; i < numFibers; i++) {
00358 fiberLocs[i] = matData[2*i];
00359 fiberArea[i] = matData[2*i+1];
00360 }
00361 }
00362
00363 for (int i = 0; i < numFibers; i++) {
00364 UniaxialMaterial *theMat = theMaterials[i];
00365 double y = fiberLocs[i] - yBar;
00366 double A = fiberArea[i];
00367
00368 double tangent = theMat->getInitialTangent();
00369
00370 double ks0 = tangent * A;
00371 double ks1 = ks0 * -y;
00372 kInitial[0] += ks0;
00373 kInitial[1] += ks1;
00374 kInitial[3] += ks1 * -y;
00375 }
00376
00377 kInitial[2] = kInitial[1];
00378
00379 return kInitialMatrix;
00380 }
00381
00382 const Matrix&
00383 FiberSection2d::getSectionTangent(void)
00384 {
00385 return *ks;
00386 }
00387
00388 const Vector&
00389 FiberSection2d::getStressResultant(void)
00390 {
00391 return *s;
00392 }
00393
00394 SectionForceDeformation*
00395 FiberSection2d::getCopy(void)
00396 {
00397 FiberSection2d *theCopy = new FiberSection2d ();
00398 theCopy->setTag(this->getTag());
00399
00400 theCopy->numFibers = numFibers;
00401
00402 if (numFibers != 0) {
00403 theCopy->theMaterials = new UniaxialMaterial *[numFibers];
00404
00405 if (theCopy->theMaterials == 0) {
00406 opserr <<"FiberSection2d::getCopy -- failed to allocate Material pointers\n";
00407 exit(-1);
00408 }
00409
00410 theCopy->matData = new double [numFibers*2];
00411
00412 if (theCopy->matData == 0) {
00413 opserr << "FiberSection2d::getCopy -- failed to allocate double array for material data\n";
00414 exit(-1);
00415 }
00416
00417 for (int i = 0; i < numFibers; i++) {
00418 theCopy->matData[i*2] = matData[i*2];
00419 theCopy->matData[i*2+1] = matData[i*2+1];
00420 theCopy->theMaterials[i] = theMaterials[i]->getCopy();
00421
00422 if (theCopy->theMaterials[i] == 0) {
00423 opserr <<"FiberSection2d::getCopy -- failed to get copy of a Material";
00424 exit(-1);
00425 }
00426 }
00427 }
00428
00429 theCopy->eCommit = eCommit;
00430 theCopy->e = e;
00431 theCopy->yBar = yBar;
00432
00433 theCopy->kData[0] = kData[0];
00434 theCopy->kData[1] = kData[1];
00435 theCopy->kData[2] = kData[2];
00436 theCopy->kData[3] = kData[3];
00437
00438 theCopy->sData[0] = sData[0];
00439 theCopy->sData[1] = sData[1];
00440
00441 if (sectionIntegr != 0)
00442 theCopy->sectionIntegr = sectionIntegr->getCopy();
00443 else
00444 theCopy->sectionIntegr = 0;
00445
00446 return theCopy;
00447 }
00448
00449 const ID&
00450 FiberSection2d::getType ()
00451 {
00452 return code;
00453 }
00454
00455 int
00456 FiberSection2d::getOrder () const
00457 {
00458 return 2;
00459 }
00460
00461 int
00462 FiberSection2d::commitState(void)
00463 {
00464 int err = 0;
00465
00466 for (int i = 0; i < numFibers; i++)
00467 err += theMaterials[i]->commitState();
00468
00469 eCommit = e;
00470
00471 return err;
00472 }
00473
00474 int
00475 FiberSection2d::revertToLastCommit(void)
00476 {
00477 int err = 0;
00478
00479
00480 e = eCommit;
00481
00482
00483 kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00484 sData[0] = 0.0; sData[1] = 0.0;
00485
00486 double fiberLocs[10000];
00487 double fiberArea[10000];
00488
00489 if (sectionIntegr != 0) {
00490 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00491 sectionIntegr->getFiberWeights(numFibers, fiberArea);
00492 }
00493 else {
00494 for (int i = 0; i < numFibers; i++) {
00495 fiberLocs[i] = matData[2*i];
00496 fiberArea[i] = matData[2*i+1];
00497 }
00498 }
00499
00500 for (int i = 0; i < numFibers; i++) {
00501 UniaxialMaterial *theMat = theMaterials[i];
00502 double y = fiberLocs[i] - yBar;
00503 double A = fiberArea[i];
00504
00505
00506 err += theMat->revertToLastCommit();
00507
00508
00509 double tangent = theMat->getTangent();
00510 double stress = theMat->getStress();
00511 double ks0 = tangent * A;
00512 double ks1 = ks0 * -y;
00513 kData[0] += ks0;
00514 kData[1] += ks1;
00515 kData[3] += ks1 * -y;
00516
00517 double fs0 = stress * A;
00518 sData[0] = fs0;
00519 sData[1] = fs0 * -y;
00520 }
00521
00522 kData[2] = kData[1];
00523
00524 return err;
00525 }
00526
00527 int
00528 FiberSection2d::revertToStart(void)
00529 {
00530
00531 int err = 0;
00532
00533 kData[0] = 0.0; kData[1] = 0.0; kData[2] = 0.0; kData[3] = 0.0;
00534 sData[0] = 0.0; sData[1] = 0.0;
00535
00536 double fiberLocs[10000];
00537 double fiberArea[10000];
00538
00539 if (sectionIntegr != 0) {
00540 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
00541 sectionIntegr->getFiberWeights(numFibers, fiberArea);
00542 }
00543 else {
00544 for (int i = 0; i < numFibers; i++) {
00545 fiberLocs[i] = matData[2*i];
00546 fiberArea[i] = matData[2*i+1];
00547 }
00548 }
00549
00550 for (int i = 0; i < numFibers; i++) {
00551 UniaxialMaterial *theMat = theMaterials[i];
00552 double y = fiberLocs[i] - yBar;
00553 double A = fiberArea[i];
00554
00555
00556 err += theMat->revertToStart();
00557
00558
00559 double tangent = theMat->getTangent();
00560 double stress = theMat->getStress();
00561 double ks0 = tangent * A;
00562 double ks1 = ks0 * -y;
00563 kData[0] += ks0;
00564 kData[1] += ks1;
00565 kData[3] += ks1 * -y;
00566
00567 double fs0 = stress * A;
00568 sData[0] = fs0;
00569 sData[1] = fs0 * -y;
00570 }
00571
00572 kData[2] = kData[1];
00573
00574 return err;
00575 }
00576
00577 int
00578 FiberSection2d::sendSelf(int commitTag, Channel &theChannel)
00579 {
00580 int res = 0;
00581
00582
00583
00584 static ID data(3);
00585 data(0) = this->getTag();
00586 data(1) = numFibers;
00587 int dbTag = this->getDbTag();
00588 res += theChannel.sendID(dbTag, commitTag, data);
00589 if (res < 0) {
00590 opserr << "FiberSection2d::sendSelf - failed to send ID data\n";
00591 return res;
00592 }
00593
00594 if (numFibers != 0) {
00595
00596
00597 ID materialData(2*numFibers);
00598 for (int i=0; i<numFibers; i++) {
00599 UniaxialMaterial *theMat = theMaterials[i];
00600 materialData(2*i) = theMat->getClassTag();
00601 int matDbTag = theMat->getDbTag();
00602 if (matDbTag == 0) {
00603 matDbTag = theChannel.getDbTag();
00604 if (matDbTag != 0)
00605 theMat->setDbTag(matDbTag);
00606 }
00607 materialData(2*i+1) = matDbTag;
00608 }
00609
00610 res += theChannel.sendID(dbTag, commitTag, materialData);
00611 if (res < 0) {
00612 opserr << "FiberSection2d::sendSelf - failed to send material data\n";
00613 return res;
00614 }
00615
00616
00617 Vector fiberData(matData, 2*numFibers);
00618 res += theChannel.sendVector(dbTag, commitTag, fiberData);
00619 if (res < 0) {
00620 opserr << "FiberSection2d::sendSelf - failed to send material data\n";
00621 return res;
00622 }
00623
00624
00625 for (int j=0; j<numFibers; j++)
00626 theMaterials[j]->sendSelf(commitTag, theChannel);
00627
00628 }
00629
00630 return res;
00631 }
00632
00633 int
00634 FiberSection2d::recvSelf(int commitTag, Channel &theChannel,
00635 FEM_ObjectBroker &theBroker)
00636 {
00637 int res = 0;
00638
00639 static ID data(3);
00640
00641 int dbTag = this->getDbTag();
00642 res += theChannel.recvID(dbTag, commitTag, data);
00643 if (res < 0) {
00644 opserr << "FiberSection2d::recvSelf - failed to recv ID data\n";
00645 return res;
00646 }
00647 this->setTag(data(0));
00648
00649
00650 if (data(1) != 0) {
00651 ID materialData(2*data(1));
00652 res += theChannel.recvID(dbTag, commitTag, materialData);
00653 if (res < 0) {
00654 opserr << "FiberSection2d::recvSelf - failed to recv material data\n";
00655 return res;
00656 }
00657
00658
00659 if (theMaterials == 0 || numFibers != data(1)) {
00660
00661 if (theMaterials != 0) {
00662 for (int i=0; i<numFibers; i++)
00663 delete theMaterials[i];
00664 delete [] theMaterials;
00665 if (matData != 0)
00666 delete [] matData;
00667 matData = 0;
00668 theMaterials = 0;
00669 }
00670
00671
00672 numFibers = data(1);
00673 if (numFibers != 0) {
00674 theMaterials = new UniaxialMaterial *[numFibers];
00675
00676 if (theMaterials == 0) {
00677 opserr <<"FiberSection2d::recvSelf -- failed to allocate Material pointers\n";
00678 exit(-1);
00679 }
00680
00681 for (int j=0; j<numFibers; j++)
00682 theMaterials[j] = 0;
00683
00684 matData = new double [numFibers*2];
00685
00686 if (matData == 0) {
00687 opserr <<"FiberSection2d::recvSelf -- failed to allocate double array for material data\n";
00688 exit(-1);
00689 }
00690 }
00691 }
00692
00693 Vector fiberData(matData, 2*numFibers);
00694 res += theChannel.recvVector(dbTag, commitTag, fiberData);
00695 if (res < 0) {
00696 opserr << "FiberSection2d::recvSelf - failed to recv material data\n";
00697 return res;
00698 }
00699
00700 int i;
00701 for (i=0; i<numFibers; i++) {
00702 int classTag = materialData(2*i);
00703 int dbTag = materialData(2*i+1);
00704
00705
00706
00707 if (theMaterials[i] == 0)
00708 theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);
00709 else if (theMaterials[i]->getClassTag() != classTag) {
00710 delete theMaterials[i];
00711 theMaterials[i] = theBroker.getNewUniaxialMaterial(classTag);
00712 }
00713
00714 if (theMaterials[i] == 0) {
00715 opserr <<"FiberSection2d::recvSelf -- failed to allocate double array for material data\n";
00716 exit(-1);
00717 }
00718
00719 theMaterials[i]->setDbTag(dbTag);
00720 res += theMaterials[i]->recvSelf(commitTag, theChannel, theBroker);
00721 }
00722
00723 double Qz = 0.0;
00724 double A = 0.0;
00725 double yLoc, Area;
00726
00727
00728 for (i = 0; i < numFibers; i++) {
00729 yLoc = matData[2*i];
00730 Area = matData[2*i+1];
00731 A += Area;
00732 Qz += yLoc*Area;
00733 }
00734
00735 yBar = Qz/A;
00736 }
00737
00738 return res;
00739 }
00740
00741 void
00742 FiberSection2d::Print(OPS_Stream &s, int flag)
00743 {
00744 s << "\nFiberSection2d, tag: " << this->getTag() << endln;
00745 s << "\tSection code: " << code;
00746 s << "\tNumber of Fibers: " << numFibers << endln;
00747 s << "\tCentroid: " << yBar << endln;
00748
00749 if (flag == 1) {
00750 for (int i = 0; i < numFibers; i++) {
00751 s << "\nLocation (y) = (" << matData[2*i] << ")";
00752 s << "\nArea = " << matData[2*i+1] << endln;
00753 theMaterials[i]->Print(s, flag);
00754 }
00755 }
00756 }
00757
00758 Response*
00759 FiberSection2d::setResponse(const char **argv, int argc,
00760 Information §Info, OPS_Stream &output)
00761 {
00762
00763 const ID &type = this->getType();
00764 int typeSize = this->getOrder();
00765
00766
00767 Response *theResponse =0;
00768
00769 output.tag("SectionOutput");
00770 output.attr("secType", this->getClassType());
00771 output.attr("secTag", this->getTag());
00772
00773
00774 if (strcmp(argv[0],"deformations") == 0 || strcmp(argv[0],"deformation") == 0) {
00775 for (int i=0; i<typeSize; i++) {
00776 int code = type(i);
00777 switch (code){
00778 case SECTION_RESPONSE_MZ:
00779 output.tag("ResponseType","kappaZ");
00780 break;
00781 case SECTION_RESPONSE_P:
00782 output.tag("ResponseType","eps");
00783 break;
00784 case SECTION_RESPONSE_VY:
00785 output.tag("ResponseType","gammaY");
00786 break;
00787 case SECTION_RESPONSE_MY:
00788 output.tag("ResponseType","kappaY");
00789 break;
00790 case SECTION_RESPONSE_VZ:
00791 output.tag("ResponseType","gammaZ");
00792 break;
00793 case SECTION_RESPONSE_T:
00794 output.tag("ResponseType","theta");
00795 break;
00796 default:
00797 output.tag("ResponseType","Unknown");
00798 }
00799 }
00800 theResponse = new MaterialResponse(this, 1, this->getSectionDeformation());
00801
00802
00803 } else if (strcmp(argv[0],"forces") == 0 || strcmp(argv[0],"force") == 0) {
00804 for (int i=0; i<typeSize; i++) {
00805 int code = type(i);
00806 switch (code){
00807 case SECTION_RESPONSE_MZ:
00808 output.tag("ResponseType","Mz");
00809 break;
00810 case SECTION_RESPONSE_P:
00811 output.tag("ResponseType","P");
00812 break;
00813 case SECTION_RESPONSE_VY:
00814 output.tag("ResponseType","Vy");
00815 break;
00816 case SECTION_RESPONSE_MY:
00817 output.tag("ResponseType","My");
00818 break;
00819 case SECTION_RESPONSE_VZ:
00820 output.tag("ResponseType","Vz");
00821 break;
00822 case SECTION_RESPONSE_T:
00823 output.tag("ResponseType","T");
00824 break;
00825 default:
00826 output.tag("ResponseType","Unknown");
00827 }
00828 }
00829 theResponse = new MaterialResponse(this, 2, this->getStressResultant());
00830
00831
00832 } else if (strcmp(argv[0],"forceAndDeformation") == 0) {
00833 for (int j=0; j<typeSize; j++) {
00834 int code = type(j);
00835 switch (code){
00836 case SECTION_RESPONSE_MZ:
00837 output.tag("ResponseType","kappaZ");
00838 break;
00839 case SECTION_RESPONSE_P:
00840 output.tag("ResponseType","eps");
00841 break;
00842 case SECTION_RESPONSE_VY:
00843 output.tag("ResponseType","gammaY");
00844 break;
00845 case SECTION_RESPONSE_MY:
00846 output.tag("ResponseType","kappaY");
00847 break;
00848 case SECTION_RESPONSE_VZ:
00849 output.tag("ResponseType","gammaZ");
00850 break;
00851 case SECTION_RESPONSE_T:
00852 output.tag("ResponseType","theta");
00853 break;
00854 default:
00855 output.tag("ResponseType","Unknown");
00856 }
00857 }
00858 for (int i=0; i<typeSize; i++) {
00859 int code = type(i);
00860 switch (code){
00861 case SECTION_RESPONSE_MZ:
00862 output.tag("ResponseType","Mz");
00863 break;
00864 case SECTION_RESPONSE_P:
00865 output.tag("ResponseType","P");
00866 break;
00867 case SECTION_RESPONSE_VY:
00868 output.tag("ResponseType","Vy");
00869 break;
00870 case SECTION_RESPONSE_MY:
00871 output.tag("ResponseType","My");
00872 break;
00873 case SECTION_RESPONSE_VZ:
00874 output.tag("ResponseType","Vz");
00875 break;
00876 case SECTION_RESPONSE_T:
00877 output.tag("ResponseType","T");
00878 break;
00879 default:
00880 output.tag("ResponseType","Unknown");
00881 }
00882 }
00883
00884 theResponse = new MaterialResponse(this, 4, Vector(2*this->getOrder()));
00885
00886 }
00887
00888 else {
00889 if (argc > 2 || strcmp(argv[0],"fiber") == 0) {
00890
00891 int key = numFibers;
00892 int passarg = 2;
00893
00894 if (argc <= 3) {
00895
00896 key = atoi(argv[1]);
00897
00898 } else if (argc > 4) {
00899
00900 int matTag = atoi(argv[3]);
00901 double yCoord = atof(argv[1]);
00902 double closestDist;
00903 double ySearch, dy;
00904 double distance;
00905 int j;
00906
00907 for (j = 0; j < numFibers; j++) {
00908 if (matTag == theMaterials[j]->getTag()) {
00909 ySearch = -matData[2*j];
00910 dy = ySearch-yCoord;
00911 closestDist = fabs(dy);
00912 key = j;
00913 break;
00914 }
00915 }
00916
00917 for ( ; j < numFibers; j++) {
00918 if (matTag == theMaterials[j]->getTag()) {
00919 ySearch = -matData[2*j];
00920 dy = ySearch-yCoord;
00921 distance = fabs(dy);
00922 if (distance < closestDist) {
00923 closestDist = distance;
00924 key = j;
00925 }
00926 }
00927 }
00928 passarg = 4;
00929 }
00930
00931 else {
00932 double yCoord = atof(argv[1]);
00933 double closestDist;
00934 double ySearch, dy;
00935 double distance;
00936 ySearch = -matData[0];
00937 dy = ySearch-yCoord;
00938 closestDist = fabs(dy);
00939 key = 0;
00940 for (int j = 1; j < numFibers; j++) {
00941 ySearch = -matData[2*j];
00942 dy = ySearch-yCoord;
00943 distance = fabs(dy);
00944 if (distance < closestDist) {
00945 closestDist = distance;
00946 key = j;
00947 }
00948 }
00949 passarg = 3;
00950 }
00951
00952
00953 if (key < numFibers && key >= 0) {
00954 output.tag("FiberOutput");
00955 output.attr("yLoc",-matData[2*key]);
00956 output.attr("zLoc",0.0);
00957 output.attr("area",matData[2*key+1]);
00958
00959 theResponse = theMaterials[key]->setResponse(&argv[passarg], argc-passarg, sectInfo, output);
00960
00961 output.endTag();
00962 }
00963 }
00964 }
00965
00966 output.endTag();
00967 return theResponse;
00968 }
00969
00970
00971 int
00972 FiberSection2d::getResponse(int responseID, Information §Info)
00973 {
00974
00975
00976 return SectionForceDeformation::getResponse(responseID, sectInfo);
00977 }
00978
00979
00980
00981
00982 int
00983 FiberSection2d::setParameter(const char **argv, int argc, Parameter ¶m)
00984 {
00985 if (argc < 1)
00986 return -1;
00987
00988
00989 if (strstr(argv[0],"material") != 0) {
00990
00991 if (argc < 3)
00992 return 0;
00993
00994
00995 int materialTag = atoi(argv[1]);
00996
00997
00998 int ok = 0;
00999 for (int i = 0; i < numFibers; i++)
01000 if (materialTag == theMaterials[i]->getTag())
01001 ok += theMaterials[i]->setParameter(&argv[2], argc-2, param);
01002
01003 return ok;
01004 }
01005
01006 else
01007 return sectionIntegr->setParameter(argv, argc, param);
01008 }
01009
01010 const Vector &
01011 FiberSection2d::getSectionDeformationSensitivity(int gradNumber)
01012 {
01013 static Vector dummy(2);
01014
01015 return dummy;
01016 }
01017
01018 const Vector &
01019 FiberSection2d::getStressResultantSensitivity(int gradNumber, bool conditional)
01020 {
01021 static Vector ds(2);
01022
01023 ds.Zero();
01024
01025 double y, A, stressGradient, stress, tangent, sig_dAdh;
01026
01027 double fiberLocs[10000];
01028 double fiberArea[10000];
01029
01030 if (sectionIntegr != 0) {
01031 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
01032 sectionIntegr->getFiberWeights(numFibers, fiberArea);
01033 }
01034 else {
01035 for (int i = 0; i < numFibers; i++) {
01036 fiberLocs[i] = matData[2*i];
01037 fiberArea[i] = matData[2*i+1];
01038 }
01039 }
01040
01041 double locsDeriv[10000];
01042 double areaDeriv[10000];
01043
01044 if (sectionIntegr != 0) {
01045 sectionIntegr->getLocationsDeriv(numFibers, locsDeriv);
01046 sectionIntegr->getWeightsDeriv(numFibers, areaDeriv);
01047 }
01048 else {
01049 for (int i = 0; i < numFibers; i++) {
01050 locsDeriv[i] = 0.0;
01051 areaDeriv[i] = 0.0;
01052 }
01053 }
01054
01055 for (int i = 0; i < numFibers; i++) {
01056 y = fiberLocs[i] - yBar;
01057 A = fiberArea[i];
01058
01059 stressGradient = theMaterials[i]->getStressSensitivity(gradNumber,true);
01060 stressGradient = stressGradient * A;
01061
01062 ds(0) += stressGradient;
01063 ds(1) += stressGradient * -y;
01064
01065 stress = theMaterials[i]->getStress();
01066 sig_dAdh = stress*areaDeriv[i];
01067
01068 ds(0) += sig_dAdh;
01069 ds(1) += sig_dAdh * -y;
01070
01071
01072 ds(1) += (stress*A) * -locsDeriv[i];
01073
01074 tangent = theMaterials[i]->getTangent();
01075 tangent = tangent * A * e(1);
01076
01077 ds(0) += -locsDeriv[i]*tangent;
01078 ds(1) += fiberLocs[i]*locsDeriv[i]*tangent;
01079
01080
01081 }
01082
01083 return ds;
01084 }
01085
01086 const Matrix &
01087 FiberSection2d::getInitialTangentSensitivity(int gradNumber)
01088 {
01089 static Matrix dksdh(2,2);
01090
01091 dksdh.Zero();
01092
01093 double y, A, dydh, dAdh, tangent, dtangentdh;
01094
01095 double fiberLocs[10000];
01096 double fiberArea[10000];
01097
01098 if (sectionIntegr != 0) {
01099 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
01100 sectionIntegr->getFiberWeights(numFibers, fiberArea);
01101 }
01102 else {
01103 for (int i = 0; i < numFibers; i++) {
01104 fiberLocs[i] = matData[2*i];
01105 fiberArea[i] = matData[2*i+1];
01106 }
01107 }
01108
01109 double locsDeriv[10000];
01110 double areaDeriv[10000];
01111
01112 if (sectionIntegr != 0) {
01113 sectionIntegr->getLocationsDeriv(numFibers, locsDeriv);
01114 sectionIntegr->getWeightsDeriv(numFibers, areaDeriv);
01115 }
01116 else {
01117 for (int i = 0; i < numFibers; i++) {
01118 locsDeriv[i] = 0.0;
01119 areaDeriv[i] = 0.0;
01120 }
01121 }
01122
01123 for (int i = 0; i < numFibers; i++) {
01124 y = fiberLocs[i] - yBar;
01125 A = fiberArea[i];
01126 dydh = locsDeriv[i];
01127 dAdh = areaDeriv[i];
01128
01129 tangent = theMaterials[i]->getInitialTangent();
01130 dtangentdh = theMaterials[i]->getInitialTangentSensitivity(gradNumber);
01131
01132 dksdh(0,0) += dtangentdh*A + tangent*dAdh;
01133
01134 dksdh(0,1) += -y*(dtangentdh*A+tangent*dAdh) - dydh*(tangent*A);
01135
01136 dksdh(1,1) += 2*(y*dydh*tangent*A) + y*y*(dtangentdh*A+tangent*dAdh);
01137 }
01138
01139 dksdh(1,0) = dksdh(0,1);
01140
01141 return dksdh;
01142 }
01143
01144 int
01145 FiberSection2d::commitSensitivity(const Vector& defSens,
01146 int gradNumber, int numGrads)
01147 {
01148 double d0 = defSens(0);
01149 double d1 = defSens(1);
01150
01151 dedh = defSens;
01152
01153 double fiberLocs[10000];
01154
01155 if (sectionIntegr != 0)
01156 sectionIntegr->getFiberLocations(numFibers, fiberLocs);
01157 else {
01158 for (int i = 0; i < numFibers; i++)
01159 fiberLocs[i] = matData[2*i];
01160 }
01161
01162 double locsDeriv[10000];
01163 double areaDeriv[10000];
01164
01165 if (sectionIntegr != 0) {
01166 sectionIntegr->getLocationsDeriv(numFibers, locsDeriv);
01167 sectionIntegr->getWeightsDeriv(numFibers, areaDeriv);
01168 }
01169 else {
01170 for (int i = 0; i < numFibers; i++) {
01171 locsDeriv[i] = 0.0;
01172 areaDeriv[i] = 0.0;
01173 }
01174 }
01175
01176 double y;
01177 double kappa = e(1);
01178
01179 for (int i = 0; i < numFibers; i++) {
01180 UniaxialMaterial *theMat = theMaterials[i];
01181 y = fiberLocs[i] - yBar;
01182
01183
01184 double strainSens = d0 - y*d1 - locsDeriv[i]*kappa;
01185 theMat->commitSensitivity(strainSens,gradNumber,numGrads);
01186 }
01187
01188 return 0;
01189 }
01190
01191