PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/opensees-websocket/SRC/material/section/FiberSection.cpp

https://code.google.com/
C++ | 596 lines | 415 code | 109 blank | 72 comment | 103 complexity | 4161fdded108e7a7bec5c2987fa34e3f MD5 | raw file
  1. /* ****************************************************************** **
  2. ** OpenSees - Open System for Earthquake Engineering Simulation **
  3. ** Pacific Earthquake Engineering Research Center **
  4. ** **
  5. ** **
  6. ** (C) Copyright 1999, The Regents of the University of California **
  7. ** All Rights Reserved. **
  8. ** **
  9. ** Commercial use of this program without express permission of the **
  10. ** University of California, Berkeley, is strictly prohibited. See **
  11. ** file 'COPYRIGHT' in main directory for information on usage and **
  12. ** redistribution, and for a DISCLAIMER OF ALL WARRANTIES. **
  13. ** **
  14. ** Developed by: **
  15. ** Frank McKenna (fmckenna@ce.berkeley.edu) **
  16. ** Gregory L. Fenves (fenves@ce.berkeley.edu) **
  17. ** Filip C. Filippou (filippou@ce.berkeley.edu) **
  18. ** **
  19. ** ****************************************************************** */
  20. // $Revision: 1.8 $
  21. // $Date: 2008-04-14 21:34:58 $
  22. // $Source: /usr/local/cvs/OpenSees/SRC/material/section/FiberSection.cpp,v $
  23. // Written: MHS
  24. // Created: Aug 2000
  25. //
  26. // Description: This file contains the class definition for
  27. // FiberSection.h. FiberSection provides the abstraction of a
  28. // section discretized by fibers. The section stiffness and
  29. // stress resultants are obtained by summing fiber contributions.
  30. #include <stdlib.h>
  31. #include <Channel.h>
  32. #include <Vector.h>
  33. #include <Matrix.h>
  34. #include <MatrixUtil.h>
  35. #include <Fiber.h>
  36. #include <classTags.h>
  37. #include <FiberSection.h>
  38. #include <ID.h>
  39. #include <FEM_ObjectBroker.h>
  40. #include <Information.h>
  41. #include <MaterialResponse.h>
  42. // constructors:
  43. FiberSection::FiberSection(int tag, int num, Fiber **fibers):
  44. SectionForceDeformation(tag, SEC_TAG_Fiber),
  45. numFibers(num), theFibers(0), sizeFibers(num),
  46. e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
  47. {
  48. theFibers = new Fiber *[numFibers];
  49. if (theFibers == 0)
  50. g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
  51. "FiberSection::FiberSection");
  52. for (int i = 0; i < numFibers; i++) {
  53. theFibers[i] = fibers[i]->getCopy();
  54. if (theFibers[i] == 0)
  55. g3ErrorHandler->fatal("%s -- failed to get copy of Fiber",
  56. "FiberSection::FiberSection");
  57. }
  58. order = theFibers[0]->getOrder();
  59. e = new Vector(order);
  60. eCommit = new Vector(order);
  61. s = new Vector(order);
  62. ks = new Matrix(order,order);
  63. code = new ID(order);
  64. *code = theFibers[0]->getType();
  65. }
  66. // constructor for blank object that recvSelf needs to be invoked upon
  67. FiberSection::FiberSection():
  68. SectionForceDeformation(0, SEC_TAG_Fiber),
  69. numFibers(0), theFibers(0), sizeFibers(0),
  70. e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
  71. {
  72. }
  73. FiberSection::FiberSection(int tag, int num):
  74. SectionForceDeformation(tag, SEC_TAG_Fiber),
  75. numFibers(0), theFibers(0), sizeFibers(num),
  76. e(0), eCommit(0), s(0), ks(0), order(0), code(0), otherDbTag(0)
  77. {
  78. // check for zero -- if zero make initial size 2
  79. if (sizeFibers == 0)
  80. sizeFibers = 2;
  81. // create the array of fiber pointers
  82. theFibers = new Fiber *[sizeFibers];
  83. if (theFibers == 0) {
  84. g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
  85. "FiberSection::FiberSection");
  86. sizeFibers = 0;
  87. }
  88. // zero the pointers
  89. for (int i = 0; i < sizeFibers; i++)
  90. theFibers[i] =0;
  91. }
  92. int
  93. FiberSection::addFiber(Fiber &newFiber)
  94. {
  95. if (order == 0) {
  96. order = newFiber.getOrder();
  97. e = new Vector(order);
  98. eCommit = new Vector(order);
  99. s = new Vector(order);
  100. ks = new Matrix(order,order);
  101. code = new ID(order);
  102. *code = newFiber.getType();
  103. }
  104. if (numFibers < sizeFibers) {
  105. // space available in array .. set new pointer and increment number
  106. theFibers[numFibers] = &newFiber;
  107. numFibers++;
  108. }
  109. else {
  110. // need to create a larger array
  111. int newSize = 2*numFibers;
  112. if (newSize == 0)
  113. newSize = 2; // in case failed in constructor
  114. Fiber **newArray = new Fiber *[newSize];
  115. if (newArray == 0) {
  116. g3ErrorHandler->fatal("%s -- failed to allocate Fiber pointers",
  117. "FiberSection::addFiber");
  118. sizeFibers = 0;
  119. return -1;
  120. }
  121. // set the new size of the array
  122. sizeFibers = newSize;
  123. // copy the old pointers
  124. for (int i = 0; i < numFibers; i++)
  125. newArray[i] = theFibers[i];
  126. // add the new pointer
  127. newArray[numFibers] = &newFiber;
  128. numFibers++;
  129. // zero the last elements of the array
  130. for (int j = numFibers; j < newSize; j++)
  131. newArray[j] = 0;
  132. delete [] theFibers;
  133. theFibers = newArray;
  134. }
  135. return 0;
  136. }
  137. // destructor:
  138. FiberSection::~FiberSection()
  139. {
  140. if (theFibers) {
  141. for (int i = 0; i < numFibers; i++)
  142. if (theFibers[i])
  143. delete theFibers[i];
  144. delete [] theFibers;
  145. }
  146. if (e)
  147. delete e;
  148. if (eCommit)
  149. delete eCommit;
  150. if (s)
  151. delete s;
  152. if (ks)
  153. delete ks;
  154. if (code)
  155. delete code;
  156. }
  157. int FiberSection::setTrialSectionDeformation (const Vector &deforms)
  158. {
  159. int res = 0;
  160. *e = deforms;
  161. for (int i = 0; i < numFibers; i++)
  162. res += theFibers[i]->setTrialFiberStrain(deforms);
  163. return res;
  164. }
  165. const Vector&
  166. FiberSection::getSectionDeformation(void)
  167. {
  168. return *e;
  169. }
  170. const Matrix&
  171. FiberSection::getSectionTangent(void)
  172. {
  173. ks->Zero();
  174. for (int i = 0; i < numFibers; i++)
  175. ks->addMatrix(1.0, theFibers[i]->getFiberTangentStiffContr(), 1.0);
  176. return *ks;
  177. }
  178. const Vector&
  179. FiberSection::getStressResultant(void)
  180. {
  181. s->Zero();
  182. for (int i = 0; i < numFibers; i++)
  183. s->addVector(1.0, theFibers[i]->getFiberStressResultants(), 1.0);
  184. return *s;
  185. }
  186. SectionForceDeformation*
  187. FiberSection::getCopy(void)
  188. {
  189. FiberSection *theCopy = new FiberSection (this->getTag(), numFibers, theFibers);
  190. *(theCopy->eCommit) = *eCommit;
  191. return theCopy;
  192. }
  193. const ID&
  194. FiberSection::getType ()
  195. {
  196. return *code;
  197. }
  198. int
  199. FiberSection::getOrder () const
  200. {
  201. return order;
  202. }
  203. int
  204. FiberSection::commitState(void)
  205. {
  206. // commit the fibers state
  207. int err = 0;
  208. for (int i = 0; i < numFibers; i++)
  209. err += theFibers[i]->commitState();
  210. *eCommit = *e;
  211. return err;
  212. }
  213. int
  214. FiberSection::revertToLastCommit(void)
  215. {
  216. int err = 0;
  217. // Last committed section deformations
  218. *e = *eCommit;
  219. s->Zero();
  220. ks->Zero();
  221. for (int i = 0; i < numFibers; i++) {
  222. // Revert the fiber ...
  223. err += theFibers[i]->revertToLastCommit();
  224. // ... now recompute the section stress resultant and tangent stiffness
  225. theFibers[i]->setTrialFiberStrain(*e);
  226. s->addVector(1.0, theFibers[i]->getFiberStressResultants(), 1.0);
  227. ks->addMatrix(1.0, theFibers[i]->getFiberTangentStiffContr(), 1.0);
  228. }
  229. return err;
  230. }
  231. int
  232. FiberSection::revertToStart(void)
  233. {
  234. // revert the fibers to start
  235. int err = 0;
  236. for (int i = 0; i < numFibers; i++)
  237. err += theFibers[i]->revertToStart();
  238. eCommit->Zero();
  239. return err;
  240. }
  241. int
  242. FiberSection::sendSelf(int commitTag, Channel &theChannel)
  243. {
  244. int res = 0;
  245. // Need two dbTags since data and dbTag ID vectors could be the same size
  246. if (otherDbTag == 0)
  247. otherDbTag = theChannel.getDbTag();
  248. // Create an ID with tag, number and size of fibers, and section order
  249. static ID data(5);
  250. data(0) = this->getTag();
  251. data(1) = numFibers;
  252. data(2) = sizeFibers;
  253. data(3) = order;
  254. data(4) = otherDbTag;
  255. // Send the data ID
  256. res += theChannel.sendID(this->getDbTag(), commitTag, data);
  257. if (res < 0) {
  258. g3ErrorHandler->warning("%s -- failed to send data ID",
  259. "FiberSection::sendSelf");
  260. return res;
  261. }
  262. if (order > 0) {
  263. // Send the committed section deformations
  264. res += theChannel.sendVector(this->getDbTag(), commitTag, *eCommit);
  265. if (res < 0) {
  266. g3ErrorHandler->warning("%s -- failed to send section deformations",
  267. "FiberSection::sendSelf");
  268. return res;
  269. }
  270. }
  271. // If there are any fibers to send ...
  272. if (numFibers > 0) {
  273. // Create an ID for fiber dbTags
  274. ID dbTags(numFibers+1);
  275. int i;
  276. int dbTag;
  277. for (i = 0; i < numFibers; i++) {
  278. dbTag = theFibers[i]->getDbTag();
  279. if (dbTag == 0) {
  280. dbTag = theChannel.getDbTag();
  281. if (dbTag != 0)
  282. theFibers[i]->setDbTag(dbTag);
  283. }
  284. dbTags(i) = dbTag;
  285. }
  286. // Get class tag from first fiber
  287. dbTags(numFibers) = theFibers[0]->getClassTag();
  288. // Send the dbTags ID
  289. res += theChannel.sendID(otherDbTag, commitTag, dbTags);
  290. if (res < 0) {
  291. g3ErrorHandler->warning("%s -- failed to send dbTags ID",
  292. "FiberSection::sendSelf");
  293. return res;
  294. }
  295. // Ask the fibers to send themselves
  296. for (i = 0; i < numFibers; i++) {
  297. res += theFibers[i]->sendSelf(commitTag, theChannel);
  298. if (res < 0) {
  299. g3ErrorHandler->warning("%s -- failed to send Fiber %d",
  300. "FiberSection::sendSelf", i);
  301. return res;
  302. }
  303. }
  304. }
  305. return res;
  306. }
  307. int
  308. FiberSection::recvSelf(int commitTag, Channel &theChannel, FEM_ObjectBroker &theBroker)
  309. {
  310. int res = 0;
  311. // Create an ID for tag, number and size of fibers, and section order
  312. static ID data(5);
  313. // Receive the data ID
  314. res += theChannel.recvID(this->getDbTag(), commitTag, data);
  315. if (res < 0) {
  316. g3ErrorHandler->warning("%s -- failed to receive data ID",
  317. "FiberSection::recvSelf");
  318. return res;
  319. }
  320. this->setTag(data(0));
  321. numFibers = data(1);
  322. sizeFibers = data(2);
  323. order = data(3);
  324. otherDbTag = data(4);
  325. // Check that section variables are of the right size, allocate if needed
  326. if (order > 0) {
  327. if (e == 0)
  328. e = new Vector(order);
  329. if (eCommit == 0)
  330. eCommit = new Vector(order);
  331. if (s == 0)
  332. s = new Vector(order);
  333. if (ks == 0)
  334. ks = new Matrix(order,order);
  335. if (code == 0)
  336. code = new ID(order);
  337. if (e->Size() != order) {
  338. delete e;
  339. e = new Vector(order);
  340. }
  341. if (eCommit->Size() != order) {
  342. delete eCommit;
  343. eCommit = new Vector(order);
  344. }
  345. if (s->Size() != order) {
  346. delete s;
  347. s = new Vector(order);
  348. }
  349. if (ks->noRows() != order) {
  350. delete ks;
  351. ks = new Matrix(order,order);
  352. }
  353. if (code->Size() != order) {
  354. delete code;
  355. code = new ID(order);
  356. }
  357. // Receive the committed section deformation
  358. res += theChannel.recvVector(this->getDbTag(), commitTag, *eCommit);
  359. if (res < 0) {
  360. g3ErrorHandler->warning("%s -- failed to receive section deformations",
  361. "FiberSection::recvSelf");
  362. return res;
  363. }
  364. *e = *eCommit;
  365. }
  366. if (numFibers > 0) {
  367. // Create an ID for fiber dbTags
  368. ID dbTags(numFibers+1);
  369. // Receive the dbTags ID
  370. res += theChannel.recvID(otherDbTag, commitTag, dbTags);
  371. if (res < 0) {
  372. g3ErrorHandler->warning("%s -- failed to receive dbTags ID",
  373. "FiberSection::recvSelf");
  374. return res;
  375. }
  376. int i;
  377. if (theFibers == 0) {
  378. theFibers = new Fiber *[sizeFibers];
  379. if (theFibers == 0) {
  380. g3ErrorHandler->warning("%s -- failed to allocate Fiber pointers",
  381. "FiberSection::recvSelf");
  382. return -1;
  383. }
  384. for (i = 0; i < sizeFibers; i++)
  385. theFibers[i] = 0;
  386. }
  387. int fiberClassTag = dbTags(numFibers);
  388. for (i = 0; i < numFibers; i++) {
  389. // Check for null fiber, allocate if so
  390. if (theFibers[i] == 0)
  391. theFibers[i] = theBroker.getNewFiber(fiberClassTag);
  392. // Check that the Fiber is of the right type; if not, delete
  393. // the current one and get a new one of the right type
  394. else if (theFibers[i]->getClassTag() != fiberClassTag) {
  395. delete theFibers[i];
  396. theFibers[i] = theBroker.getNewFiber(fiberClassTag);
  397. }
  398. // Check if either allocation failed
  399. if (theFibers[i] == 0) {
  400. g3ErrorHandler->warning("%s -- could not get Fiber %d",
  401. "FiberSection::recvSelf", i);
  402. return -1;
  403. }
  404. // Now, receive the Fiber
  405. theFibers[i]->setDbTag(dbTags(i));
  406. res += theFibers[i]->recvSelf(commitTag, theChannel, theBroker);
  407. if (res < 0) {
  408. g3ErrorHandler->warning("%s -- could not receive Fiber %d",
  409. "FiberSection::recvSelf", i);
  410. return res;
  411. }
  412. }
  413. // Reset the section code
  414. *code = theFibers[0]->getType();
  415. }
  416. //this->revertToLastCommit();
  417. return res;
  418. }
  419. void
  420. FiberSection::Print(OPS_Stream &s, int flag)
  421. {
  422. s << "\nFiberSection, tag: " << this->getTag() << endln;
  423. s << "\tSection code: " << *code;
  424. s << "\tNumber of Fibers: " << numFibers << endln;
  425. if (flag == 1)
  426. for (int i = 0; i < numFibers; i++)
  427. theFibers[i]->Print(s, flag);
  428. }
  429. Response*
  430. FiberSection::setResponse(const char **argv, int argc, OPS_Stream &output)
  431. {
  432. // See if the response is one of the defaults
  433. Response *res = SectionForceDeformation::setResponse(argv, argc, s);
  434. if (theResponse != 0)
  435. return theResponse;
  436. output.tag("SectionOutput");
  437. output.attr("secType", this->getClassType());
  438. output.attr("secTag", this->getTag());
  439. // Check if fiber response is requested
  440. else if (strcmp(argv[0],"fiber") == 0) {
  441. int key = 0;
  442. int passarg = 2;
  443. if (argc <= 2) // not enough data input
  444. return 0;
  445. else if (argc <= 3) // fiber number was input directly
  446. key = atoi(argv[1]);
  447. else { // fiber near-to coordinate specified
  448. double yCoord = atof(argv[1]);
  449. double zCoord = atof(argv[2]);
  450. double ySearch, zSearch;
  451. theFibers[0]->getFiberLocation(ySearch,zSearch);
  452. double closestDist = sqrt( pow(ySearch-yCoord,2) +
  453. pow(zSearch-zCoord,2) );
  454. double distance;
  455. for (int j = 1; j < numFibers; j++) {
  456. theFibers[j]->getFiberLocation(ySearch,zSearch);
  457. distance = sqrt( pow(ySearch-yCoord,2) +
  458. pow(zSearch-zCoord,2) );
  459. if (distance < closestDist) {
  460. closestDist = distance;
  461. key = j;
  462. }
  463. }
  464. theFibers[key]->getFiberLocation(ySearch,zSearch);
  465. passarg = 3;
  466. }
  467. if (key < numFibers && key >= 0) {
  468. output.tag("FiberOutput");
  469. double yLoc, zLoc;
  470. theFibers[key]->getFiberLocation(yLoc, zLoc);
  471. output.attr("yLoc", yLoc);
  472. output.attr("zLoc",0.0);
  473. output.attr("area", zLoc);
  474. theResponse = theFibers[key]->setResponse(&argv[passarg],argc-passarg, output);
  475. output.endTag();
  476. }
  477. }
  478. output.endTag();
  479. return theResponse;
  480. }
  481. int
  482. FiberSection::getResponse(int responseID, Information &sectInfo)
  483. {
  484. // Just call the base class method ... don't need to define
  485. // this function, but keeping it here just for clarity
  486. return SectionForceDeformation::getResponse(responseID, sectInfo);
  487. }