From c4ad60acc342f9fd8dc2a37d7f04da4b6708c7d6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 2 May 2020 16:03:53 +0000 Subject: [PATCH 01/16] CompatHelper: bump compat for "Polynomials" to "1.0" --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 3cb03b1..ca3be94 100644 --- a/Project.toml +++ b/Project.toml @@ -17,7 +17,7 @@ Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" ConstructionBase = "1.0" IterTools = "1.2, 1.3" LsqFit = "0.8, 0.9, 0.10" -Polynomials = "0.5.2, 0.6, 0.7, 0.8" +Polynomials = "0.5.2, 0.6, 0.7, 0.8, 1.0" Roots = "0.8, 1.0" Unitful = "0.18, 1.0" julia = "1" From af1daa33d40896f4a24f43bca1a7a02c23264d0b Mon Sep 17 00:00:00 2001 From: singularitti Date: Wed, 6 May 2020 07:17:40 -0400 Subject: [PATCH 02/16] Merge src/FiniteStrains.jl to src/LinearFitting.jl --- src/FiniteStrains.jl | 22 ---------------------- src/LinearFitting.jl | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 24 deletions(-) delete mode 100644 src/FiniteStrains.jl diff --git a/src/FiniteStrains.jl b/src/FiniteStrains.jl deleted file mode 100644 index 598f870..0000000 --- a/src/FiniteStrains.jl +++ /dev/null @@ -1,22 +0,0 @@ -""" -This module provides some `FiniteStrain` types and `getstrain` methods to -calculate various strains. -""" -module FiniteStrains - -export FiniteStrain, - EulerianStrain, LagrangianStrain, NaturalStrain, InfinitesimalStrain, getstrain - -abstract type FiniteStrain end - -struct EulerianStrain <: FiniteStrain end -struct LagrangianStrain <: FiniteStrain end -struct NaturalStrain <: FiniteStrain end -struct InfinitesimalStrain <: FiniteStrain end - -getstrain(::EulerianStrain, v0::Real, v::Real) = (cbrt(v0 / v)^2 - 1) / 2 -getstrain(::LagrangianStrain, v0::Real, v::Real) = (cbrt(v / v0)^2 - 1) / 2 -getstrain(::NaturalStrain, v0::Real, v::Real) = log(v / v0) / 3 -getstrain(::InfinitesimalStrain, v0::Real, v::Real) = 1 - cbrt(v0 / v) - -end diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 66e2d3d..34847f7 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -7,8 +7,8 @@ using LinearAlgebra: dot using Polynomials: polyder, degree, coeffs, Poly using Polynomials.PolyCompat: polyfit -using ..FiniteStrains - +export FiniteStrain, + EulerianStrain, LagrangianStrain, NaturalStrain, InfinitesimalStrain, getstrain export energy_strain_expansion, energy_strain_derivative, strain_volume_derivative, @@ -16,6 +16,18 @@ export energy_strain_expansion, energy_volume_derivatives, energy_volume_derivative_at_order +abstract type FiniteStrain end + +struct EulerianStrain <: FiniteStrain end +struct LagrangianStrain <: FiniteStrain end +struct NaturalStrain <: FiniteStrain end +struct InfinitesimalStrain <: FiniteStrain end + +getstrain(::EulerianStrain, v0::Real, v::Real) = (cbrt(v0 / v)^2 - 1) / 2 +getstrain(::LagrangianStrain, v0::Real, v::Real) = (cbrt(v / v0)^2 - 1) / 2 +getstrain(::NaturalStrain, v0::Real, v::Real) = log(v / v0) / 3 +getstrain(::InfinitesimalStrain, v0::Real, v::Real) = 1 - cbrt(v0 / v) + energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int)::Poly = polyfit(f, e, n) From 80c5417b30502e4a8bb92bbb91ed4b558c088611 Mon Sep 17 00:00:00 2001 From: singularitti Date: Wed, 6 May 2020 07:20:48 -0400 Subject: [PATCH 03/16] Deprecate `getstrain` using functors --- src/EquationsOfState.jl | 1 - src/LinearFitting.jl | 15 +++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/EquationsOfState.jl b/src/EquationsOfState.jl index e3bfedc..093a224 100644 --- a/src/EquationsOfState.jl +++ b/src/EquationsOfState.jl @@ -2,7 +2,6 @@ module EquationsOfState include("Collections.jl") include("NonlinearFitting.jl") -include("FiniteStrains.jl") include("LinearFitting.jl") include("Find.jl") diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 34847f7..5653feb 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -7,8 +7,7 @@ using LinearAlgebra: dot using Polynomials: polyder, degree, coeffs, Poly using Polynomials.PolyCompat: polyfit -export FiniteStrain, - EulerianStrain, LagrangianStrain, NaturalStrain, InfinitesimalStrain, getstrain +export FiniteStrain, EulerianStrain, LagrangianStrain, NaturalStrain, InfinitesimalStrain export energy_strain_expansion, energy_strain_derivative, strain_volume_derivative, @@ -23,10 +22,10 @@ struct LagrangianStrain <: FiniteStrain end struct NaturalStrain <: FiniteStrain end struct InfinitesimalStrain <: FiniteStrain end -getstrain(::EulerianStrain, v0::Real, v::Real) = (cbrt(v0 / v)^2 - 1) / 2 -getstrain(::LagrangianStrain, v0::Real, v::Real) = (cbrt(v / v0)^2 - 1) / 2 -getstrain(::NaturalStrain, v0::Real, v::Real) = log(v / v0) / 3 -getstrain(::InfinitesimalStrain, v0::Real, v::Real) = 1 - cbrt(v0 / v) +(::EulerianStrain)(v0, v) = (cbrt(v0 / v)^2 - 1) / 2 +(::LagrangianStrain)(v0, v) = (cbrt(v / v0)^2 - 1) / 2 +(::NaturalStrain)(v0, v) = log(v / v0) / 3 +(::InfinitesimalStrain)(v0, v) = 1 - cbrt(v0 / v) energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int)::Poly = polyfit(f, e, n) @@ -46,7 +45,7 @@ function strain_volume_derivative(s::NaturalStrain, v0::Real, v::Real, m::Int) -m / v * strain_volume_derivative(s, v0, v, m - 1) end function strain_volume_derivative(s::InfinitesimalStrain, v0::Real, v::Real, m::Int) - m == 1 && return (1 - getstrain(s, v0, v))^4 / 3 / v0 + m == 1 && return (1 - s(v0, v))^4 / 3 / v0 -(3m + 1) / (3v) * strain_volume_derivative(s, v0, v, m - 1) end @@ -60,7 +59,7 @@ function energy_volume_expansion( # The zeroth order value plus values from the first to the ``highest_order`. p(v) + dot( energy_volume_derivatives(s, v0, v, p, highest_order), - getstrain(s, v0, v) .^ collect(1:highest_order), + s(v0, v) .^ collect(1:highest_order), ) end From d874630c418059831ec8af60accb085eb4d3310f Mon Sep 17 00:00:00 2001 From: singularitti Date: Wed, 6 May 2020 07:32:29 -0400 Subject: [PATCH 04/16] Relax type constraints as suggested in https://white.ucc.asn.au/2020/04/19/Julia-Antipatterns.html --- src/LinearFitting.jl | 61 +++++++++++++++++--------------------------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 5653feb..c61caa1 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -4,8 +4,8 @@ This module provides some linear fitting methods. module LinearFitting using LinearAlgebra: dot -using Polynomials: polyder, degree, coeffs, Poly -using Polynomials.PolyCompat: polyfit +using Polynomials: degree, coeffs +using Polynomials.PolyCompat: polyfit, polyder, Poly export FiniteStrain, EulerianStrain, LagrangianStrain, NaturalStrain, InfinitesimalStrain export energy_strain_expansion, @@ -27,35 +27,28 @@ struct InfinitesimalStrain <: FiniteStrain end (::NaturalStrain)(v0, v) = log(v / v0) / 3 (::InfinitesimalStrain)(v0, v) = 1 - cbrt(v0 / v) -energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int)::Poly = - polyfit(f, e, n) +energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int) = polyfit(f, e, n) -energy_strain_derivative(p::Poly, m::Int)::Poly = polyder(p, m) +energy_strain_derivative(p::Poly, deg) = polyder(p, deg) -function strain_volume_derivative(s::EulerianStrain, v0::Real, v::Real, m::Int) - m == 1 && return -1 / (3v) * cbrt(v0 / v)^2 - -(3m + 2) / (3v) * strain_volume_derivative(s, v0, v, m - 1) +function strain_volume_derivative(s::EulerianStrain, v0, v, deg) + deg == 1 && return -1 / (3v) * cbrt(v0 / v)^2 + -(3deg + 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) end -function strain_volume_derivative(s::LagrangianStrain, v0::Real, v::Real, m::Int) - m == 1 && return -1 / (3v) * cbrt(v / v0)^2 - -(3m - 2) / (3v) * strain_volume_derivative(s, v0, v, m - 1) +function strain_volume_derivative(s::LagrangianStrain, v0, v, deg) + deg == 1 && return -1 / (3v) * cbrt(v / v0)^2 + -(3deg - 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) end -function strain_volume_derivative(s::NaturalStrain, v0::Real, v::Real, m::Int) - m == 1 && return 1 / (3v) - -m / v * strain_volume_derivative(s, v0, v, m - 1) +function strain_volume_derivative(s::NaturalStrain, v0, v, deg) + deg == 1 && return 1 / (3v) + -deg / v * strain_volume_derivative(s, v0, v, deg - 1) end -function strain_volume_derivative(s::InfinitesimalStrain, v0::Real, v::Real, m::Int) - m == 1 && return (1 - s(v0, v))^4 / 3 / v0 - -(3m + 1) / (3v) * strain_volume_derivative(s, v0, v, m - 1) +function strain_volume_derivative(s::InfinitesimalStrain, v0, v, deg) + deg == 1 && return (1 - s(v0, v))^4 / 3 / v0 + -(3deg + 1) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) end -function energy_volume_expansion( - s::FiniteStrain, - v0::Real, - v::Real, - p::Poly, - highest_order::Int = degree(p), -) +function energy_volume_expansion(s::FiniteStrain, v0, v, p::Poly, highest_order = degree(p)) # The zeroth order value plus values from the first to the ``highest_order`. p(v) + dot( energy_volume_derivatives(s, v0, v, p, highest_order), @@ -63,13 +56,7 @@ function energy_volume_expansion( ) end -function energy_volume_derivatives( - s::FiniteStrain, - v0::Real, - v::Real, - p::Poly, - highest_order::Int, -) +function energy_volume_derivatives(s::FiniteStrain, v0, v, p::Poly, highest_order) 0 ≤ highest_order ≤ degree(p) ? (x = 1:highest_order) : throw(DomainError("The `highest_order` must be within 0 to $(degree(p))!")) strain_derivatives = map(m -> strain_volume_derivative(s, v0, v, m), x) @@ -80,21 +67,21 @@ function energy_volume_derivatives( ) end -function energy_volume_derivative_at_order(m::Int)::Function +function energy_volume_derivative_at_order(deg) function (f::Vector{<:Real}, e::Vector{<:Real}) - if m == 1 + if deg == 1 e[1] * f[1] - elseif m == 2 + elseif deg == 2 e[2] * f[1]^2 + e[1] * f[1] - elseif m == 3 + elseif deg == 3 e[3] * f[1]^3 + 3 * f[1] * f[2] * e[2] + e[1] * f[3] - elseif m == 4 + elseif deg == 4 e[4] * f[1]^4 + 6 * f[1]^2 * f[2] * e[3] + (4 * f[1] * f[3] + 3 * f[3]^2) * e[2] + e[1] * f[3] else - error("Expansion is not defined at order = $(m)!") + error("Expansion is not defined at order = $(deg)!") end end end From 4700d80f20a106239fbfaa54d18af5c8d98a2b83 Mon Sep 17 00:00:00 2001 From: singularitti Date: Wed, 6 May 2020 07:47:01 -0400 Subject: [PATCH 05/16] Restyle code using Yin Wang's style --- src/LinearFitting.jl | 40 ++++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index c61caa1..a6974a1 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -32,25 +32,37 @@ energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int) = polyfit( energy_strain_derivative(p::Poly, deg) = polyder(p, deg) function strain_volume_derivative(s::EulerianStrain, v0, v, deg) - deg == 1 && return -1 / (3v) * cbrt(v0 / v)^2 - -(3deg + 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) + if deg == 1 + return -1 / (3v) * cbrt(v0 / v)^2 + else # Recursion + return -(3deg + 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) + end end function strain_volume_derivative(s::LagrangianStrain, v0, v, deg) - deg == 1 && return -1 / (3v) * cbrt(v / v0)^2 - -(3deg - 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) + if deg == 1 + return -1 / (3v) * cbrt(v / v0)^2 + else # Recursion + return -(3deg - 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) + end end function strain_volume_derivative(s::NaturalStrain, v0, v, deg) - deg == 1 && return 1 / (3v) - -deg / v * strain_volume_derivative(s, v0, v, deg - 1) + if deg == 1 + return 1 / (3v) + else # Recursion + return -deg / v * strain_volume_derivative(s, v0, v, deg - 1) + end end function strain_volume_derivative(s::InfinitesimalStrain, v0, v, deg) - deg == 1 && return (1 - s(v0, v))^4 / 3 / v0 - -(3deg + 1) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) + if deg == 1 + return (1 - s(v0, v))^4 / 3 / v0 + else # Recursion + return -(3deg + 1) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) + end end function energy_volume_expansion(s::FiniteStrain, v0, v, p::Poly, highest_order = degree(p)) # The zeroth order value plus values from the first to the ``highest_order`. - p(v) + dot( + return p(v) + dot( energy_volume_derivatives(s, v0, v, p, highest_order), s(v0, v) .^ collect(1:highest_order), ) @@ -61,7 +73,7 @@ function energy_volume_derivatives(s::FiniteStrain, v0, v, p::Poly, highest_orde throw(DomainError("The `highest_order` must be within 0 to $(degree(p))!")) strain_derivatives = map(m -> strain_volume_derivative(s, v0, v, m), x) energy_derivatives = map(f -> f(v), map(m -> energy_strain_derivative(p, m), x)) - map( + return map( m -> energy_volume_derivative_at_order(m)(strain_derivatives, energy_derivatives), x, ) @@ -70,13 +82,13 @@ end function energy_volume_derivative_at_order(deg) function (f::Vector{<:Real}, e::Vector{<:Real}) if deg == 1 - e[1] * f[1] + return e[1] * f[1] elseif deg == 2 - e[2] * f[1]^2 + e[1] * f[1] + return e[2] * f[1]^2 + e[1] * f[1] elseif deg == 3 - e[3] * f[1]^3 + 3 * f[1] * f[2] * e[2] + e[1] * f[3] + return e[3] * f[1]^3 + 3 * f[1] * f[2] * e[2] + e[1] * f[3] elseif deg == 4 - e[4] * f[1]^4 + + return e[4] * f[1]^4 + 6 * f[1]^2 * f[2] * e[3] + (4 * f[1] * f[3] + 3 * f[3]^2) * e[2] + e[1] * f[3] From 54bc07baffa87afc220a157cce2919538440d330 Mon Sep 17 00:00:00 2001 From: singularitti Date: Wed, 6 May 2020 22:47:44 -0400 Subject: [PATCH 06/16] Simplify `energy_volume_derivatives` --- src/LinearFitting.jl | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index a6974a1..403fe9d 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -13,7 +13,7 @@ export energy_strain_expansion, strain_volume_derivative, energy_volume_expansion, energy_volume_derivatives, - energy_volume_derivative_at_order + energy_volume_nth_derivative abstract type FiniteStrain end @@ -69,17 +69,19 @@ function energy_volume_expansion(s::FiniteStrain, v0, v, p::Poly, highest_order end function energy_volume_derivatives(s::FiniteStrain, v0, v, p::Poly, highest_order) - 0 ≤ highest_order ≤ degree(p) ? (x = 1:highest_order) : - throw(DomainError("The `highest_order` must be within 0 to $(degree(p))!")) - strain_derivatives = map(m -> strain_volume_derivative(s, v0, v, m), x) - energy_derivatives = map(f -> f(v), map(m -> energy_strain_derivative(p, m), x)) - return map( - m -> energy_volume_derivative_at_order(m)(strain_derivatives, energy_derivatives), - x, - ) + if 0 ≤ highest_order ≤ degree(p) + x = 1:highest_order + strain_derivatives = map(m -> strain_volume_derivative(s, v0, v, m), x) + energy_derivatives = map(f -> f(v), map(m -> energy_strain_derivative(p, m), x)) + return map(x) do m + energy_volume_nth_derivative(m)(strain_derivatives, energy_derivatives) + end + else + throw(DomainError("The `highest_order` must be within 0 to $(degree(p))!")) + end end -function energy_volume_derivative_at_order(deg) +function energy_volume_nth_derivative(deg) function (f::Vector{<:Real}, e::Vector{<:Real}) if deg == 1 return e[1] * f[1] @@ -89,9 +91,9 @@ function energy_volume_derivative_at_order(deg) return e[3] * f[1]^3 + 3 * f[1] * f[2] * e[2] + e[1] * f[3] elseif deg == 4 return e[4] * f[1]^4 + - 6 * f[1]^2 * f[2] * e[3] + - (4 * f[1] * f[3] + 3 * f[3]^2) * e[2] + - e[1] * f[3] + 6 * f[1]^2 * f[2] * e[3] + + (4 * f[1] * f[3] + 3 * f[3]^2) * e[2] + + e[1] * f[3] else error("Expansion is not defined at order = $(deg)!") end From fe70c040a486bf7fe0eaf5f89d7c7ac2bd452db3 Mon Sep 17 00:00:00 2001 From: singularitti Date: Thu, 7 May 2020 01:23:03 -0400 Subject: [PATCH 07/16] Deprecate test/FiniteStrains.jl --- test/FiniteStrains.jl | 157 ------------------------------------------ test/LinearFitting.jl | 155 ++++++++++++++++++++++++++++++++++++++++- test/runtests.jl | 1 - 3 files changed, 154 insertions(+), 159 deletions(-) delete mode 100644 test/FiniteStrains.jl diff --git a/test/FiniteStrains.jl b/test/FiniteStrains.jl deleted file mode 100644 index b65f5e0..0000000 --- a/test/FiniteStrains.jl +++ /dev/null @@ -1,157 +0,0 @@ -using Test - -using EquationsOfState.FiniteStrains - -@testset "Test data from Pymatgen" begin - volumes = [ - 25.987454833, - 26.9045702104, - 27.8430241908, - 28.8029649591, - 29.7848370694, - 30.7887887064, - 31.814968055, - 32.8638196693, - 33.9353435494, - 35.0299842495, - 36.1477417695, - 37.2892088485, - 38.4543854865, - 39.6437162376, - 40.857201102, - 42.095136449, - 43.3579668329, - 44.6456922537, - 45.9587572656, - 47.2973100535, - 48.6614988019, - 50.0517680652, - 51.4682660281, - 52.9112890601, - 54.3808371612, - 55.8775030703, - 57.4014349722, - 58.9526328669, - ] - v0 = 40.98926572870838 - @test map(v -> getstrain(EulerianStrain(), v0, v), volumes) ≈ [ - 0.17749734613767998, - 0.16201229839015363, - 0.14705196468522874, - 0.13259433633439055, - 0.11861428460608225, - 0.10509239492761757, - 0.09201008130906252, - 0.07934607736917354, - 0.06708557020358508, - 0.0552093893237503, - 0.043704151717372075, - 0.032551138219835574, - 0.021738453213956288, - 0.011250631487461304, - 0.0010768691828133559, - -0.00879571243518995, - -0.01838039465214164, - -0.02768646727024454, - -0.03672601609939291, - -0.04550846145018128, - -0.05404287277132974, - -0.06233970600633609, - -0.07040712280723271, - -0.07825377702272912, - -0.08588638996615916, - -0.09331442415000685, - -0.10054463011940301, - -0.1075828678792159, - ] - @test [getstrain(LagrangianStrain(), v0, v) for v in volumes] ≈ [ - -0.13099486451833953, - -0.12236351105872695, - -0.11363226812607319, - -0.10480202613156259, - -0.09587095509895383, - -0.08683995684674645, - -0.07770989398154193, - -0.06847899767396914, - -0.059149424468252, - -0.04971943052962041, - -0.04019111457888069, - -0.030561514081675456, - -0.020832711371037982, - -0.011003048988641961, - -0.0010745548727579268, - 0.008953212194864557, - 0.0190818588446644, - 0.029309415622954416, - 0.039637468728734304, - 0.050065246093897176, - 0.06059200478213067, - 0.0712192845248587, - 0.08194633401200402, - 0.09277353626347284, - 0.10369906697722475, - 0.11472551485871496, - 0.125852144820906, - 0.13707718021610538, - ] - @test [getstrain(NaturalStrain(), v0, v) for v in volumes] ≈ [ - -0.15189876859201823, - -0.14033801748544264, - -0.1289092546069999, - -0.1176106297063706, - -0.10643692669611844, - -0.09538653341846574, - -0.08445778277754971, - -0.07364595812672871, - -0.06295105569265277, - -0.05236861111679098, - -0.04189858087249365, - -0.03153541438302606, - -0.02127915820568489, - -0.011125922058677679, - -0.0010757111979426712, - 0.008873996435816848, - 0.018726748238692272, - 0.028482534552264627, - 0.0381447307354657, - 0.04771440101503085, - 0.05719263915631435, - 0.06658253672817539, - 0.07588506772815591, - 0.0851021663162455, - 0.09423387093583208, - 0.10328387622610548, - 0.11225302719931324, - 0.1211413559225737, - ] - @test [getstrain(InfinitesimalStrain(), v0, v) for v in volumes] ≈ [ - -0.1640423928171002, - -0.1506626772344306, - -0.13758688871244362, - -0.12480606002491879, - -0.1123077673073063, - -0.10008399218206754, - -0.0881269055666829, - -0.07642563827621052, - -0.06497471350599215, - -0.05376410009427657, - -0.04278871466598844, - -0.0320379239348092, - -0.021507173948334346, - -0.011188045308548222, - -0.0010762899827498895, - 0.00883473873948748, - 0.01855249213433896, - 0.02808073099690478, - 0.03742638317829727, - 0.046593960004638224, - 0.05558787891231487, - 0.06441430751249311, - 0.07307726622682587, - 0.08158155182153393, - 0.08993010154841308, - 0.09812908257335062, - 0.10618193139700183, - 0.11409127770318894, - ] -end diff --git a/test/LinearFitting.jl b/test/LinearFitting.jl index 11f9c22..4ea2677 100644 --- a/test/LinearFitting.jl +++ b/test/LinearFitting.jl @@ -1,8 +1,161 @@ using Test -using EquationsOfState.FiniteStrains using EquationsOfState.LinearFitting +@testset "Test data from Pymatgen" begin + volumes = [ + 25.987454833, + 26.9045702104, + 27.8430241908, + 28.8029649591, + 29.7848370694, + 30.7887887064, + 31.814968055, + 32.8638196693, + 33.9353435494, + 35.0299842495, + 36.1477417695, + 37.2892088485, + 38.4543854865, + 39.6437162376, + 40.857201102, + 42.095136449, + 43.3579668329, + 44.6456922537, + 45.9587572656, + 47.2973100535, + 48.6614988019, + 50.0517680652, + 51.4682660281, + 52.9112890601, + 54.3808371612, + 55.8775030703, + 57.4014349722, + 58.9526328669, + ] + v0 = 40.98926572870838 + @test map(v -> EulerianStrain()(v0, v), volumes) ≈ [ + 0.17749734613767998, + 0.16201229839015363, + 0.14705196468522874, + 0.13259433633439055, + 0.11861428460608225, + 0.10509239492761757, + 0.09201008130906252, + 0.07934607736917354, + 0.06708557020358508, + 0.0552093893237503, + 0.043704151717372075, + 0.032551138219835574, + 0.021738453213956288, + 0.011250631487461304, + 0.0010768691828133559, + -0.00879571243518995, + -0.01838039465214164, + -0.02768646727024454, + -0.03672601609939291, + -0.04550846145018128, + -0.05404287277132974, + -0.06233970600633609, + -0.07040712280723271, + -0.07825377702272912, + -0.08588638996615916, + -0.09331442415000685, + -0.10054463011940301, + -0.1075828678792159, + ] + @test [LagrangianStrain()(v0, v) for v in volumes] ≈ [ + -0.13099486451833953, + -0.12236351105872695, + -0.11363226812607319, + -0.10480202613156259, + -0.09587095509895383, + -0.08683995684674645, + -0.07770989398154193, + -0.06847899767396914, + -0.059149424468252, + -0.04971943052962041, + -0.04019111457888069, + -0.030561514081675456, + -0.020832711371037982, + -0.011003048988641961, + -0.0010745548727579268, + 0.008953212194864557, + 0.0190818588446644, + 0.029309415622954416, + 0.039637468728734304, + 0.050065246093897176, + 0.06059200478213067, + 0.0712192845248587, + 0.08194633401200402, + 0.09277353626347284, + 0.10369906697722475, + 0.11472551485871496, + 0.125852144820906, + 0.13707718021610538, + ] + @test [NaturalStrain()(v0, v) for v in volumes] ≈ [ + -0.15189876859201823, + -0.14033801748544264, + -0.1289092546069999, + -0.1176106297063706, + -0.10643692669611844, + -0.09538653341846574, + -0.08445778277754971, + -0.07364595812672871, + -0.06295105569265277, + -0.05236861111679098, + -0.04189858087249365, + -0.03153541438302606, + -0.02127915820568489, + -0.011125922058677679, + -0.0010757111979426712, + 0.008873996435816848, + 0.018726748238692272, + 0.028482534552264627, + 0.0381447307354657, + 0.04771440101503085, + 0.05719263915631435, + 0.06658253672817539, + 0.07588506772815591, + 0.0851021663162455, + 0.09423387093583208, + 0.10328387622610548, + 0.11225302719931324, + 0.1211413559225737, + ] + @test [InfinitesimalStrain()(v0, v) for v in volumes] ≈ [ + -0.1640423928171002, + -0.1506626772344306, + -0.13758688871244362, + -0.12480606002491879, + -0.1123077673073063, + -0.10008399218206754, + -0.0881269055666829, + -0.07642563827621052, + -0.06497471350599215, + -0.05376410009427657, + -0.04278871466598844, + -0.0320379239348092, + -0.021507173948334346, + -0.011188045308548222, + -0.0010762899827498895, + 0.00883473873948748, + 0.01855249213433896, + 0.02808073099690478, + 0.03742638317829727, + 0.046593960004638224, + 0.05558787891231487, + 0.06441430751249311, + 0.07307726622682587, + 0.08158155182153393, + 0.08993010154841308, + 0.09812908257335062, + 0.10618193139700183, + 0.11409127770318894, + ] +end + @testset "Test strain-volume-derivative" begin volumes = [ 25.987454833, diff --git a/test/runtests.jl b/test/runtests.jl index d5388eb..3321bb7 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,7 +3,6 @@ using Test @testset "EquationsOfState.jl" begin include("Collections.jl") - include("FiniteStrains.jl") include("NonlinearFitting.jl") include("LinearFitting.jl") include("Find.jl") From e197d6cefc64537b82440aade0b37e1f053a9649 Mon Sep 17 00:00:00 2001 From: singularitti Date: Thu, 7 May 2020 01:34:23 -0400 Subject: [PATCH 08/16] Simplify `Strain`s' names --- src/LinearFitting.jl | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 403fe9d..bc9baa6 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -7,7 +7,7 @@ using LinearAlgebra: dot using Polynomials: degree, coeffs using Polynomials.PolyCompat: polyfit, polyder, Poly -export FiniteStrain, EulerianStrain, LagrangianStrain, NaturalStrain, InfinitesimalStrain +export FiniteStrain, Eulerian, Lagrangian, Natural, Infinitesimal export energy_strain_expansion, energy_strain_derivative, strain_volume_derivative, @@ -16,11 +16,10 @@ export energy_strain_expansion, energy_volume_nth_derivative abstract type FiniteStrain end - -struct EulerianStrain <: FiniteStrain end -struct LagrangianStrain <: FiniteStrain end -struct NaturalStrain <: FiniteStrain end -struct InfinitesimalStrain <: FiniteStrain end +struct Eulerian <: FiniteStrain end +struct Lagrangian <: FiniteStrain end +struct Natural <: FiniteStrain end +struct Infinitesimal <: FiniteStrain end (::EulerianStrain)(v0, v) = (cbrt(v0 / v)^2 - 1) / 2 (::LagrangianStrain)(v0, v) = (cbrt(v / v0)^2 - 1) / 2 @@ -31,28 +30,28 @@ energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int) = polyfit( energy_strain_derivative(p::Poly, deg) = polyder(p, deg) -function strain_volume_derivative(s::EulerianStrain, v0, v, deg) +function strain_volume_derivative(s::Eulerian, v0, v, deg) if deg == 1 return -1 / (3v) * cbrt(v0 / v)^2 else # Recursion return -(3deg + 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) end end -function strain_volume_derivative(s::LagrangianStrain, v0, v, deg) +function strain_volume_derivative(s::Lagrangian, v0, v, deg) if deg == 1 return -1 / (3v) * cbrt(v / v0)^2 else # Recursion return -(3deg - 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) end end -function strain_volume_derivative(s::NaturalStrain, v0, v, deg) +function strain_volume_derivative(s::Natural, v0, v, deg) if deg == 1 return 1 / (3v) else # Recursion return -deg / v * strain_volume_derivative(s, v0, v, deg - 1) end end -function strain_volume_derivative(s::InfinitesimalStrain, v0, v, deg) +function strain_volume_derivative(s::Infinitesimal, v0, v, deg) if deg == 1 return (1 - s(v0, v))^4 / 3 / v0 else # Recursion From a9dd3ab82543b52ee6ce618aae9cecc2a79015a9 Mon Sep 17 00:00:00 2001 From: singularitti Date: Thu, 7 May 2020 01:50:29 -0400 Subject: [PATCH 09/16] Add `StrainFromVolume` & `VolumeFromStrain` --- src/LinearFitting.jl | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index bc9baa6..f808e23 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -21,10 +21,21 @@ struct Lagrangian <: FiniteStrain end struct Natural <: FiniteStrain end struct Infinitesimal <: FiniteStrain end -(::EulerianStrain)(v0, v) = (cbrt(v0 / v)^2 - 1) / 2 -(::LagrangianStrain)(v0, v) = (cbrt(v / v0)^2 - 1) / 2 -(::NaturalStrain)(v0, v) = log(v / v0) / 3 -(::InfinitesimalStrain)(v0, v) = 1 - cbrt(v0 / v) +struct StrainFromVolume{T<:FiniteStrain} + v0::Any +end +(x::StrainFromVolume{Eulerian})(v) = (cbrt(x.v0 / v)^2 - 1) / 2 +(x::StrainFromVolume{Lagrangian})(v) = (cbrt(v / x.v0)^2 - 1) / 2 +(x::StrainFromVolume{Natural})(v) = log(v / x.v0) / 3 +(x::StrainFromVolume{Infinitesimal})(v) = 1 - cbrt(x.v0 / v) + +struct VolumeFromStrain{T<:FiniteStrain} + v0::Any +end +(x::VolumeFromStrain{Eulerian})(f) = x.v0 / (2f + 1)^(3 / 2) +(x::VolumeFromStrain{Lagrangian})(f) = x.v0 * (2f + 1)^(3 / 2) +(x::VolumeFromStrain{Natural})(f) = x.v0 * exp(3f) +(x::VolumeFromStrain{Infinitesimal})(f) = x.v0 / (1 - f)^3 energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int) = polyfit(f, e, n) @@ -79,6 +90,8 @@ function energy_volume_derivatives(s::FiniteStrain, v0, v, p::Poly, highest_orde throw(DomainError("The `highest_order` must be within 0 to $(degree(p))!")) end end +Base.inv(x::StrainFromVolume{T}) where {T} = VolumeFromStrain{T}(x.v0) +Base.inv(x::VolumeFromStrain{T}) where {T} = StrainFromVolume{T}(x.v0) function energy_volume_nth_derivative(deg) function (f::Vector{<:Real}, e::Vector{<:Real}) @@ -98,5 +111,9 @@ function energy_volume_nth_derivative(deg) end end end +Base.:∘(a::StrainFromVolume{T}, b::VolumeFromStrain{T}) where {T} = + a.v0 == b.v0 ? identity : error("operation undefined!") +Base.:∘(a::VolumeFromStrain{T}, b::StrainFromVolume{T}) where {T} = + a.v0 == b.v0 ? identity : error("operation undefined!") end From e9bac66b66d02f3e0399899ac16b25d939f83c10 Mon Sep 17 00:00:00 2001 From: singularitti Date: Thu, 7 May 2020 20:19:37 -0400 Subject: [PATCH 10/16] Try to add `linearfit` in src/LinearFitting.jl --- src/LinearFitting.jl | 96 +++++++++----------------------------------- 1 file changed, 19 insertions(+), 77 deletions(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index f808e23..2667815 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -3,17 +3,9 @@ This module provides some linear fitting methods. """ module LinearFitting -using LinearAlgebra: dot -using Polynomials: degree, coeffs -using Polynomials.PolyCompat: polyfit, polyder, Poly +using Polynomials: Polynomial, fit, derivative, roots, coeffs -export FiniteStrain, Eulerian, Lagrangian, Natural, Infinitesimal -export energy_strain_expansion, - energy_strain_derivative, - strain_volume_derivative, - energy_volume_expansion, - energy_volume_derivatives, - energy_volume_nth_derivative +export FiniteStrain, Eulerian, Lagrangian, Natural, Infinitesimal, linearfit abstract type FiniteStrain end struct Eulerian <: FiniteStrain end @@ -37,80 +29,30 @@ end (x::VolumeFromStrain{Natural})(f) = x.v0 * exp(3f) (x::VolumeFromStrain{Infinitesimal})(f) = x.v0 / (1 - f)^3 -energy_strain_expansion(f::Vector{<:Real}, e::Vector{<:Real}, n::Int) = polyfit(f, e, n) +_islocalminimum(poly, x, δx) = poly(x) < poly(x - δx) && poly(x) < poly(x + δx) -energy_strain_derivative(p::Poly, deg) = polyder(p, deg) - -function strain_volume_derivative(s::Eulerian, v0, v, deg) - if deg == 1 - return -1 / (3v) * cbrt(v0 / v)^2 - else # Recursion - return -(3deg + 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) - end -end -function strain_volume_derivative(s::Lagrangian, v0, v, deg) - if deg == 1 - return -1 / (3v) * cbrt(v / v0)^2 - else # Recursion - return -(3deg - 2) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) - end -end -function strain_volume_derivative(s::Natural, v0, v, deg) - if deg == 1 - return 1 / (3v) - else # Recursion - return -deg / v * strain_volume_derivative(s, v0, v, deg - 1) - end -end -function strain_volume_derivative(s::Infinitesimal, v0, v, deg) - if deg == 1 - return (1 - s(v0, v))^4 / 3 / v0 - else # Recursion - return -(3deg + 1) / (3v) * strain_volume_derivative(s, v0, v, deg - 1) - end -end - -function energy_volume_expansion(s::FiniteStrain, v0, v, p::Poly, highest_order = degree(p)) - # The zeroth order value plus values from the first to the ``highest_order`. - return p(v) + dot( - energy_volume_derivatives(s, v0, v, p, highest_order), - s(v0, v) .^ collect(1:highest_order), - ) -end - -function energy_volume_derivatives(s::FiniteStrain, v0, v, p::Poly, highest_order) - if 0 ≤ highest_order ≤ degree(p) - x = 1:highest_order - strain_derivatives = map(m -> strain_volume_derivative(s, v0, v, m), x) - energy_derivatives = map(f -> f(v), map(m -> energy_strain_derivative(p, m), x)) - return map(x) do m - energy_volume_nth_derivative(m)(strain_derivatives, energy_derivatives) +function linearfit(volumes, energies, deg = 3) + poly = fit(volumes, energies, deg) + der = derivative(poly, 1) + δx = minimum(diff(volumes)) / 10 + localminima = eltype(volumes)[] + for x in roots(der) + if _islocalminimum(poly, x, δx) + push!(localminima, x) end + end + if length(localminima) == 0 + error("no volume minimizes the energy!") else - throw(DomainError("The `highest_order` must be within 0 to $(degree(p))!")) + e0, i = findmin(poly.(localminima)) + v0 = localminima[i] + return Polynomial(append!([e0, 0], coeffs(poly)[3:end])) end -end +end # function linearfit + Base.inv(x::StrainFromVolume{T}) where {T} = VolumeFromStrain{T}(x.v0) Base.inv(x::VolumeFromStrain{T}) where {T} = StrainFromVolume{T}(x.v0) -function energy_volume_nth_derivative(deg) - function (f::Vector{<:Real}, e::Vector{<:Real}) - if deg == 1 - return e[1] * f[1] - elseif deg == 2 - return e[2] * f[1]^2 + e[1] * f[1] - elseif deg == 3 - return e[3] * f[1]^3 + 3 * f[1] * f[2] * e[2] + e[1] * f[3] - elseif deg == 4 - return e[4] * f[1]^4 + - 6 * f[1]^2 * f[2] * e[3] + - (4 * f[1] * f[3] + 3 * f[3]^2) * e[2] + - e[1] * f[3] - else - error("Expansion is not defined at order = $(deg)!") - end - end -end Base.:∘(a::StrainFromVolume{T}, b::VolumeFromStrain{T}) where {T} = a.v0 == b.v0 ? identity : error("operation undefined!") Base.:∘(a::VolumeFromStrain{T}, b::StrainFromVolume{T}) where {T} = From c4e84e7366507606870deddff9638615d508ec94 Mon Sep 17 00:00:00 2001 From: singularitti Date: Fri, 8 May 2020 01:26:55 -0400 Subject: [PATCH 11/16] Separate `_findglobalminimum` from `linearfit` --- src/LinearFitting.jl | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 2667815..1044d5a 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -29,25 +29,29 @@ end (x::VolumeFromStrain{Natural})(f) = x.v0 * exp(3f) (x::VolumeFromStrain{Infinitesimal})(f) = x.v0 / (1 - f)^3 -_islocalminimum(poly, x, δx) = poly(x) < poly(x - δx) && poly(x) < poly(x + δx) +_islocalminimum(f, x, δx) = f(x) < f(x - δx) && f(x) < f(x + δx) + +function _findglobalminimum(f, localminima, δx) + if length(localminima) == 0 + error("no volume minimizes the energy!") + else + f0, i = findmin(f.(localminima)) + x0 = localminima[i] + return x0, f0 + end +end # function _findglobalminimum function linearfit(volumes, energies, deg = 3) poly = fit(volumes, energies, deg) - der = derivative(poly, 1) + poly1d = derivative(poly, 1) δx = minimum(diff(volumes)) / 10 localminima = eltype(volumes)[] - for x in roots(der) + for x in roots(poly1d) if _islocalminimum(poly, x, δx) push!(localminima, x) end end - if length(localminima) == 0 - error("no volume minimizes the energy!") - else - e0, i = findmin(poly.(localminima)) - v0 = localminima[i] - return Polynomial(append!([e0, 0], coeffs(poly)[3:end])) - end + v0, e0 = _findglobalminimum(poly, localminima, δx) end # function linearfit Base.inv(x::StrainFromVolume{T}) where {T} = VolumeFromStrain{T}(x.v0) From 310d7907d84bf59f92eaa4cf6788556c2317e0f5 Mon Sep 17 00:00:00 2001 From: singularitti Date: Fri, 8 May 2020 01:49:28 -0400 Subject: [PATCH 12/16] Fix a bug in `linearfit` in case of `Complex` roots --- src/LinearFitting.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 1044d5a..46e64b2 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -46,7 +46,7 @@ function linearfit(volumes, energies, deg = 3) poly1d = derivative(poly, 1) δx = minimum(diff(volumes)) / 10 localminima = eltype(volumes)[] - for x in roots(poly1d) + for x in real(filter(isreal, roots(poly1d))) # Complex volume is meaningless if _islocalminimum(poly, x, δx) push!(localminima, x) end From 04cd4b4067d663b4dc7dba24cc4536427f344c9c Mon Sep 17 00:00:00 2001 From: singularitti Date: Fri, 8 May 2020 01:50:02 -0400 Subject: [PATCH 13/16] Finish `linearfit` --- src/LinearFitting.jl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 46e64b2..6e05441 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -52,6 +52,12 @@ function linearfit(volumes, energies, deg = 3) end end v0, e0 = _findglobalminimum(poly, localminima, δx) + bs = [] + for n in 2:deg + f = derivative(poly, n) / factorial(n) + push!(bs, f(v0)) + end + return [v0, e0, bs...] end # function linearfit Base.inv(x::StrainFromVolume{T}) where {T} = VolumeFromStrain{T}(x.v0) From c54adb32898891396c880b32b23722e5e51177ae Mon Sep 17 00:00:00 2001 From: singularitti Date: Fri, 8 May 2020 02:01:08 -0400 Subject: [PATCH 14/16] Rename `FiniteStrainEquationOfState` to `FiniteStrainEOS` --- docs/src/api/Collections.md | 4 ++-- src/Collections.jl | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/src/api/Collections.md b/docs/src/api/Collections.md index 28492c9..9772c06 100644 --- a/docs/src/api/Collections.md +++ b/docs/src/api/Collections.md @@ -10,7 +10,7 @@ The current `EquationOfState`s contain EquationOfState ├─ AntonSchmidt ├─ BreenanStacey -├─ FiniteStrainEquationOfState +├─ FiniteStrainEOS │ ├─ BirchMurnaghan2nd │ ├─ BirchMurnaghan3rd │ ├─ BirchMurnaghan4th @@ -264,7 +264,7 @@ Energy Pressure BulkModulus EquationOfState -FiniteStrainEquationOfState +FiniteStrainEOS Murnaghan BirchMurnaghan2nd BirchMurnaghan3rd diff --git a/src/Collections.jl b/src/Collections.jl index 8e6dec7..1028ec3 100644 --- a/src/Collections.jl +++ b/src/Collections.jl @@ -142,11 +142,11 @@ An abstraction of equations of state, where `T` specifies the elements' common t abstract type EquationOfState{T} end """ - FiniteStrainEquationOfState{T} <: EquationOfState{T} + FiniteStrainEOS{T} <: EquationOfState{T} An abstraction of finite strain equations of state, where `T` specifies the elements' common type. """ -abstract type FiniteStrainEquationOfState{T} <: EquationOfState{T} end +abstract type FiniteStrainEOS{T} <: EquationOfState{T} end """ Murnaghan(v0, b0, b′0, e0) @@ -212,7 +212,7 @@ julia> BirchMurnaghan2nd(1u"nm^3", 2u"GPa", 3.0u"eV") BirchMurnaghan2nd{Quantity{Float64,D,U} where U where D}(1.0 nm³, 2.0 GPa, 3.0 eV) ``` """ -struct BirchMurnaghan2nd{T} <: FiniteStrainEquationOfState{T} +struct BirchMurnaghan2nd{T} <: FiniteStrainEOS{T} v0::T b0::T e0::T @@ -250,7 +250,7 @@ julia> BirchMurnaghan3rd(1u"nm^3", 2u"GPa", 4.0, 3u"eV") BirchMurnaghan3rd{Quantity{Float64,D,U} where U where D}(1.0 nm³, 2.0 GPa, 4.0, 3.0 eV) ``` """ -struct BirchMurnaghan3rd{T} <: FiniteStrainEquationOfState{T} +struct BirchMurnaghan3rd{T} <: FiniteStrainEOS{T} v0::T b0::T b′0::T @@ -290,7 +290,7 @@ julia> BirchMurnaghan4th(1u"nm^3", 2u"GPa", 3.0, 4u"1/GPa", 5u"eV") BirchMurnaghan4th{Quantity{Float64,D,U} where U where D}(1.0 nm³, 2.0 GPa, 3.0, 4.0 GPa⁻¹, 5.0 eV) ``` """ -struct BirchMurnaghan4th{T} <: FiniteStrainEquationOfState{T} +struct BirchMurnaghan4th{T} <: FiniteStrainEOS{T} v0::T b0::T b′0::T @@ -330,7 +330,7 @@ julia> PoirierTarantola2nd(1u"nm^3", 2u"GPa", 3.0u"eV") PoirierTarantola2nd{Quantity{Float64,D,U} where U where D}(1.0 nm³, 2.0 GPa, 3.0 eV) ``` """ -struct PoirierTarantola2nd{T} <: FiniteStrainEquationOfState{T} +struct PoirierTarantola2nd{T} <: FiniteStrainEOS{T} v0::T b0::T e0::T @@ -368,7 +368,7 @@ julia> PoirierTarantola3rd(1u"nm^3", 2u"GPa", 3, 4.0u"eV") PoirierTarantola3rd{Quantity{Float64,D,U} where U where D}(1.0 nm³, 2.0 GPa, 3.0, 4.0 eV) ``` """ -struct PoirierTarantola3rd{T} <: FiniteStrainEquationOfState{T} +struct PoirierTarantola3rd{T} <: FiniteStrainEOS{T} v0::T b0::T b′0::T @@ -408,7 +408,7 @@ julia> PoirierTarantola4th(1u"nm^3", 2u"GPa", 3, 4u"1/GPa", 5.0u"eV") PoirierTarantola4th{Quantity{Float64,D,U} where U where D}(1.0 nm³, 2.0 GPa, 3.0, 4.0 GPa⁻¹, 5.0 eV) ``` """ -struct PoirierTarantola4th{T} <: FiniteStrainEquationOfState{T} +struct PoirierTarantola4th{T} <: FiniteStrainEOS{T} v0::T b0::T b′0::T From c699f68a10eaa028c253d65500394595c0127389 Mon Sep 17 00:00:00 2001 From: singularitti Date: Fri, 8 May 2020 02:59:10 -0400 Subject: [PATCH 15/16] Add `PolynomialEOS` & fix `linearfit` --- src/Collections.jl | 13 ++++++++++++- src/LinearFitting.jl | 10 ++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Collections.jl b/src/Collections.jl index 1028ec3..5be37d7 100644 --- a/src/Collections.jl +++ b/src/Collections.jl @@ -23,7 +23,8 @@ export Energy, Vinet, AntonSchmidt, BreenanStacey, - Shanker + Shanker, + PolynomialEOS # ============================================================================ # # Types # @@ -502,6 +503,16 @@ end Shanker(v0::Real, b0::Real, b′0::Real) = Shanker(v0, b0, b′0, 0) Shanker(v0::AbstractQuantity, b0::AbstractQuantity, b′0) = Shanker(v0, b0, b′0, 0 * upreferred(Unitful.J)) + +struct PolynomialEOS{N,T} <: EquationOfState{T} + v0::T + b0::NTuple{N,T} + e0::T +end +function PolynomialEOS(v0, b0, e0) + T = Base.promote_typeof(v0, b0..., e0) + return PolynomialEOS{length(b0),T}(convert(T, v0), T.(b0), convert(T, e0)) +end # =================================== Types ================================== # # Energy evaluation diff --git a/src/LinearFitting.jl b/src/LinearFitting.jl index 6e05441..bb288c0 100644 --- a/src/LinearFitting.jl +++ b/src/LinearFitting.jl @@ -5,6 +5,8 @@ module LinearFitting using Polynomials: Polynomial, fit, derivative, roots, coeffs +using ..Collections: PolynomialEOS + export FiniteStrain, Eulerian, Lagrangian, Natural, Infinitesimal, linearfit abstract type FiniteStrain end @@ -52,12 +54,8 @@ function linearfit(volumes, energies, deg = 3) end end v0, e0 = _findglobalminimum(poly, localminima, δx) - bs = [] - for n in 2:deg - f = derivative(poly, n) / factorial(n) - push!(bs, f(v0)) - end - return [v0, e0, bs...] + bs = Tuple(derivative(poly, n)(v0) / factorial(n) for n in 1:deg) + return PolynomialEOS(v0, bs, e0) end # function linearfit Base.inv(x::StrainFromVolume{T}) where {T} = VolumeFromStrain{T}(x.v0) From e0f502e1c83219c4d7f5a87894a817889c961ffc Mon Sep 17 00:00:00 2001 From: singularitti Date: Fri, 8 May 2020 03:05:51 -0400 Subject: [PATCH 16/16] Remove `LinearAlgebra` from deps --- Project.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Project.toml b/Project.toml index ca3be94..aa0c022 100644 --- a/Project.toml +++ b/Project.toml @@ -7,7 +7,6 @@ version = "3.0.2" ConstructionBase = "187b0558-2788-49d3-abe0-74a17ed4e7c9" InteractiveUtils = "b77e0a4c-d291-57a0-90e8-8db25a27a240" IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e" -LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LsqFit = "2fda8390-95c7-5789-9bda-21331edee243" Polynomials = "f27b6e38-b328-58d1-80ce-0feddd5e7a45" Roots = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"