-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
10 changed files
with
423 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,148 @@ | ||
using Parameters | ||
using Tensors | ||
using Materials | ||
using FEMMaterials | ||
|
||
mgis_bv = MFrontInterface.behaviour | ||
|
||
""" | ||
Variables updated by MFront. | ||
""" | ||
@with_kw struct MFrontVariableState <: AbstractMaterialState | ||
stress :: SymmetricTensor{2,3} = zero(SymmetricTensor{2,3,Float64}) | ||
jacobian :: SymmetricTensor{4,3} = zero(SymmetricTensor{4,3,Float64}) | ||
end | ||
|
||
""" | ||
Variables passed in for information. | ||
These drive evolution of the material state. | ||
""" | ||
@with_kw mutable struct MFrontDriverState <: AbstractMaterialState | ||
time :: Float64 = zero(Float64) | ||
strain :: SymmetricTensor{2,3} = zero(SymmetricTensor{2,3,Float64}) | ||
end | ||
|
||
""" | ||
Material external variables in order that is specific to chosen MFront behaviour. | ||
""" | ||
@with_kw struct MFrontExternalVariableState <: AbstractMaterialState | ||
names :: Array{String,1} = [""] | ||
values :: Array{Float64,1} = zeros(Float64, 1) | ||
end | ||
|
||
""" | ||
MFront material structure. | ||
`lib_path` is the path to the compiled shared library. | ||
`behaviour` is the loaded material behaviour from the shared library. | ||
""" | ||
@with_kw mutable struct MFrontMaterial <: AbstractMaterial | ||
drivers :: MFrontDriverState = MFrontDriverState() | ||
ddrivers :: MFrontDriverState = MFrontDriverState() | ||
variables :: MFrontVariableState = MFrontVariableState() | ||
variables_new :: MFrontVariableState = MFrontVariableState() | ||
|
||
external_variables :: MFrontExternalVariableState = MFrontExternalVariableState() | ||
|
||
behaviour :: MFrontInterface.behaviour.BehaviourAllocated | ||
behaviour_data :: MFrontInterface.behaviour.BehaviourDataAllocated | ||
end | ||
|
||
function Materials.integrate_material!(material::MFrontMaterial) | ||
behaviour = material.behaviour | ||
behaviour_data = material.behaviour_data | ||
|
||
mgis_bv.set_time_increment!(behaviour_data, material.ddrivers.time) | ||
mgis_bv.revert(material.behaviour_data) | ||
|
||
# setting the external variables (like temperature) | ||
for j in 1:length(material.external_variables.names) | ||
if material.external_variables.names[j] != "" | ||
mgis_bv.set_external_state_variable!(mgis_bv.get_s1(behaviour_data), material.external_variables.names[j], material.external_variables.values[j]) | ||
end | ||
end | ||
|
||
# passing strain from material struct to the mfront interface | ||
dstrain = tovoigt(material.ddrivers.strain; offdiagscale=2.0) | ||
# now reorder from voigt 11, 22, 33, 23, 13, 12 -> 11, 22, 33, 12, 13, 23 | ||
# and use Mandel notation (scaling with sqrt(2.0)) | ||
# https://en.wikipedia.org/wiki/Voigt_notation#Mandel_notation | ||
mfront_dstrain = tovoigt(frommandel(SymmetricTensor{2, 3}, [dstrain[1], dstrain[2], dstrain[3], dstrain[6], dstrain[5], dstrain[4]])) | ||
gradients = mgis_bv.get_gradients(mgis_bv.get_final_state(behaviour_data)) | ||
for j in 1:6 | ||
gradients[j] += mfront_dstrain[j] | ||
end | ||
|
||
# tell mfront interface to calculate the tangent | ||
# if K[0] is greater than 3.5, the consistent tangent operator must be computed. | ||
dummy = zeros(36) | ||
dummy[1] = 4.0 | ||
mgis_bv.set_tangent_operator!(behaviour_data, dummy) | ||
|
||
mgis_bv.integrate(behaviour_data, behaviour) | ||
|
||
stress = [mgis_bv.get_thermodynamic_forces(mgis_bv.get_final_state(behaviour_data))[k] for k in 1:6] | ||
jacobian = reshape([mgis_bv.get_tangent_operator(behaviour_data)[k] for k in 1:36], 6, 6) | ||
|
||
# now reorder to voigt 11, 22, 33, 12, 13, 23 -> 11, 22, 33, 23, 13, 12 | ||
stress = [stress[1], stress[2], stress[3], stress[6], stress[5], stress[4]] | ||
stress = frommandel(SymmetricTensor{2, 3}, stress) | ||
|
||
r1 = jacobian[4, :] | ||
r3 = jacobian[6, :] | ||
jacobian[4, :] .= r3 | ||
jacobian[6, :] .= r1 | ||
c1 = jacobian[:, 4] | ||
c3 = jacobian[:, 6] | ||
jacobian[:, 4] .= c3 | ||
jacobian[:, 6] .= c1 | ||
jacobian = frommandel(SymmetricTensor{4, 3}, jacobian) | ||
|
||
variables_new = MFrontVariableState(stress=stress, jacobian=jacobian) | ||
material.variables_new = variables_new | ||
end | ||
|
||
function Materials.update_material!(material::MFrontMaterial) | ||
mgis_bv.update(material.behaviour_data) | ||
|
||
material.drivers += material.ddrivers | ||
material.variables = material.variables_new | ||
|
||
reset_material!(material) | ||
end | ||
|
||
function Materials.reset_material!(material::MFrontMaterial) | ||
material.ddrivers = typeof(material.ddrivers)() | ||
material.variables_new = typeof(material.variables_new)() | ||
end | ||
|
||
# other material_* functions are used from FEMMaterials | ||
|
||
import FEMMaterials: update_ip! | ||
import FEMBase: Element, Hex8 | ||
|
||
""" | ||
Initializes integration point `ip` for data storage of both `variables` and `drivers` at simulation start `time`. | ||
""" | ||
function FEMMaterials.material_preprocess_analysis!(material::MFrontMaterial, element::Element{Hex8}, ip, time) | ||
update_ip!(material, ip, time) | ||
# Read parameter values | ||
values = element("external_variables", ip, time) | ||
material.external_variables = MFrontExternalVariableState(material.external_variables.names, values) | ||
end | ||
|
||
""" | ||
Initializes integration point `ip` for data storage of both `variables` and `drivers` at simulation start `time`. | ||
Updates external variables, e.g. temperature, stored in `ip` to material | ||
""" | ||
function FEMMaterials.material_preprocess_increment!(material::MFrontMaterial, element::Element{Hex8}, ip, time) | ||
|
||
values = element("external_variables", ip, time) | ||
material.external_variables = MFrontExternalVariableState(material.external_variables.names, values) | ||
|
||
# Update time increment | ||
dtime = time - material.drivers.time | ||
material.ddrivers.time = dtime | ||
|
||
return nothing | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# This file is a part of JuliaFEM. | ||
# License is MIT: see https://github.com/JuliaFEM/MFrontInterface.jl/blob/master/LICENSE | ||
|
||
using MFrontInterface | ||
using Test | ||
using Tensors | ||
|
||
mgis_bv = MFrontInterface.behaviour | ||
|
||
function MaterialTest() | ||
lib_path = "test_plasticity/libBehaviour.so" | ||
behaviour_name = "IsotropicLinearHardeningPlasticity" | ||
hypothesis = mgis_bv.Tridimensional | ||
|
||
behaviour = load(lib_path, behaviour_name, hypothesis) | ||
behaviour_data = BehaviourData(behaviour) | ||
|
||
ext_variable_names = [mgis_bv.get_name(mgis_bv.get_external_state_variables(behaviour)[i]) for i in 1:mgis_bv.length(mgis_bv.get_external_state_variables(behaviour))] | ||
ext_variable_values = zeros(length(ext_variable_names)) | ||
ext_vatiable_state = MFrontExternalVariableState(names=ext_variable_names, values=ext_variable_values) | ||
|
||
return MFrontMaterial(behaviour=behaviour, behaviour_data=behaviour_data, external_variables=ext_vatiable_state) | ||
end | ||
|
||
mat = MaterialTest() | ||
|
||
d = mat.behaviour_data | ||
o = get_variable_offset(get_internal_state_variables(mat.behaviour), | ||
"EquivalentPlasticStrain", | ||
get_hypothesis(mat.behaviour)) | ||
|
||
dstrain_dtime = fromvoigt(SymmetricTensor{2,3,Float64}, 1e-3*[1.0, -0.3, -0.3, 0.0, 0.0, 0.0]; offdiagscale=2.0) | ||
ddrivers = MFrontDriverState(time = 0.25, strain = 0.25*dstrain_dtime) | ||
mat.ddrivers = ddrivers | ||
|
||
integrate_material!(mat) | ||
update_material!(mat) | ||
@test isapprox(mat.variables.stress, fromvoigt(SymmetricTensor{2,3}, 1.0e6*[50.0, 0.0, 0.0, 0.0, 0.0, 0.0])) | ||
|
||
mat.ddrivers = ddrivers | ||
integrate_material!(mat) | ||
update_material!(mat) | ||
@test isapprox(mat.variables.stress, fromvoigt(SymmetricTensor{2,3}, 1.0e6*[100.0, 0.0, 0.0, 0.0, 0.0, 0.0])) | ||
@test isapprox(get_internal_state_variables(get_initial_state(d))[o], 0.0; atol=1.0e-6) | ||
|
||
dstrain_dtime = fromvoigt(SymmetricTensor{2,3,Float64}, 1e-3*[1.0, -0.5, -0.5, 0.0, 0.0, 0.0]; offdiagscale=2.0) | ||
ddrivers = MFrontDriverState(time = 0.25, strain = 0.25*dstrain_dtime) | ||
mat.ddrivers = ddrivers | ||
integrate_material!(mat) | ||
update_material!(mat) | ||
@test isapprox(mat.variables.stress, fromvoigt(SymmetricTensor{2,3}, 1.0e6*[100.0, 0.0, 0.0, 0.0, 0.0, 0.0]); atol=1.0e-6) | ||
@test isapprox(get_internal_state_variables(get_initial_state(d))[o], 0.25*1.0e-3) | ||
|
||
dstrain_dtime = fromvoigt(SymmetricTensor{2,3,Float64}, -1e-3*[1.0, -0.3, -0.3, 0.0, 0.0, 0.0]; offdiagscale=2.0) | ||
ddrivers = MFrontDriverState(time = 0.25, strain = 0.25*dstrain_dtime) | ||
mat.ddrivers = ddrivers | ||
integrate_material!(mat) | ||
update_material!(mat) | ||
@test isapprox(mat.variables.stress, fromvoigt(SymmetricTensor{2,3}, 1.0e6*[50.0, 0.0, 0.0, 0.0, 0.0, 0.0]); atol=1.0e-6) | ||
|
||
dstrain_dtime = (-0.75*fromvoigt(SymmetricTensor{2,3,Float64}, 1e-3*[1.0, -0.3, -0.3, 0.0, 0.0, 0.0]; offdiagscale=2.0) | ||
-0.25*fromvoigt(SymmetricTensor{2,3,Float64}, 1e-3*[1.0, -0.5, -0.5, 0.0, 0.0, 0.0]; offdiagscale=2.0)) | ||
ddrivers = MFrontDriverState(time = 1.0, strain = dstrain_dtime) | ||
mat.ddrivers = ddrivers | ||
integrate_material!(mat) | ||
integrate_material!(mat) | ||
update_material!(mat) | ||
@test isapprox(mat.variables.stress, fromvoigt(SymmetricTensor{2,3}, 1.0e6*[-100.0, 0.0, 0.0, 0.0, 0.0, 0.0])) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# This file is a part of JuliaFEM. | ||
# License is MIT: see https://github.com/JuliaFEM/MFrontInterface.jl/blob/master/LICENSE | ||
|
||
using MFrontInterface | ||
using Test | ||
using Tensors | ||
|
||
mgis_bv = MFrontInterface.behaviour | ||
|
||
function MaterialTest() | ||
lib_path = "test_plasticity/libBehaviour.so" | ||
behaviour_name = "IsotropicLinearHardeningPlasticity" | ||
hypothesis = mgis_bv.Tridimensional | ||
|
||
behaviour = load(lib_path, behaviour_name, hypothesis) | ||
behaviour_data = BehaviourData(behaviour) | ||
|
||
ext_variable_names = [mgis_bv.get_name(mgis_bv.get_external_state_variables(behaviour)[i]) for i in 1:mgis_bv.length(mgis_bv.get_external_state_variables(behaviour))] | ||
ext_variable_values = zeros(length(ext_variable_names)) | ||
ext_vatiable_state = MFrontExternalVariableState(names=ext_variable_names, values=ext_variable_values) | ||
|
||
return MFrontMaterial(behaviour=behaviour, behaviour_data=behaviour_data, external_variables=ext_vatiable_state) | ||
end | ||
|
||
mat = MaterialTest() | ||
|
||
E = 200.0e9 | ||
nu = 0.3 | ||
syield = 100.0e6 | ||
|
||
times = [0.0] | ||
loads = [0.0] | ||
dt = 0.5 | ||
G = 0.5*E/(1+nu) | ||
|
||
ea = 2*syield/(sqrt(3)*G) | ||
# Go to elastic border | ||
push!(times, times[end]+dt) | ||
push!(loads, loads[end] + ea*dt) | ||
# Proceed to plastic flow | ||
push!(times, times[end]+dt) | ||
push!(loads, loads[end] + ea*dt) | ||
# Reverse direction | ||
push!(times, times[end]+dt) | ||
push!(loads, loads[end] - ea*dt) | ||
# Continue and pass yield criterion | ||
push!(times, times[end]+dt) | ||
push!(loads, loads[end] - 2*ea*dt) | ||
stresses = [copy(tovoigt(mat.variables.stress))] | ||
for i=2:length(times) | ||
dtime = times[i]-times[i-1] | ||
dstrain12 = loads[i]-loads[i-1] | ||
dstrain = [0.0, 0.0, 0.0, 0.0, 0.0, dstrain12] | ||
dstrain_ = fromvoigt(SymmetricTensor{2,3,Float64}, dstrain; offdiagscale=2.0) | ||
ddrivers = MFrontDriverState(time = dtime, strain = dstrain_) | ||
mat.ddrivers = ddrivers | ||
integrate_material!(mat) | ||
update_material!(mat) | ||
push!(stresses, copy(tovoigt(mat.variables.stress))) | ||
end | ||
|
||
for i in 1:length(times) | ||
@test isapprox(stresses[i][1:5], zeros(5); atol=1e-6) | ||
end | ||
s12 = [s[6] for s in stresses] | ||
|
||
s12_expected = [0.0, syield/sqrt(3.0), syield/sqrt(3.0), 0.0, -syield/sqrt(3.0)] | ||
@test isapprox(s12, s12_expected; rtol=1.0e-2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# This file is a part of JuliaFEM. | ||
# License is MIT: see https://github.com/JuliaFEM/MFrontInterface.jl/blob/master/LICENSE | ||
|
||
using MFrontInterface | ||
using Test | ||
using Materials, Tensors, FEMMaterials, FEMBase, Test | ||
|
||
mgis_bv = MFrontInterface.behaviour | ||
|
||
function MaterialTest() | ||
lib_path = "test_plasticity/libBehaviour.so" | ||
behaviour_name = "IsotropicLinearHardeningPlasticity" | ||
hypothesis = mgis_bv.Tridimensional | ||
|
||
behaviour = load(lib_path, behaviour_name, hypothesis) | ||
behaviour_data = BehaviourData(behaviour) | ||
|
||
ext_variable_names = [mgis_bv.get_name(mgis_bv.get_external_state_variables(behaviour)[i]) for i in 1:mgis_bv.length(mgis_bv.get_external_state_variables(behaviour))] | ||
ext_variable_values = zeros(length(ext_variable_names)) | ||
ext_vatiable_state = MFrontExternalVariableState(names=ext_variable_names, values=ext_variable_values) | ||
|
||
return MFrontMaterial(behaviour=behaviour, behaviour_data=behaviour_data, external_variables=ext_vatiable_state) | ||
end | ||
|
||
analysis, problem, element, bc_elements, ip = get_one_element_material_analysis(:(Main.MaterialTest)) | ||
|
||
temperature = 293.15 | ||
update!(element, "external_variables", [temperature]) | ||
|
||
times = [0.0, 1.0, 2.0, 3.0] | ||
loads = [0.0, 1.0e-3, -1.0e-3, 1.0e-3] | ||
loading = AxialStrainLoading(times, loads) | ||
update_bc_elements!(bc_elements, loading) | ||
analysis.properties.t1 = maximum(times) | ||
|
||
run!(analysis) | ||
s33 = [tovoigt(ip("stress", t))[3] for t in times] | ||
s33_expected = 1e6*[0.0, 100.0, -100.0, 100.0] | ||
@test isapprox(s33, s33_expected; rtol=1.0e-2) |
Oops, something went wrong.