The SectionAggregator was one of my few useful OpenSees ideas. This class gives a flexible way to combine, or aggregate, modes of force-deformation in a single section model.
The idea for SectionAggregator came from the Decorator software design pattern, the same pattern from which so many UniaxialMaterial wrappers were spawned (here and here). In fact, SectionDecorator was the working title for what would become SectionAggregator.
The need for SectionAggregator came from using force-based frame elements to model shear in reinforced concrete columns. With these elements, flexure and shear are coupled through element equilibrium, so adding a nonlinear shear force-deformation relationship to a fiber section will couple flexural and shear effects. Not as pure as coupling at the material level, but it gets the job done.
In general, there are two use cases for the SectionAggregator: 1) combine modes of force-deformation with a pre-existing section model; and 2) combine modes of force-deformation into a new section model. In both cases, all of the aggregated modes are uncoupled from each other and uncoupled from the pre-existing section. A UniaxialMaterial object represents each mode of force-deformation.
Combine uniaxial materials with a section
The first use case adds modes of force-deformation response to a pre-defined section model, e.g., the aforementioned example of fiber section plus shear.
You first define your base section and uniaxialMaterial, then aggregate the objects into a new section. To indicate the mode of force-deformation, the aggregated materials are assigned a code:
T. We’ll add more codes for warping elements, new and old.
ops.section('Fiber',1) ops.patch(...) ops.layer(...) ops.uniaxialMaterial('WhateverYouWant', shearTag, parameters...) ops.section('Aggregator',2,shearTag,'Vy','-section',1)
Before moving on to 3D considerations and the second use case, here are some random bullets to consider with respect to the SectionAggregator in general:
- You can aggregate whatever UniaxialMaterials you want–Elastic, Hardening, Hysteretic, etc. Heck, although it wouldn’t make any sense and you may encounter convergence issues, you can aggregate Concrete23 as an additional mode of section force-deformation.
- The section to which the uniaxial materials are aggregated can be any section you like, not just a fiber section. You can aggregate to an elastic section, which is useful for testing and debugging models, a stress resultant plasticity model, or one of the “canned” fiber section models, e.g., WFSection2d or RCSection2d.
- When aggregating to a fiber section, you are adding force-deformation to the section, not stress-strain to the fibers. For example, to aggregate linear-elastic shear to a fiber section, you would use an Elastic uniaxial material with stiffness GAv, not G.
Specific to 3D analysis, until this recent change in FiberSection3d, you had to use a SectionAggregator to attach torsional response to the section so that the force-based element wouldn’t try to invert a singular flexibility matrix. Now, as described in the post, that aggregation is handled internally, i.e., the FiberSection3d is P–Mz–My–T out of the box.
With torsion taken care of, you can aggregate modes of shear force-deformation to FiberSection3d as well–one in each direction or only one in one direction. I tried to make a figure for 3D aggregation, but it got a little messy, so here’s code instead.
ops.uniaxialMaterial('WhateverYouWant', torsionTag, parameters...) ops.section('Fiber',3,'-torsion',torsionTag) # or ops.section('Fiber',3,'-GJ',GJ) ops.patch(...) ops.layer(...) ops.uniaxialMaterial('WhateverYouWant', shearTag, parameters...) # Define another uniaxial material if you want Vy and Vz to be different ops.section('Aggregator',4,shearTag,'Vy',shearTag,'Vz','-section',3)
Combine uniaxial materials into a new section
The second use case for SectionAggregator is to derive all modes of section response from only uniaxial materials without an underlying section. For example, you can define uniaxial moment-curvature for a section, combined with axial force-deformation response, and potentially shear force-deformation response.
ops.uniaxialMaterial('WhateverYouWant', axialTag, parameters...) ops.uniaxialMaterial('WhateverYouWant', flexuralTag, parameters...) ops.uniaxialMaterial('WhateverYouWant', shearTag, parameters...) ops.section('Aggregator',5,axialTag,'P',flexuralTag,'Mz',shearTag,'Vy')
For 3D models, you can aggregate axial, flexure, shear, and torsion from disparate uniaxial materials.
ops.uniaxialMaterial('WhateverYouWant', axialTag, parameters...) ops.uniaxialMaterial('WhateverYouWant', flexuralTag, parameters...) ops.uniaxialMaterial('WhateverYouWant', shearTag, parameters...) ops.uniaxialMaterial('WhateverYouWant', torsionTag, parameters...) # Define other uniaxial materials if you want My and Mz and/or Vy and Vz to be different ops.section('Aggregator',6,torsionTag,'T',axialTag,'P',flexuralTag,'Mz',shearTag,'Vy',flexuralTag,'My',shearTag,'Vz')
You can put the aggregated uniaxial materials in any order you want–I intentionally put torsion first in the example code above. The beam-column elements (2D and 3D, force-based, displacement-based, and mixed) have switch statements to figure out which modes to use and in what order. For example, in ForceBeamColumn3D, you’ll see code like below.
Although not shown here, the displacement-based and mixed elements do not account for shear and will simply ignore section shear response, whether it’s from SectionAggregator or something else, like an NDFiberSection. The cases for Vy and Vz are missing from the switch statements for these elements.
So, to wrap it up, you can combine anything you want in a SectionAggregator. I can’t show all combinations, but it should be apparent that the SectionAggregator mitigates a lot of unnecessary code duplication.