Skip to content

Commit

Permalink
K4 uniaxial concrete model (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
TLCFEM authored Sep 5, 2023
1 parent f459bbc commit 749a61d
Show file tree
Hide file tree
Showing 13 changed files with 473 additions and 2 deletions.
6 changes: 6 additions & 0 deletions Enhancement/suanPan.sublime-completions
Original file line number Diff line number Diff line change
Expand Up @@ -3432,6 +3432,12 @@
"kind":"type",
"trigger":"ConcreteExp"
},
{
"contents":"material ConcreteK4 ${1:(1)} ${2:(2)} ${3:(3)} ${4:(4)} ${5:(5)} ${6:(6)} ${7:(7)} ${8:(8)} ${9:(9)} ${10:(10)} ${11:(11)} ${12:[12]} ${13:[13]}",
"details":"K4 Concrete Model",
"kind":"type",
"trigger":"ConcreteK4"
},
{
"contents":"",
"details":"",
Expand Down
2 changes: 1 addition & 1 deletion Enhancement/suanPan.sublime-syntax
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contexts:
- match: '\b(?i)(Allman|B21|B21EL|B21EH|B21H|B31|NMB21(EL|EH)|NMB31|C3D20|C3D4|C3D8|C3D8I|C3D8R|CAX3|CAX4|CAX8|CIN3D8|CINP4|Contact2D|Contact3D|CP3|CSMT3|CSMT6|CSMQ[4-8]|CP4I|CP[4-8]|Damper0[1-4]|DC3D4|DC3D8|DCP3|DCP4|DKT3|DKT4|DKTS3|DKTS4|EB21|F21|F21H|F31|GCMQ|SGCMQ|GQ12|Joint|Mass(Point)([2-3]D)|Membrane|Mindlin|MVLEM|NodeLine|NodeFacet|PatchCube|PatchQuad|PCPE4DC|PCPE4DI|PCPE8DC|PCPE4UC|PCPE8UC|PS|QE2|S4|SGCMS|SingleSection2D|SingleSection3D|Spring01|Spring02|T[2|3]D2S?|R[2|3]D2|Tie|TranslationConnector[2|3]D|Embed[2|3]D|S?GCMQ(I|L|G)?|(T|B)[2|3]D(L|C)|Embedded[2|3]D|Sleeve[2|3]D)\b'
scope: storage
# material
- match: '\b(?i)(AFC0[1-3]|AFCN|ArmstrongFrederick(1D)?|Axisymmetric(Elastic)?|Bilinear([1-2]D|CC|DP|J2|OO|PO|Peric|Hoffman)|(Bilinear|Asymm)Elastic1D|NLE1D01|BilinearMises1D|BlatzKo|BoucWen|BWBN|CDP(M2(NO|ISO|ANISO)?)?|Concrete2[1-2]|Concrete(CM|Tsai|Exp)|CoulombFriction|Custom(StressDegradation|StrainDegradation|Elastic1D|J2|DP|Hoffman|Mises1D|CC)|CustomGurson(1D)?|DafaliasManzari|Degradation|Elastic(1|2)D|Exp(CC|DP|Gurson|Gurson1D|Hoffman|J2|Mises1D)|Flag0(1|2)|Fluid|IsotropicDamage|Isotropic(Nonlinear)?Elastic3D|Kelvin|Laminated|LinearDamage|Maxwell|Metal|Mises1D|MooneyRivlin|MPF|Multilinear((Elastic)?1D|J2|OO|PO)|NLE3D01|OrthotropicElastic3D|ParabolicCC|Parallel|PlaneStrain|PlaneSymmetric(1|2)3|PlaneStress|PolyJ2|RambergOsgood|Rebar[2|3]D|Sequential|SimpleSand|SlipLock|Stacked|SteelBRB|TableCDP|TimberPD|Trivial|Uniaxial|VAFCRP(1D)?|Viscosity0(1|2)|Yeoh|Elastic3D|TrilinearStrainDegradation|TableGurson|Substepping|PolyElastic1D|Rotation[2|3]D|MultilinearMises1D|Gap01|Dhakal|ConcreteTable|BilinearViscosity|Sinh1D|Tanh1D|SimpleScalar)\b'
- match: '\b(?i)(AFC0[1-3]|AFCN|ArmstrongFrederick(1D)?|Axisymmetric(Elastic)?|Bilinear([1-2]D|CC|DP|J2|OO|PO|Peric|Hoffman)|(Bilinear|Asymm)Elastic1D|NLE1D01|BilinearMises1D|BlatzKo|BoucWen|BWBN|CDP(M2(NO|ISO|ANISO)?)?|Concrete2[1-2]|Concrete(CM|Tsai|Exp|K4)|CoulombFriction|Custom(StressDegradation|StrainDegradation|Elastic1D|J2|DP|Hoffman|Mises1D|CC)|CustomGurson(1D)?|DafaliasManzari|Degradation|Elastic(1|2)D|Exp(CC|DP|Gurson|Gurson1D|Hoffman|J2|Mises1D)|Flag0(1|2)|Fluid|IsotropicDamage|Isotropic(Nonlinear)?Elastic3D|Kelvin|Laminated|LinearDamage|Maxwell|Metal|Mises1D|MooneyRivlin|MPF|Multilinear((Elastic)?1D|J2|OO|PO)|NLE3D01|OrthotropicElastic3D|ParabolicCC|Parallel|PlaneStrain|PlaneSymmetric(1|2)3|PlaneStress|PolyJ2|RambergOsgood|Rebar[2|3]D|Sequential|SimpleSand|SlipLock|Stacked|SteelBRB|TableCDP|TimberPD|Trivial|Uniaxial|VAFCRP(1D)?|Viscosity0(1|2)|Yeoh|Elastic3D|TrilinearStrainDegradation|TableGurson|Substepping|PolyElastic1D|Rotation[2|3]D|MultilinearMises1D|Gap01|Dhakal|ConcreteTable|BilinearViscosity|Sinh1D|Tanh1D|SimpleScalar)\b'
scope: storage
# section
- match: '\b(?i)(Bar[2|3]D|Box[2|3]D|Circle[1-3]D|CircularHollow[2|3]D|EU[2|3]D|Fibre[1-3]D|HSection2D|ISection[2|3]D|NM[2|3]D[1-3]|NM[2|3]D3K|NZ[2|3]D|Rectangle[1-3]D|TrussSection|TSection[2-3]D|US[2|3]D)\b'
Expand Down
59 changes: 59 additions & 0 deletions Example/Material/ConcreteK4.supan
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# A TEST MODEL FOR CONCRETEK4 MATERIAL

node 1 0 0
node 2 3 0
node 3 6 0

material ConcreteK4 1 3E4 .05 .01 .01 3. 30. 2E-3 .7 2E-3 2E-3
element T2D2 1 1 2 1 10
element T2D2 2 3 2 1 10

fix2 1 P 1
fix2 2 2 2 3

hdf5recorder 1 Element E 1
hdf5recorder 2 Element S 1

step static 1
set ini_step_size 1E-2
set fixed_step_size 1

displacement 1 0 .002 1 3
converger RelIncreDisp 1 1E-8 10 1

step static 2
set ini_step_size 1E-1
set fixed_step_size 1

displacement 2 0 -.025 1 3

step static 3
set ini_step_size 1E-2
set fixed_step_size 1

displacement 3 0 .01 1 3

step static 4
set ini_step_size 1E-2
set fixed_step_size 1

displacement 4 0 -.02 1 3

analyze

# Node 3:
# Coordinate:
# 6.0000e+00 0.0000e+00
# Displacement:
# -3.3000e-02 0.0000e+00
# Resistance:
# -8.9176e+01 0.0000e+00
peek node 3

peek element 1 2

save recorder 1 2

reset
clear
exit
2 changes: 2 additions & 0 deletions MSVC/suanPan/suanPan/suanPan.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@
<ClCompile Include="..\..\..\Material\Material.cpp" />
<ClCompile Include="..\..\..\Material\Material1D\Concrete\ConcreteCM.cpp" />
<ClCompile Include="..\..\..\Material\Material1D\Concrete\ConcreteExp.cpp" />
<ClCompile Include="..\..\..\Material\Material1D\Concrete\NonlinearK4.cpp" />
<ClCompile Include="..\..\..\Material\Material1D\Concrete\ConcreteTable.cpp" />
<ClCompile Include="..\..\..\Material\Material1D\Concrete\ConcreteTsai.cpp" />
<ClCompile Include="..\..\..\Material\Material1D\Degradation\CustomStrainDegradation.cpp" />
Expand Down Expand Up @@ -765,6 +766,7 @@
<ClInclude Include="..\..\..\Material\Material.h" />
<ClInclude Include="..\..\..\Material\Material1D\Concrete\ConcreteCM.h" />
<ClInclude Include="..\..\..\Material\Material1D\Concrete\ConcreteExp.h" />
<ClInclude Include="..\..\..\Material\Material1D\Concrete\NonlinearK4.h" />
<ClInclude Include="..\..\..\Material\Material1D\Concrete\ConcreteTable.h" />
<ClInclude Include="..\..\..\Material\Material1D\Concrete\ConcreteTsai.h" />
<ClInclude Include="..\..\..\Material\Material1D\Degradation\CustomStrainDegradation.h" />
Expand Down
6 changes: 6 additions & 0 deletions MSVC/suanPan/suanPan/suanPan.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,9 @@
<ClCompile Include="..\..\..\Material\Material1D\Degradation\CustomStressDegradation.cpp">
<Filter>Material\Material1D\Degradation</Filter>
</ClCompile>
<ClCompile Include="..\..\..\Material\Material1D\Concrete\NonlinearK4.cpp">
<Filter>Material\Material1D\Concrete</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\Constraint\BC\GroupMultiplierBC.h">
Expand Down Expand Up @@ -2911,6 +2914,9 @@
<ClInclude Include="..\..\..\Material\Material1D\Degradation\CustomStressDegradation.h">
<Filter>Material\Material1D\Degradation</Filter>
</ClInclude>
<ClInclude Include="..\..\..\Material\Material1D\Concrete\NonlinearK4.h">
<Filter>Material\Material1D\Concrete</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\Resource\suanPan.rc" />
Expand Down
2 changes: 1 addition & 1 deletion MSVC/suanPan/suanPan/suanPan.vcxproj.user
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<ShowAllFiles>false</ShowAllFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>-f Degradation</LocalDebuggerCommandArguments>
<LocalDebuggerCommandArguments>-f ConcreteK4</LocalDebuggerCommandArguments>
<LocalDebuggerWorkingDirectory>..\..\..\Example\Material</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
Expand Down
1 change: 1 addition & 0 deletions Material/Material1D/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ set(M1D
Material1D/Concrete/ConcreteExp.cpp
Material1D/Concrete/ConcreteTable.cpp
Material1D/Concrete/ConcreteTsai.cpp
Material1D/Concrete/NonlinearK4.cpp
Material1D/Degradation/CustomStrainDegradation.cpp
Material1D/Degradation/CustomStressDegradation.cpp
Material1D/Degradation/Degradation.cpp
Expand Down
251 changes: 251 additions & 0 deletions Material/Material1D/Concrete/NonlinearK4.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,251 @@
/*******************************************************************************
* Copyright (C) 2017-2023 Theodore Chang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/

#include "NonlinearK4.h"
#include <Toolbox/utility.h>

int NonlinearK4::compute_tension_branch() {
auto& plastic_strain = trial_history(0);
auto& kt = trial_history(1);

const auto sign_sigma = suanpan::sign(trial_stress(0));

auto counter = 0u;
while(true) {
if(max_iteration == ++counter) {
suanpan_error("Cannot converge within {} iterations.\n", max_iteration);
return SUANPAN_FAIL;
}

const auto backbone = compute_tension_backbone(kt);
const auto residual = fabs(trial_stress(0)) - backbone(0);

if(1u == counter && residual <= 0.) {
if(apply_damage) {
const auto damage = compute_tension_damage(kt);
const auto damage_factor = 1. - damage(0);

trial_stress *= damage_factor;
trial_stiffness *= damage_factor;
}

return SUANPAN_SUCCESS;
}

const double jacobian = elastic_modulus + backbone(1);
const auto incre = residual / jacobian;
const auto error = fabs(incre);
suanpan_debug("Local tension iteration error: {:.5E}.\n", error);
if(error < tolerance || fabs(residual) < tolerance) {
const auto dgamma = elastic_modulus / jacobian;
trial_stiffness -= dgamma * elastic_modulus;

if(apply_damage) {
const auto damage = compute_tension_damage(kt);
const auto damage_factor = 1. - damage(0);

trial_stiffness *= damage_factor;
trial_stiffness -= trial_stress * damage(1) * dgamma;

trial_stress *= damage_factor;
}

return SUANPAN_SUCCESS;
}

const auto incre_ep = incre * sign_sigma;

kt += incre;
plastic_strain += incre_ep;
trial_stress -= elastic_modulus * incre_ep;
}
}

int NonlinearK4::compute_compression_branch() {
auto& plastic_strain = trial_history(0);
auto& kc = trial_history(2);

const auto sign_sigma = suanpan::sign(trial_stress(0));

auto counter = 0u;
while(true) {
if(max_iteration == ++counter) {
suanpan_error("Cannot converge within {} iterations.\n", max_iteration);
return SUANPAN_FAIL;
}

const auto backbone = compute_compression_backbone(kc);
const auto residual = fabs(trial_stress(0)) - backbone(0);

if(1u == counter && residual <= 0.) {
if(apply_damage) {
const auto damage = compute_compression_damage(kc);
const auto damage_factor = 1. - damage(0);

trial_stress *= damage_factor;
trial_stiffness *= damage_factor;
}

return SUANPAN_SUCCESS;
}

const double jacobian = elastic_modulus + backbone(1);
const auto incre = residual / jacobian;
const auto error = fabs(incre);
suanpan_debug("Local compression iteration error: {:.5E}.\n", error);
if(error < tolerance || fabs(residual) < tolerance) {
const auto dgamma = elastic_modulus / jacobian;
trial_stiffness -= dgamma * elastic_modulus;

if(apply_damage) {
const auto damage = compute_compression_damage(kc);
const auto damage_factor = 1. - damage(0);

trial_stiffness *= damage_factor;
trial_stiffness -= trial_stress * damage(1) * dgamma;

trial_stress *= damage_factor;
}

return SUANPAN_SUCCESS;
}

const auto incre_ep = incre * sign_sigma;

kc += incre;
plastic_strain += incre_ep;
trial_stress -= elastic_modulus * incre_ep;
}
}

int NonlinearK4::compute_crack_close_branch() {
auto& plastic_strain = trial_history(0);
const auto& kt = trial_history(1);
auto& kk = trial_history(3);

const auto jacobian = elastic_modulus + hardening_k;

// account for entering
const auto net_strain = fabs(incre_strain(0)) - std::max(0., current_stress(0)) / elastic_modulus;
const auto dgamma = elastic_modulus / jacobian;
auto incre = net_strain * dgamma;

// physically, the tension plastic strain is the crack opening, closing the crack should not exceed the opening
// ensure the crack plastic strain is bounded by the tension plastic strain
if(incre > kt - kk) incre = kt - kk;
else trial_stiffness -= dgamma * elastic_modulus; // otherwise, the stiffness is degraded during the closing phase

const auto incre_ep = incre * suanpan::sign(trial_stress(0));

kk += incre;
plastic_strain += incre_ep;
trial_stress -= elastic_modulus * incre_ep;

return SUANPAN_SUCCESS;
}

NonlinearK4::NonlinearK4(const unsigned T, const double E, const double H, const double L, const double R)
: DataNonlinearK4{fabs(E), std::min(1., std::max(fabs(H), 1E-4)) * fabs(E)}
, Material1D(T, R) { characteristic_length = fabs(L); }

int NonlinearK4::initialize(const shared_ptr<DomainBase>&) {
trial_stiffness = current_stiffness = initial_stiffness = elastic_modulus;

initialize_history(4);

return SUANPAN_SUCCESS;
}

double NonlinearK4::get_parameter(const ParameterType P) const {
if(ParameterType::DENSITY == P) return density;
if(ParameterType::ELASTICMODULUS == P || ParameterType::YOUNGSMODULUS == P || ParameterType::E == P) return initial_stiffness(0);
return 0.;
}

int NonlinearK4::update_trial_status(const vec& n_strain) {
incre_strain = (trial_strain = n_strain) - current_strain;

if(fabs(incre_strain(0)) <= tolerance) return SUANPAN_SUCCESS;

trial_history = current_history;
const auto& plastic_strain = trial_history(0);
const auto& current_kt = current_history(1);
const auto& current_kk = current_history(3);

trial_stress = (trial_stiffness = elastic_modulus) * (trial_strain - plastic_strain);

if(trial_stress(0) < 0. && incre_strain(0) < 0. && current_kt > current_kk && SUANPAN_SUCCESS != compute_crack_close_branch()) return SUANPAN_FAIL;

return trial_stress(0) > 0. ? compute_tension_branch() : compute_compression_branch();
}

int NonlinearK4::clear_status() {
current_strain.zeros();
current_stress.zeros();
current_history = initial_history;
current_stiffness = initial_stiffness;
return reset_status();
}

int NonlinearK4::commit_status() {
current_strain = trial_strain;
current_stress = trial_stress;
current_history = trial_history;
current_stiffness = trial_stiffness;
return SUANPAN_SUCCESS;
}

int NonlinearK4::reset_status() {
trial_strain = current_strain;
trial_stress = current_stress;
trial_history = current_history;
trial_stiffness = current_stiffness;
return SUANPAN_SUCCESS;
}

void NonlinearK4::print() {
suanpan_info("A concrete model. doi: 10.1061/(ASCE)ST.1943-541X.000259\n");
Material1D::print();
}

vec2 ConcreteK4::compute_tension_backbone(const double k) const { return vec2{f_t + hardening_t * k, hardening_t}; }

vec2 ConcreteK4::compute_compression_backbone(const double k) const {
if(k < k_peak) return vec2{f_y + hardening_c * k, hardening_c};

return vec2{f_c + hardening_d * (k - k_peak), hardening_d};
}

vec2 ConcreteK4::compute_tension_damage(const double k) const {
const auto factor = exp(-k / ref_e_t / characteristic_length);
return vec2{1. - factor, factor / ref_e_t / characteristic_length};
}

vec2 ConcreteK4::compute_compression_damage(double k) const {
if(k < k_peak) return vec2{0., 0.};

k -= k_peak;

const auto factor = exp(-k / ref_e_c / characteristic_length);
return vec2{1. - factor, factor / ref_e_c / characteristic_length};
}

ConcreteK4::ConcreteK4(const unsigned T, const double E, const double H, vec&& P, const double L, const double R)
: DataConcreteK4{fabs(E * P(0)), fabs(E * P(1)), perturb(fabs(P(2))), fabs(P(3)), fabs(P(4)), fabs(P(3) * P(5)), fabs(P(6)), fabs(P(7))}
, NonlinearK4(T, E, H, L, R) {}

unique_ptr<Material> ConcreteK4::get_copy() { return make_unique<ConcreteK4>(*this); }
Loading

0 comments on commit 749a61d

Please sign in to comment.